/** * Tests the getCeiling() method. */ @Test public void testGetCeiling() { final int itemCount = 1000; final int maxKey = itemCount * 10; // Create an index and populate sparsely. val index = createIndex(); val validKeys = populate(index, itemCount, maxKey); validKeys.sort(KEY_COMPARATOR); val validKeysIterator = validKeys.iterator(); Long expectedValue = -1L; for (long testKey = 0; testKey < maxKey; testKey++) { // Since both testKey and validKeysIterator increase with natural ordering, finding the next expected value // is a straightforward call to the iterator next() method. while (expectedValue != null && testKey > expectedValue) { if (validKeysIterator.hasNext()) { expectedValue = validKeysIterator.next(); } else { expectedValue = null; } } val ceilingEntry = index.getCeiling(testKey); Long actualValue = ceilingEntry != null ? ceilingEntry.key() : null; Assert.assertEquals("Unexpected value for getCeiling for key " + testKey, expectedValue, actualValue); } }
/** * Tests the getFloor() method. */ @Test public void testGetFloor() { final int itemCount = 1000; final int maxKey = itemCount * 10; // Create an index and populate sparsely. val index = createIndex(); val validKeys = populate(index, itemCount, maxKey); validKeys.sort(KEY_REVERSE_COMPARATOR); val validKeysIterator = validKeys.iterator(); Long expectedValue = (long) Integer.MAX_VALUE; for (long testKey = maxKey; testKey >= 0; testKey--) { // Since both testKey and validKeysIterator increase with natural ordering, finding the next expected value // is a straightforward call to the iterator next() method. while (expectedValue != null && testKey < expectedValue) { if (validKeysIterator.hasNext()) { expectedValue = validKeysIterator.next(); } else { expectedValue = null; } } val ceilingEntry = index.getFloor(testKey); Long actualValue = ceilingEntry != null ? ceilingEntry.key() : null; Assert.assertEquals("Unexpected value for getCeiling for key " + testKey, expectedValue, actualValue); } }
/** * 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()); } } }
/** * Tests the forEach() method. */ @Test public void testForEach() { // Create an index and populate it. val index = createIndex(); val validKeys = populate(index); // Extract the keys using forEach - they should be ordered naturally. val actualKeys = new ArrayList<Long>(); index.forEach(e -> actualKeys.add(e.key())); // Order the inserted keys using the same comparator we used for the index. validKeys.sort(KEY_COMPARATOR); // Verify that modifying the index while looping through it does throw an exception. AssertExtensions.assertThrows( "forEach did not throw when a new item was added during enumeration.", () -> index.forEach(e -> index.put(new TestEntry(index.size()))), ex -> ex instanceof ConcurrentModificationException); AssertExtensions.assertThrows( "forEach did not throw when an item was removed during enumeration.", () -> index.forEach(e -> index.remove(e.key())), ex -> ex instanceof ConcurrentModificationException); AssertExtensions.assertThrows( "forEach did not throw when the index was cleared during enumeration.", () -> index.forEach(e -> index.clear()), ex -> ex instanceof ConcurrentModificationException); }