Versioned<byte[]> versioned = Versioned.value(v.getVersioned().getValue(), ((VectorClock) v.getVersion()).clone()); toReadRepair.add(new NodeValue<ByteArray, byte[]>(v.getNodeId(), v.getKey(), versioned)); try { if(logger.isDebugEnabled()) logger.debug("Doing read repair on node " + v.getNodeId() + " for key '" + ByteUtils.toHexString(v.getKey().get()) + "' with version " + v.getVersion() + "."); NonblockingStore store = nonblockingStores.get(v.getNodeId()); store.submitPutRequest(v.getKey(), v.getVersioned(), null, null, timeoutMs); } catch(VoldemortApplicationException e) { if(logger.isDebugEnabled()) logger.debug("Read repair cancelled due to application level exception on node " + v.getNodeId() + " for key '" + ByteUtils.toHexString(v.getKey().get()) + "' with version " + v.getVersion() + ": " + e.getMessage()); } catch(Exception e) { logger.debug("Read repair failed: ", e); String logStr = "Repaired (node, key, version): ("; for(NodeValue<ByteArray, byte[]> v: toReadRepair) { logStr += "(" + v.getNodeId() + ", " + v.getKey() + "," + v.getVersion() + ") ";
@Override public boolean equals(Object o) { if(o == this) return true; if(!(o instanceof NodeValue<?, ?>)) return false; NodeValue<?, ?> v = (NodeValue<?, ?>) o; return getNodeId() == v.getNodeId() && Objects.equal(getKey(), v.getKey()) && Objects.equal(getVersion(), v.getVersion()); } }
/** * This method updates exactly one key/value for a specific store on a * specific node. * * @param storeName Name of the store * @param nodeKeyValue A specific key/value to update on a specific * node. */ public void putNodeKeyValue(String storeName, NodeValue<ByteArray, byte[]> nodeKeyValue) { SocketStore socketStore = adminStoreClient.getSocketStore(nodeKeyValue.getNodeId(), storeName); socketStore.put(nodeKeyValue.getKey(), nodeKeyValue.getVersioned(), null); }
@Override public void run() { for(NodeValue<ByteArray, byte[]> v: toReadRepair) { try { if(logger.isDebugEnabled()) logger.debug("Doing read repair on node " + v.getNodeId() + " for key '" + v.getKey() + "' with version " + v.getVersion() + "."); // no transforms since this is read repair innerStores.get(v.getNodeId()).put(v.getKey(), v.getVersioned(), null); } catch(VoldemortApplicationException e) { if(logger.isDebugEnabled()) logger.debug("Read repair cancelled due to application level exception on node " + v.getNodeId() + " for key '" + v.getKey() + "' with version " + v.getVersion() + ": " + e.getMessage()); } catch(Exception e) { logger.debug("Read repair failed: ", e); } } } });
@Override public NodeValue<K, V> clone() { return new NodeValue<K, V>(nodeId, key, value); }
@Test public void testHashCodeEquals() { // Create multiple nodeValues that are equal and see if they hash the same and equal each other Version v1 = createVersion(1, 6); Version v2 = createVersion(1, 6); Version v3 = createVersion(1, 7); logger.info("v1 = " + v1); logger.info("v2 = " + v2); logger.info("v3 = " + v3); assertEquals("VectorClock#equals works", v1, v2); assertEquals("VectorClock#hashCode works", v1.hashCode(), v2.hashCode()); assertFalse(v1.equals(v3)); assertFalse(v1.hashCode() == v3.hashCode()); NodeValue<ByteArray, byte[]> nv1 = createNodeValue(1, v1); NodeValue<ByteArray, byte[]> nv2 = createNodeValue(1, v2); NodeValue<ByteArray, byte[]> nv3 = createNodeValue(1, v3); logger.info("nv1 = " + nv1); logger.info("nv2 = " + nv2); logger.info("nv3 = " + nv3); assertEquals("NodeValue#equals works", nv1, nv2); assertEquals("NodeValue#hashCode works", nv1.hashCode(), nv2.hashCode()); assertFalse(nv1.equals(nv3)); assertFalse(nv1.hashCode() == nv3.hashCode()); }
/** * Compute the repair set from the given values and nodes * * @param nodeValues The value found on each node * @return A set of repairs to perform */ public List<NodeValue<K, V>> getRepairs(List<NodeValue<K, V>> nodeValues) { int size = nodeValues.size(); if(size <= 1) return Collections.emptyList(); Map<K, List<NodeValue<K, V>>> keyToNodeValues = Maps.newHashMap(); for(NodeValue<K, V> nodeValue: nodeValues) { List<NodeValue<K, V>> keyNodeValues = keyToNodeValues.get(nodeValue.getKey()); if(keyNodeValues == null) { keyNodeValues = Lists.newArrayListWithCapacity(5); keyToNodeValues.put(nodeValue.getKey(), keyNodeValues); } keyNodeValues.add(nodeValue); } List<NodeValue<K, V>> result = Lists.newArrayList(); for(List<NodeValue<K, V>> keyNodeValues: keyToNodeValues.values()) result.addAll(singleKeyGetRepairs(keyNodeValues)); return result; }
protected void insertNodeValue(Node node, ByteArray key, List<Versioned<byte[]>> value) { if(value.size() == 0) { Versioned<byte[]> versioned = new Versioned<byte[]>(null); nodeValues.add(new NodeValue<ByteArray, byte[]>(node.getId(), key, versioned)); } else { for(Versioned<byte[]> versioned: value) nodeValues.add(new NodeValue<ByteArray, byte[]>(node.getId(), key, versioned)); } }
for(NodeValue<ByteArray, byte[]> nodeKeyValue: toReadRepair) { try { consistencyFix.maybePutThrottle(nodeKeyValue.getNodeId()); consistencyFix.getAdminClient().storeOps.putNodeKeyValue(consistencyFix.getStoreName(), nodeKeyValue); } catch(VoldemortException ve) { allRepairsSuccessful = false; logger.debug("Repair of key " + nodeKeyValue.getKey() + "on node with id " + nodeKeyValue.getNodeId() + " for version " + nodeKeyValue.getVersion() + " failed because of exception : " + ve.getMessage());
private void fillRepairReadsValues(final List<NodeValue<ByteArray, byte[]>> nodeValues, final ByteArray key, Node node, List<Versioned<byte[]>> fetched) { if(repairReads) { if(fetched.size() == 0) nodeValues.add(nullValue(node, key)); else { for(Versioned<byte[]> f: fetched) nodeValues.add(new NodeValue<ByteArray, byte[]>(node.getId(), key, f)); } } }
Versioned<byte[]> versioned = Versioned.value(v.getVersioned().getValue(), ((VectorClock) v.getVersion()).clone()); toReadRepair.add(new NodeValue<ByteArray, byte[]>(v.getNodeId(), v.getKey(), versioned));
private void setMetadataVersion(int nodeId, Versioned<byte[]> value) { ByteArray keyArray = getKeyArray(); NodeValue<ByteArray, byte[]> nodeKeyValue = new NodeValue<ByteArray, byte[]>(nodeId, keyArray, value); storeOps.putNodeKeyValue(SystemStoreConstants.SystemStoreName.voldsys$_metadata_version_persistence.name(), nodeKeyValue); }
nodeVersionsMap.put(nodeValue.getNodeId(), nodeValue); mostCurrentVersionsMap.put(nodeValues.get(0).getVersion(), nodeValues.get(0)); if(curr.getVersion().equals(currentGoodversion)) { concurrentToAll = false; if(logger.isDebugEnabled()) { Occurred occurred = curr.getVersion().compare(currentGoodversion); if(occurred == Occurred.BEFORE) { mostCurrentVersionsMap.put(curr.getVersion(), curr); if(logger.isDebugEnabled()) { logger.debug("Updating the current best - adding : " + curr); mostCurrentVersionsMap.put(curr.getVersion(), curr); if(logger.isDebugEnabled()) { logger.debug("Value is concurrent to all ! : " + curr); currentNodeVersions.add(nodeValue.getVersion()); NodeValue<K, V> repair = new NodeValue<K, V>(nodeId, mostCurrentVersionsMap.get(remainingVersion) .getKey(), mostCurrentVersionsMap.get(remainingVersion) .getVersioned()); if(logger.isDebugEnabled()) { logger.debug("Node value marked to be repaired : " + repair);
private NodeValue<ByteArray, byte[]> nullValue(Node node, ByteArray key) { return new NodeValue<ByteArray, byte[]>(node.getId(), key, new Versioned<byte[]>(null)); }
logger.trace("\t" + nodeValue.getNodeId() + " - " + nodeValue.getKey().toString() + " - " + nodeValue.getVersion().toString()); if(this.orphanedValues != null) { for(Versioned<byte[]> value: this.orphanedValues.getValues()) { nodeValues.add(new NodeValue<ByteArray, byte[]>(currentFakeNodeId, this.orphanedValues.getKey(), value)); + ByteUtils.toHexString(nodeKeyValue.getKey().get()) + " on node with id " + nodeKeyValue.getNodeId() + " for version " + nodeKeyValue.getVersion()); if(v.getNodeId() > currentFakeNodeId) { Versioned<byte[]> versioned = Versioned.value(v.getVersioned().getValue(), ((VectorClock) v.getVersion()).clone()); toReadRepair.add(new NodeValue<ByteArray, byte[]>(v.getNodeId(), v.getKey(), versioned)); } else { if(logger.isDebugEnabled()) { logger.debug("\tIgnoring repair to fake node: " + ByteUtils.toHexString(v.getKey().get()) + " on node with id " + v.getNodeId() + " for version " + v.getVersion()); logger.trace("\tRepair key " + ByteUtils.toHexString(nodeKeyValue.getKey().get()) + " on node with id " + nodeKeyValue.getNodeId() + " for version " + nodeKeyValue.getVersion());
public void setQuotaForNode(String storeName, QuotaType quotaType, Integer nodeId, Long quota) { ByteArray keyArray = QuotaUtils.getByteArrayKey(storeName, quotaType); VectorClock clock = makeDenseClock(); byte[] valueArray = ByteUtils.getBytes(quota.toString(), "UTF8"); Versioned<byte[]> value = new Versioned<byte[]>(valueArray, clock); NodeValue<ByteArray, byte[]> nodeKeyValue = new NodeValue<ByteArray, byte[]>(nodeId, keyArray, value); storeOps.putNodeKeyValue(SystemStoreConstants.SystemStoreName.voldsys$_store_quotas.name(), nodeKeyValue); }
if(keyValue.getValues().isEmpty()) { Versioned<byte[]> versioned = new Versioned<byte[]>(null); nodeValues.add(new NodeValue<ByteArray, byte[]>(nodeId, keyValue.getKey(), versioned)); nodeValues.add(new NodeValue<ByteArray, byte[]>(nodeId, keyValue.getKey(), value)); logger.debug("No key-value returned from node with id:" + nodeId); Versioned<byte[]> versioned = new Versioned<byte[]>(null); nodeValues.add(new NodeValue<ByteArray, byte[]>(nodeId, keyAsByteArray, versioned)); logger.debug("\tRead NodeKeyValue : " + ByteUtils.toHexString(nkv.getKey().get()) + " on node with id " + nkv.getNodeId() + " for version " + nkv.getVersion());
public static NodeValue<ByteArray, byte[]> createNodeValue(int nodeId, Version version) { ByteArray key = new ByteArray(new byte[]{54, 52, 49, 57, 52, 54, 51, 51}); byte[] value = new byte[]{69,119,105,119,83,71,80,113,108,108,119,86,67,120,103,111}; Versioned<byte[]> versioned = new Versioned<byte[]>(value, version); return new NodeValue<ByteArray, byte[]>(nodeId, key, versioned); }
/** * Testing helper method to construct node-values out of thin air. * * @param nodeId The node ID * @param value The value (an integer) * @param version The version (vector of integers passed to getClock()) * @return */ private NodeValue<String, Integer> getValue(int nodeId, int value, int[] version) { return new NodeValue<String, Integer>(nodeId, Integer.toString(value), new Versioned<Integer>(value, getClock(version))); }