public List<Versioned<T>> resolveConflicts(List<Versioned<T>> items) { if(items.size() <= 1) { return items; } else { Iterator<Versioned<T>> iter = items.iterator(); Versioned<T> current = iter.next(); T merged = current.getValue(); VectorClock clock = (VectorClock) current.getVersion(); while(iter.hasNext()) { Versioned<T> versioned = iter.next(); merged = merger.merge(merged, versioned.getValue()); clock = clock.merge((VectorClock) versioned.getVersion()); } return Collections.singletonList(new Versioned<T>(merged, clock)); } }
public static Versioned<Properties> parseProperties(List<Versioned<byte[]>> versionProps) { Properties props = new Properties(); if(versionProps == null || versionProps.size() == 0) { return new Versioned<Properties>(props); } VectorClock version = new VectorClock(); for(int cur = 0; cur < versionProps.size(); cur++) { VectorClock curVersion = (VectorClock) versionProps.get(cur).getVersion(); version = version.merge(curVersion); byte[] value = versionProps.get(cur).getValue(); if(value == null) { continue; } Properties curProps = new Properties(); try { curProps.load(new ByteArrayInputStream(value)); } catch(Exception e) { continue; } props = mergeVersions(props, curProps); } return new Versioned<Properties>(props, version); }
public List<Versioned<T>> resolveConflicts(List<Versioned<T>> items) { if(items.size() <= 1) { return items; } else { Versioned<T> max = items.get(0); long maxTime = ((VectorClock) items.get(0).getVersion()).getTimestamp(); VectorClock maxClock = ((VectorClock) items.get(0).getVersion()); for(Versioned<T> versioned: items) { VectorClock clock = (VectorClock) versioned.getVersion(); if(clock.getTimestamp() > maxTime) { max = versioned; maxTime = ((VectorClock) versioned.getVersion()).getTimestamp(); } maxClock = maxClock.merge(clock); } Versioned<T> maxTimeClockVersioned = new Versioned<T>(max.getValue(), maxClock); return Collections.singletonList(maxTimeClockVersioned); } }
private Versioned<Properties> getMetadataVersion(Collection<Integer> nodeIds) { VectorClock version = new VectorClock(); Properties props = new Properties(); boolean atLeastOneSuccess = false; for(Integer nodeId: nodeIds) { try { Versioned<Properties> versionedProps = getMetadataVersion(nodeId); VectorClock curVersion = (VectorClock) versionedProps.getVersion(); Properties curProps = versionedProps.getValue(); version = version.merge(curVersion); props = MetadataVersionStoreUtils.mergeVersions(props, curProps); atLeastOneSuccess = true; } catch(Exception e) { if (logger.isDebugEnabled()) { logger.debug("Error retrieving metadata versions for node " + nodeId, e); } } } if(atLeastOneSuccess == false) { throw new VoldemortApplicationException("Metadata version retrieval failed on all nodes" + Arrays.toString(nodeIds.toArray())); } return new Versioned<Properties>(props, version); }
/** * Sets metadata. * * @param nodeIds Node ids to set metadata * @param key Metadata key to set * @param value Metadata value to set */ public void updateRemoteMetadata(Collection<Integer> nodeIds, String key, String value) { VectorClock updatedVersion = null; for(Integer nodeId: nodeIds) { if(updatedVersion == null) { updatedVersion = (VectorClock) metadataMgmtOps.getRemoteMetadata(nodeId, key) .getVersion(); } else { updatedVersion = updatedVersion.merge((VectorClock) metadataMgmtOps.getRemoteMetadata(nodeId, key) .getVersion()); } // Bump up version on first node updatedVersion = updatedVersion.incremented(nodeIds.iterator().next(), System.currentTimeMillis()); } metadataMgmtOps.updateRemoteMetadata(nodeIds, key, Versioned.value(value, updatedVersion)); }
private static Versioned<Properties> mergeAllVersions(AdminClient adminClient) { Properties props = new Properties(); VectorClock version = new VectorClock(); for(Integer nodeId: adminClient.getAdminClientCluster().getNodeIds()) { Versioned<Properties> versionedProp = doMetaGetVersionsForNode_ExitOnError(adminClient, nodeId); Properties newProps = versionedProp.getValue(); VectorClock newVersion = (VectorClock) versionedProp.getVersion(); version = version.merge(newVersion); props = MetadataVersionStoreUtils.mergeVersions(props, newProps); } return new Versioned<Properties>(props, version); } }
.getVersion(); } else { updatedClusterVersion = updatedClusterVersion.merge((VectorClock) adminClient.metadataMgmtOps.getRemoteMetadata(nodeId, MetadataStore.CLUSTER_KEY) .getVersion()); updatedStoresVersion = updatedStoresVersion.merge((VectorClock) adminClient.metadataMgmtOps.getRemoteMetadata(nodeId, MetadataStore.STORES_KEY) .getVersion());
.getVersion(); } else { updatedVersion = updatedVersion.merge((VectorClock) adminClient.metadataMgmtOps.getRemoteMetadata(node.getId(), key) .getVersion());
.getVersion(); } else { updatedClusterVersion = updatedClusterVersion.merge((VectorClock) adminClient.metadataMgmtOps.getRemoteMetadata(node.getId(), clusterKey) .getVersion()); updatedStoresVersion = updatedStoresVersion.merge((VectorClock) adminClient.metadataMgmtOps.getRemoteMetadata(node.getId(), storesKey) .getVersion());
/** * See github issue #25: Incorrect coercion of version to short before * passing to ClockEntry constructor */ @Test public void testMergeWithLargeVersion() { VectorClock clock1 = getClock(1); VectorClock clock2 = new VectorClock(Lists.newArrayList(new ClockEntry((short) 1, Short.MAX_VALUE + 1)), System.currentTimeMillis()); VectorClock mergedClock = clock1.merge(clock2); assertEquals(mergedClock.getMaxVersion(), Short.MAX_VALUE + 1); }
@Test public void testMerge() { // merging two clocks should create a clock contain the element-wise // maximums assertEquals("Two empty clocks merge to an empty clock.", getClock().merge(getClock()), getClock()); assertEquals("Merge of a clock with itself does nothing", getClock(1).merge(getClock(1)), getClock(1)); assertEquals(getClock(1).merge(getClock(2)), getClock(1, 2)); assertEquals(getClock(1).merge(getClock(1, 2)), getClock(1, 2)); assertEquals(getClock(1, 2).merge(getClock(1)), getClock(1, 2)); assertEquals("Two-way merge fails.", getClock(1, 1, 1, 2, 3, 5).merge(getClock(1, 2, 2, 4)), getClock(1, 1, 1, 2, 2, 3, 4, 5)); assertEquals(getClock(2, 3, 5).merge(getClock(1, 2, 2, 4, 7)), getClock(1, 2, 2, 3, 4, 5, 7)); }