@SPITest @SuppressWarnings("unchecked") public void iterableContainsValuesInAnyOrder() throws StoreAccessException, IllegalAccessException, InstantiationException { K key1 = factory.createKey(1L); K key2 = factory.createKey(2L); K key3 = factory.createKey(3L); V value1 = factory.createValue(1L); V value2 = factory.createValue(2L); V value3 = factory.createValue(3L); kvStore.put(key1, value1); kvStore.put(key2, value2); kvStore.put(key3, value3); Store.Iterator<Cache.Entry<K, Store.ValueHolder<V>>> iterator = kvStore.iterator(); List<K> keys = new ArrayList<>(); List<V> values = new ArrayList<>(); while (iterator.hasNext()) { Cache.Entry<K, Store.ValueHolder<V>> nextEntry = iterator.next(); keys.add(nextEntry.getKey()); values.add(nextEntry.getValue().get()); } assertThat(keys, containsInAnyOrder(equalTo(key1), equalTo(key2), equalTo(key3))); assertThat(values, containsInAnyOrder(equalTo(value1), equalTo(value2), equalTo(value3))); } }
@Override public void remove() { if (current == null) { throw new IllegalStateException(); } cache.remove(current.getKey()); current = null; } }
@SPITest public void nextReturnsNextElement() throws IllegalAccessException, InstantiationException, StoreAccessException, LegalSPITesterException { kvStore = factory.newStore(); K key = factory.createKey(1); V value = factory.createValue(1); kvStore.put(key, value); Store.Iterator<Cache.Entry<K, Store.ValueHolder<V>>> iterator = kvStore.iterator(); try { Cache.Entry<K, Store.ValueHolder<V>> entry = iterator.next(); assertThat(entry.getKey(), is(equalTo(key))); assertThat(entry.getValue().get(), is(equalTo(value))); } catch (StoreAccessException e) { throw new LegalSPITesterException("Warning, an exception is thrown due to the SPI test"); } }
@Override public Cache.Entry<K, V> next() { try { Cache.Entry<K, Store.ValueHolder<V>> next = iterator.next(); final K nextKey = next.getKey(); Store.ValueHolder<V> nextValueHolder = next.getValue(); // call Cache.get() here to check for expiry *and* account for a get in the stats, without using the loader if (cache.getNoLoader(nextKey) == null) { current = null; return null; } current = next; final V nextValue = nextValueHolder.get(); return new Cache.Entry<K, V>() { @Override public K getKey() { return nextKey; } @Override public V getValue() { return nextValue; } }; } catch (StoreAccessException sae) { current = null; return null; } }
@Test public void testIteratorDoesNotSkipOrExpiresEntries() throws Exception { offHeapStore = createAndInitStore(timeSource, ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMillis(10L))); offHeapStore.put("key1", "value1"); offHeapStore.put("key2", "value2"); timeSource.advanceTime(11L); offHeapStore.put("key3", "value3"); offHeapStore.put("key4", "value4"); final List<String> expiredKeys = new ArrayList<>(); offHeapStore.getStoreEventSource().addEventListener(event -> { if (event.getType() == EventType.EXPIRED) { expiredKeys.add(event.getKey()); } }); List<String> iteratedKeys = new ArrayList<>(); Store.Iterator<Cache.Entry<String, Store.ValueHolder<String>>> iterator = offHeapStore.iterator(); while(iterator.hasNext()) { iteratedKeys.add(iterator.next().getKey()); } assertThat(iteratedKeys, containsInAnyOrder("key1", "key2", "key3", "key4")); assertThat(expiredKeys.isEmpty(), is(true)); }
@Test public void iterator() { cache.put(1, "a"); cache.put(2, "b"); changesOf(0, 0, 2, 0); Iterator<Cache.Entry<Integer, String>> iterator = cache.iterator(); changesOf(1, 0, 0, 0); // FIXME Why one?!? iterator.next().getKey(); changesOf(2, 0, 0, 0); // FIXME Why two?!? expect(iterator.hasNext()).isTrue(); changesOf(0, 0, 0, 0); iterator.next().getKey(); changesOf(1, 0, 0, 0); expect(iterator.hasNext()).isFalse(); changesOf(0, 0, 0, 0); iterator.remove(); changesOf(1, 0, 0, 1); // FIXME remove does hit }
@Test public void iterator() { cache.put(1, "a"); cache.put(2, "b"); changesOf(0, 0, 2, 0); Iterator<Cache.Entry<Integer, String>> iterator = cache.iterator(); changesOf(1, 0, 0, 0); // FIXME Why one?!? iterator.next().getKey(); changesOf(1, 0, 0, 0); // FIXME One hit and on the cache we have two expect(iterator.hasNext()).isTrue(); changesOf(0, 0, 0, 0); iterator.next().getKey(); changesOf(0, 0, 0, 0); // FIXME No hit on a next expect(iterator.hasNext()).isFalse(); changesOf(0, 0, 0, 0); iterator.remove(); changesOf(1, 0, 0, 1); // FIXME remove does hit }
@Override public void run() { try { transactionManager.begin(); Map<Long, String> result = new HashMap<>(); for (Cache.Entry<Long, String> next : txCache1) { result.put(next.getKey(), next.getValue()); } assertThat(result.size(), equalTo(0)); transactionManager.commit(); } catch (Throwable t) { throwableRef.set(t); } } };
/** * Tests fetching all entries via an {@link Ehcache#iterator()} on a non-empty cache. */ @Test public void testIteratorNonEmptyAll() throws Exception { final Map<String, String> testStoreEntries = this.getTestStoreEntries(); this.store = new FakeStore(testStoreEntries); final InternalCache<String, String> ehcache = this.getEhcache(); for (Cache.Entry<String, String> cacheEntry : ehcache) { final String cacheEntryKey = cacheEntry.getKey(); assertThat(testStoreEntries, hasEntry(equalTo(cacheEntryKey), equalTo(cacheEntry.getValue()))); testStoreEntries.remove(cacheEntryKey); } assertThat("Iterator did not return all values", testStoreEntries.isEmpty(), is(true)); }
@Test public void testKeyUniqueObject() throws Exception { OnHeapStore<Serializable, Serializable> store = newStore(); List<String> key = new ArrayList<>(); key.add("key"); String value = "value"; store.put((Serializable)key, value); // mutate the key -- should not affect cache key.clear(); Serializable storeKey = store.iterator().next().getKey(); if (storeKey == key || ! storeKey.equals(Collections.singletonList("key"))) { throw new AssertionError(); } }
@Override public K getKey() { return storeEntry.getKey(); }
@Override public K getKey() { return ehEntry.getKey(); }
private static void assertEntry(Entry<String, ValueHolder<String>> entry, String key, String value) { assertThat(entry.getKey(), equalTo(key)); assertThat(entry.getValue().get(), equalTo(value)); }
@Test public void testIteration() throws StoreAccessException { store.put(KEY, VALUE); Store.Iterator<Cache.Entry<Key, Store.ValueHolder<String>>> iterator = store.iterator(); assertThat(iterator.hasNext(), is(true)); while (iterator.hasNext()) { Cache.Entry<Key, Store.ValueHolder<String>> entry = iterator.next(); if (copyForRead || copyForWrite) { assertThat(entry.getKey(), not(sameInstance(KEY))); } else { assertThat(entry.getKey(), sameInstance(KEY)); } } }
@Test public void testIteratorWithSingleNonExpiredEntry() throws Exception { offHeapStore = createAndInitStore(timeSource, ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMillis(10L))); offHeapStore.put("key1", "value1"); timeSource.advanceTime(5L); Store.Iterator<Cache.Entry<String, Store.ValueHolder<String>>> iterator = offHeapStore.iterator(); assertTrue(iterator.hasNext()); assertThat(iterator.next().getKey(), is("key1")); }
@Test public void testIteratorWithSingleExpiredEntry() throws Exception { offHeapStore = createAndInitStore(timeSource, ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofMillis(10L))); offHeapStore.put("key1", "value1"); timeSource.advanceTime(11L); Store.Iterator<Cache.Entry<String, Store.ValueHolder<String>>> iterator = offHeapStore.iterator(); assertTrue(iterator.hasNext()); assertThat(iterator.next().getKey(), equalTo("key1")); assertFalse(iterator.hasNext()); }
private static Map<String, String> observe(Iterator<Entry<String, ValueHolder<String>>> iter) throws StoreAccessException { Map<String, String> map = new HashMap<>(); while (iter.hasNext()) { Entry<String, ValueHolder<String>> entry = iter.next(); map.put(entry.getKey(), entry.getValue().get()); } return map; }
private static Map<String, Long> observeAccessTimes(Iterator<Entry<String, ValueHolder<String>>> iter) throws StoreAccessException { Map<String, Long> map = new HashMap<>(); while (iter.hasNext()) { Entry<String, ValueHolder<String>> entry = iter.next(); map.put(entry.getKey(), entry.getValue().lastAccessTime()); } return map; }
private K getOnlyKey(Store.Iterator<Cache.Entry<K, Store.ValueHolder<V>>> iter) throws StoreAccessException { if (iter.hasNext()) { Cache.Entry<K, Store.ValueHolder<V>> entry = iter.next(); return entry.getKey(); } return null; }