private HashedArray createRandomData(int length, TestContext context) { byte[] data = new byte[length]; context.random.nextBytes(data); return new HashedArray(data); }
@Override public boolean equals(Object obj) { if (obj instanceof HashedArray) { HashedArray ha = (HashedArray) obj; return this.hashCode == ha.hashCode && arrayEquals(this, ha); } return false; }
@Override public int hashCode() { return HashedArray.hashCode(this.key); }
private boolean keyMatches(ArrayView k1, ArrayView k2) { return new HashedArray(k1).equals(new HashedArray(k2)); }
/** * Tests equals() and hashCode(). */ @Test public void testEqualsHashCode() { val data1 = generate(); val data2 = copy(data1); HashedArray prev = null; for (int i = 0; i < data1.size(); i++) { val a1 = new HashedArray(data1.get(i)); val a2 = new HashedArray(data2.get(i)); Assert.assertEquals("Expecting hashCode() to be the same for the same array contents.", a1.hashCode(), a2.hashCode()); Assert.assertTrue("Expecting equals() to return true for the same array contents.", a1.equals(a2) && a2.equals(a1)); if (prev != null) { Assert.assertNotEquals("Expecting hashCode() to be different for different arrays.", prev.hashCode(), a1.hashCode()); Assert.assertFalse("Expecting equals() to return false for different array contents.", prev.equals(a1) || a1.equals(prev)); } prev = a1; } }
bu.withExistingKey(new BucketUpdate.KeyInfo(new HashedArray(new byte[]{(byte) i}), i)); bu.withKeyUpdate(new BucketUpdate.KeyUpdate(new HashedArray(new byte[]{(byte) -i}), i, i % 2 == 0)); bu.isKeyUpdated(new HashedArray(new byte[]{(byte) -1}))); Assert.assertFalse("Unexpected result from isKeyUpdated for non-updated key.", bu.isKeyUpdated(new HashedArray(new byte[]{(byte) -count}))); val e = existingIterator.next(); val u = updatesIterator.next(); Assert.assertEquals("Unexpected key for existing " + i, (byte) i, e.getKey().get(0)); Assert.assertEquals("Unexpected offset for existing " + i, i, e.getOffset()); Assert.assertEquals("Unexpected key for update " + i, (byte) -i, u.getKey().get(0)); Assert.assertEquals("Unexpected offset for update " + i, i, u.getOffset()); Assert.assertEquals("Unexpected value for isDeleted " + i, i % 2 == 0, u.isDeleted());
@Override public String toString() { return String.format("Length=%d, Hash=%d", getLength(), this.hashCode); }
keyUpdates.add(new BucketUpdate.KeyUpdate(new HashedArray(key), i * hashesPerBucket + j, true)); rnd.nextBytes(key); hashToBuckets.put(KeyHashers.DEFAULT_HASHER.hash(key), bucket); AssertExtensions.assertContainsSameElements("Unexpected updates grouped.", expected, bu.getKeyUpdates(), (u1, u2) -> u1.getKey().equals(u2.getKey()) && u1.getOffset() == u2.getOffset() ? 0 : 1);
private HashMap<HashedArray, Long> generateUpdateBatch(int batchSize, long offset, Random rnd) { val batch = new HashMap<HashedArray, Long>(); int batchOffset = 0; // Randomly generated keys may be duplicated, so we need to loop as long as we need to fill up the batch. while (batch.size() < batchSize) { val key = newKey(rnd); batch.put(key, encodeOffset(offset + batchOffset, false)); batchOffset += key.getLength(); } return batch; }
private HashedArray generateData(int length, Random rnd) { byte[] keyData = new byte[length]; rnd.nextBytes(keyData); return new HashedArray(keyData); }
@Override public boolean equals(Object obj) { if (obj instanceof TableKey) { TableKey other = (TableKey) obj; return HashedArray.arrayEquals(this.key, other.key) && this.version == other.version; } return false; }
/** * Creates a new instance of the HashedArray class. * * @param array An {@link ArrayView} to wrap. */ public HashedArray(ArrayView array) { super(array.array(), array.arrayOffset(), array.getLength()); this.hashCode = hashCode(array); }
val key = toUpdate.get(i); batch.put(key, encodeOffset(offset + batchOffset, false)); batchOffset += key.getLength(); i++;
private HashedArray generateData(int minLength, int maxLength, Random rnd) { byte[] keyData = new byte[Math.max(minLength, rnd.nextInt(maxLength))]; rnd.nextBytes(keyData); return new HashedArray(keyData); }
@Override protected SearchContinuation processResult(TableKey result, ArrayView soughtKey) { if (HashedArray.arrayEquals(soughtKey, result.getKey())) { // Match. return SearchContinuation.ResultFound; } else { // No match: Continue searching if possible. return SearchContinuation.Continue; } }
val key = toRemove.get(i); batch.put(key, encodeOffset(offset + batchOffset, true)); batchOffset += key.getLength(); i++;
private HashedArray newKey(Random rnd) { byte[] key = new byte[Math.max(1, rnd.nextInt(MAX_KEY_LENGTH))]; rnd.nextBytes(key); return new HashedArray(key); }
@Override public boolean equals(Object obj) { if (obj instanceof TableEntry) { TableEntry other = (TableEntry) obj; return this.key.equals(other.key) && ((this.value == null && other.value == null) || (this.value != null && other.value != null && HashedArray.arrayEquals(this.value, other.getValue()))); } return false; } }
/** * Locates all {@link ResultT} instances in a TableBucket. * * @param bucketOffset The current segment offset of the Table Bucket we are looking into. * @param timer A {@link TimeoutTimer} for the operation. * @return A CompletableFuture that, when completed, will contain a List with the desired result items. This list * will exclude all {@link ResultT} items that are marked as deleted. */ CompletableFuture<List<ResultT>> findAllExisting(long bucketOffset, TimeoutTimer timer) { val result = new HashMap<HashedArray, ResultT>(); // This handler ensures that items are only added once (per key) and only if they are not deleted. Since the items // are processed in descending version order, the first time we encounter its key is its latest value. Consumer<ResultT> handler = item -> { TableKey key = getKey(item); HashedArray indexedKey = new HashedArray(key.getKey()); if (!result.containsKey(indexedKey)) { result.put(indexedKey, key.getVersion() == TableKey.NOT_EXISTS ? null : item); } }; return findAll(bucketOffset, handler, timer) .thenApply(v -> result.values().stream().filter(Objects::nonNull).collect(Collectors.toList())); }
Assert.assertTrue("Unexpected value for non-deleted Key.", HashedArray.arrayEquals(expectedEntry.getValue(), actual.getValue())); Assert.assertTrue("Unexpected key for non-deleted Key.", HashedArray.arrayEquals(expectedKey, actual.getKey().getKey())); Assert.assertEquals("Unexpected TableKey.Version for non-deleted Key.", expectedEntry.getVersion(), actual.getKey().getVersion());