private void readExact(SortedIndex<TestEntry> rbt, int count) { for (int i = 0; i < count; i++) { rbt.get(i); } }
/** * Tests the clear() method. */ @Test public void testClear() { val index = createIndex(); val keys = populate(index); Assert.assertNotNull("Unexpected return value for getFirst() on non-empty index.", index.getFirst()); Assert.assertNotNull("Unexpected return value for getLast() on non-empty index.", index.getLast()); index.clear(); Assert.assertEquals("Unexpected size of empty index.", 0, index.size()); Assert.assertNull("Unexpected return value for getFirst() on empty index.", index.getFirst()); Assert.assertNull("Unexpected return value for getLast() on empty index.", index.getLast()); for (long key : keys) { Assert.assertNull("Unexpected value for get() on empty index.", index.get(key)); Assert.assertNull("Unexpected value for getCeiling() on empty index.", index.getCeiling(key)); } }
/** * Tests the remove(), size(), get(), getFirst(), getLast() methods. */ @Test public void testRemove() { val index = createIndex(); val keys = populate(index); // Remove the items, in order. keys.sort(KEY_COMPARATOR); val keysToRemove = new LinkedList<Long>(keys); int expectedSize = index.size(); while (keysToRemove.size() > 0) { // Remove either the first or the last key - this helps test getFirst/getLast properly. long key = expectedSize % 2 == 0 ? keysToRemove.removeLast() : keysToRemove.removeFirst(); val entry = index.get(key); val removedEntry = index.remove(key); expectedSize--; Assert.assertEquals("Unexpected removed entry for key " + key, entry, removedEntry); Assert.assertEquals("Unexpected size after removing key " + key, expectedSize, index.size()); Assert.assertNull("Entry was not removed for key " + key, index.get(key)); if (expectedSize == 0) { Assert.assertNull("Unexpected value from getFirst() when index is empty.", index.getFirst()); Assert.assertNull("Unexpected value from getLast() when index is empty.", index.getLast()); } else { Assert.assertEquals("Unexpected value from getFirst() after removing key " + key, (long) keysToRemove.getFirst(), index.getFirst().key()); Assert.assertEquals("Unexpected value from getLast() after removing key " + key, (long) keysToRemove.getLast(), index.getLast().key()); } } }
/** * Tests various operations on already sorted input. */ @Test public void testSortedInput() { val index = createIndex(); for (int key = 0; key < ITEM_COUNT; key++) { index.put(new TestEntry(key)); } //Get + GetCeiling. for (int key = 0; key < ITEM_COUNT; key++) { Assert.assertEquals("Unexpected value from get() for key " + key, key, (long) index.get(key).key()); Assert.assertEquals("Unexpected value from getCeiling() for key " + key, key, (long) index.getCeiling(key).key()); } // Remove + get. for (long key = 0; key < ITEM_COUNT; key++) { long removedKey = index.remove(key).key(); Assert.assertEquals("Unexpected value from remove(). ", key, removedKey); Assert.assertNull("Unexpected value from get() for removed key " + key, index.get(key)); if (key == ITEM_COUNT - 1) { Assert.assertNull("Unexpected value from getCeiling() for removed key " + key, index.getCeiling(key)); } else { Assert.assertEquals("Unexpected value from getCeiling() for removed key " + key, key + 1, (long) index.getCeiling(key).key()); } } }
do { key = rnd.nextInt(); } while (index.get(key) != null); val oldEntry = index.get(key); val entry = new TestEntry(key); val overriddenEntry = index.put(entry); val reRetrievedEntry = index.get(key); Assert.assertEquals("Unexpected overridden entry for key " + key, oldEntry, overriddenEntry); Assert.assertEquals("New entry was not placed in the index for key " + key, entry, reRetrievedEntry);
private ArrayList<Long> populate(SortedIndex<TestEntry> index, int itemCount, int maxKey) { Random rnd = new Random(0); val keys = new ArrayList<Long>(); for (int i = 0; i < itemCount; i++) { // Generate a unique key. long key; do { key = rnd.nextInt(maxKey); } while (index.get(key) != null); keys.add(key); index.put(new TestEntry(key)); } return keys; }
/** * Returns a CacheReadResultEntry that matches the specified search parameters, but only if the data is readily available * in the cache and if there is an index entry that starts at that location.. As opposed from getSingleReadResultEntry(), * this method will return null if the requested data is not available. * * @param resultStartOffset The Offset within the StreamSegment where to start returning data from. * @param maxLength The maximum number of bytes to return. * @return A CacheReadResultEntry representing the data to return. */ private CacheReadResultEntry getSingleMemoryReadResultEntry(long resultStartOffset, int maxLength) { Exceptions.checkNotClosed(this.closed, this); if (maxLength > 0 && checkReadAvailability(resultStartOffset, false) == ReadAvailability.Available) { // Look up an entry in the index that contains our requested start offset. synchronized (this.lock) { ReadIndexEntry indexEntry = this.indexEntries.get(resultStartOffset); if (indexEntry != null && indexEntry.isDataEntry()) { // We found an entry; return a result for it. return createMemoryRead(indexEntry, resultStartOffset, maxLength, true); } } } // Nothing could be found in the cache at the given offset. return null; }
ReadIndexEntry indexEntry = this.indexEntries.get(pendingMerge.getMergeOffset()); assert indexEntry != null && !indexEntry.isDataEntry() : String.format("pendingMergers points to a ReadIndexEntry that does not exist or is of the wrong type. sourceStreamSegmentId = %d, offset = %d, treeEntry = %s.",