Fix Cache.Iterator and add tests to it
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/984ac18c Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/984ac18c Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/984ac18c Branch: refs/heads/sprint-1 Commit: 984ac18cd199a8b69adcb4e7b7e1078530bd3bb1 Parents: 8a8182a Author: ivasilinets <ivasilin...@gridgain.com> Authored: Wed Jan 14 16:40:24 2015 +0400 Committer: ivasilinets <ivasilin...@gridgain.com> Committed: Wed Jan 14 16:40:24 2015 +0400 ---------------------------------------------------------------------- .../processors/cache/IgniteCacheProxy.java | 36 ++++++-- .../cache/GridCacheAbstractFullApiSelfTest.java | 95 +++++++++++++++++--- 2 files changed, 110 insertions(+), 21 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/984ac18c/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java index 7e20204..3d8c75c 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/processors/cache/IgniteCacheProxy.java @@ -1083,19 +1083,17 @@ public class IgniteCacheProxy<K, V> extends IgniteAsyncSupportAdapter implements /** Current element. */ private Map.Entry<K, V> curIter; + /** Next element. */ + private Map.Entry<K,V> nextIter; + /** - * + * No-arg constructor. */ public IgniteCacheIterator() { fut = delegate.queries().createScanQuery(null).execute(); - } - /** {@inheritDoc} */ - @Override public boolean hasNext() { try { - curIter = fut.next(); - - return curIter != null; + nextIter = fut.next(); } catch (IgniteCheckedException e) { throw cacheException(e); @@ -1103,7 +1101,27 @@ public class IgniteCacheProxy<K, V> extends IgniteAsyncSupportAdapter implements } /** {@inheritDoc} */ + @Override public boolean hasNext() { + return nextIter != null; + } + + /** {@inheritDoc} */ @Override public Entry<K, V> next() { + curIter = nextIter; + + if (curIter == null) { + throw new NoSuchElementException(); + } + + try { + nextIter = fut.next(); + } + catch (IgniteCheckedException e) { + curIter = null; + + throw cacheException(e); + } + return new Cache.Entry<K, V>() { @Override public K getKey() { return curIter.getKey(); @@ -1121,12 +1139,16 @@ public class IgniteCacheProxy<K, V> extends IgniteAsyncSupportAdapter implements /** {@inheritDoc} */ @Override public void remove() { + if (curIter == null) + throw new IllegalStateException(); + try { delegate.removex(curIter.getKey()); } catch (IgniteCheckedException e) { throw cacheException(e); } + curIter = null; } } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/984ac18c/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java ---------------------------------------------------------------------- diff --git a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java index e2d7ba5..0753ab4 100644 --- a/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java +++ b/modules/core/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheAbstractFullApiSelfTest.java @@ -5248,45 +5248,112 @@ public abstract class GridCacheAbstractFullApiSelfTest extends GridCacheAbstract public void testIgniteCacheIterator() throws Exception { IgniteCache<String, Integer> cache = jcache(0); - for (int i = 0; i < 100; ++i) + final int cacheSz = 100; + Map<String, Integer> entries = new HashMap(); + + for (int i = 0; i < cacheSz; ++i) { cache.put(Integer.toString(i), i); + entries.put(Integer.toString(i), i); + } + + checkIteratorHasNext(); - checkIteratorCacheSize(cache, 100); + checkIteratorCache(entries); - removeCacheIterator(cache); + checkIteratorRemove(cache, entries); - checkIteratorCacheSize(cache, 100 - 1); } /** - * Remove one element from the cache. Throws exception if cache is empty. - * + * If hasNext() is called repeatedly, it should return the same result. + */ + private void checkIteratorHasNext() { + Iterator<Cache.Entry<String, Integer>> iter = jcache(0).iterator(); + + assertEquals(iter.hasNext(), iter.hasNext()); + + while (iter.hasNext()) + iter.next(); + + assertFalse(iter.hasNext()); + } + + /** * @param cache Cache. + * @param entries Expected entries in the cache. */ - private void removeCacheIterator(IgniteCache<String, Integer> cache) { - Iterator<Cache.Entry<String, Integer>> iter = cache.iterator(); + private void checkIteratorRemove(IgniteCache<String, Integer> cache, Map<String, Integer> entries) { + //Check that we can remove element. + String rmvKey = Integer.toString(5); + removeCacheIterator(cache, rmvKey); + entries.remove(rmvKey); + assertFalse(cache.containsKey(rmvKey)); + + checkIteratorCache(entries); + + try { + //check that we cannot call Iterator.remove() without next(). + Iterator<Cache.Entry<String, Integer>> iter = jcache(0).iterator(); + + assertTrue(iter.hasNext()); - if (iter.hasNext()) + iter.next(); iter.remove(); - else + iter.remove(); + fail(); + } + catch (Exception e) { + } } /** * @param cache Cache. - * @param size Expected value of cache's size. + * @param key Key to remove. */ - private void checkIteratorCacheSize(IgniteCache<String, Integer> cache, int size) { + private void removeCacheIterator(IgniteCache<String, Integer> cache, String key) { + Iterator<Cache.Entry<String, Integer>> iter = cache.iterator(); + int delCnt = 0; + + while (iter.hasNext()) { + Cache.Entry<String, Integer> cur = iter.next(); + + if (cur.getKey().equals(key)) { + iter.remove(); + delCnt++; + } + + } + + assertEquals(1, delCnt); + } + + /** + * @param entries Expected entries in the cache. + */ + private void checkIteratorCache(Map<String, Integer> entries) { + for (int i = 0; i < gridCount(); ++i) + checkIteratorCache(jcache(i), entries); + } + + /** + * @param cache Cache. + * @param entries Expected entries in the cache. + */ + private void checkIteratorCache(IgniteCache<String, Integer> cache, Map<String, Integer> entries) { Iterator<Cache.Entry<String, Integer>> iter = cache.iterator(); int cnt = 0; while (iter.hasNext()) { - iter.next(); + Cache.Entry<String, Integer> cur = iter.next(); + + assertTrue(entries.containsKey(cur.getKey())); + assertEquals(entries.get(cur.getKey()), cur.getValue()); cnt++; } - assertEquals(size, cnt); + assertEquals(entries.size(), cnt); } }