Repository: incubator-geode Updated Branches: refs/heads/develop f8e5d1a82 -> 1246f4fae
GEODE-1864: CompactMapRangeIndex now updates/removes from index correctly * Any old mappings are left in the index and not removed correctly Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/1246f4fa Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/1246f4fa Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/1246f4fa Branch: refs/heads/develop Commit: 1246f4faedc38715977244e10fa06fa1962d6288 Parents: f8e5d1a Author: Jason Huynh <huyn...@gmail.com> Authored: Tue Sep 6 10:08:17 2016 -0700 Committer: Jason Huynh <huyn...@gmail.com> Committed: Mon Sep 12 15:57:54 2016 -0700 ---------------------------------------------------------------------- .../internal/index/CompactMapRangeIndex.java | 21 ++++ .../MapRangeIndexMaintenanceJUnitTest.java | 110 +++++++++++++++++++ 2 files changed, 131 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1246f4fa/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/CompactMapRangeIndex.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/CompactMapRangeIndex.java b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/CompactMapRangeIndex.java index a089853..80c9fca 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/CompactMapRangeIndex.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/cache/query/internal/index/CompactMapRangeIndex.java @@ -16,9 +16,16 @@ */ package com.gemstone.gemfire.cache.query.internal.index; +import static javax.swing.UIManager.get; + +import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + import com.gemstone.gemfire.cache.Region; import com.gemstone.gemfire.cache.RegionAttributes; import com.gemstone.gemfire.cache.query.IndexStatistics; @@ -110,6 +117,7 @@ public class CompactMapRangeIndex extends AbstractMapIndex Object indexKey = mapEntry.getValue(); this.saveIndexAddition(mapKey, indexKey, value, entry); } + removeOldMappings(((Map) key).entrySet(), entry); } else { for (Object mapKey : mapKeys) { @@ -121,6 +129,19 @@ public class CompactMapRangeIndex extends AbstractMapIndex } } } + + private void removeOldMappings(Collection presentKeys, RegionEntry entry) throws IMQException { + Map oldKeysAndValuesForEntry = entryToMapKeyIndexKeyMap.get(entry); + if (oldKeysAndValuesForEntry == null) { + oldKeysAndValuesForEntry = Collections.EMPTY_MAP; + } + Set<Entry> removedKeyValueEntries = oldKeysAndValuesForEntry != null ? oldKeysAndValuesForEntry.entrySet(): Collections.EMPTY_SET; + removedKeyValueEntries.removeAll(presentKeys); + for (Map.Entry<?,?> keyValue : removedKeyValueEntries){ + CompactRangeIndex rg = (CompactRangeIndex) this.mapKeyToValueIndex.get(keyValue.getKey()); + rg.removeMapping(keyValue.getValue(), entry); + } + } protected void doIndexAddition(Object mapKey, Object indexKey, Object value, RegionEntry entry) throws IMQException http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/1246f4fa/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java index e346522..55084bd 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java @@ -146,6 +146,116 @@ public class MapRangeIndexMaintenanceJUnitTest{ } } + @Test + public void updatingAMapFieldWithDifferentKeysShouldRemoveOldKeysThatAreNoLongerPresent() throws Exception { + //Create Partition Region + AttributesFactory af = new AttributesFactory(); + af.setScope(Scope.LOCAL); + + Portfolio p = new Portfolio(1, 1); + HashMap map1 = new HashMap(); + map1.put("SUN", 1); + map1.put("IBM", 2); + p.positions = map1; + region = CacheUtils.createRegion("portfolio", af.create(), false); + region.put(1, p); + qs = CacheUtils.getQueryService(); + + keyIndex1 = (IndexProtocol) qs.createIndex(INDEX_NAME, "positions[*]", "/portfolio"); + + assertTrue(keyIndex1 instanceof CompactMapRangeIndex); + + Portfolio p2 = new Portfolio(1, 1); + HashMap map2 = new HashMap(); + p2.positions = map2; + map2.put("NEW_KEY", 1); + region.put(1, p2); + + SelectResults results = (SelectResults) qs.newQuery("select * from /portfolio p where p.positions['SUN'] = 1 OR p.positions['IBM'] = 2").execute(); + assertEquals(0, results.size()); + } + + @Test + public void updatingAMapFieldSameKeysShouldUpdateCorrectly() throws Exception { + //Create Partition Region + AttributesFactory af = new AttributesFactory(); + af.setScope(Scope.LOCAL); + + Portfolio p = new Portfolio(1, 1); + HashMap map1 = new HashMap(); + map1.put("SUN", 1); + map1.put("IBM", 2); + p.positions = map1; + region = CacheUtils.createRegion("portfolio", af.create(), false); + region.put(1, p); + qs = CacheUtils.getQueryService(); + + keyIndex1 = (IndexProtocol) qs.createIndex(INDEX_NAME, "positions[*]", "/portfolio"); + + assertTrue(keyIndex1 instanceof CompactMapRangeIndex); + + Portfolio p2 = new Portfolio(1, 1); + HashMap map2 = new HashMap(); + p2.positions = map2; + map2.put("NEW_KEY", 1); + region.put(1, p2); + + SelectResults results = (SelectResults) qs.newQuery("select * from /portfolio p where p.positions['SUN'] = 1 OR p.positions['IBM'] = 2").execute(); + assertEquals(0, results.size()); + } + + @Test + public void updatingAMapFieldWithNoKeysShouldRemoveOldKeysThatAreNoLongerPresent() throws Exception { + //Create Partition Region + AttributesFactory af = new AttributesFactory(); + af.setScope(Scope.LOCAL); + + Portfolio p = new Portfolio(1, 1); + HashMap map1 = new HashMap(); + map1.put("SUN", 1); + map1.put("IBM", 2); + p.positions = map1; + region = CacheUtils.createRegion("portfolio", af.create(), false); + region.put(1, p); + qs = CacheUtils.getQueryService(); + + keyIndex1 = (IndexProtocol) qs.createIndex(INDEX_NAME, "positions[*]", "/portfolio"); + + Portfolio p2 = new Portfolio(1, 1); + HashMap map2 = new HashMap(); + p2.positions = map2; + region.put(1, p2); + + SelectResults results = (SelectResults) qs.newQuery("select * from /portfolio p where p.positions['SUN'] = 1 OR p.positions['IBM'] = 2").execute(); + assertEquals(0, results.size()); + } + + + @Test + public void updatingEmptyMapToMapWithKeysShouldIndexNewKeysCorrectly() throws Exception { + //Create Partition Region + AttributesFactory af = new AttributesFactory(); + af.setScope(Scope.LOCAL); + + Portfolio p = new Portfolio(1, 1); + HashMap map1 = new HashMap(); + p.positions = map1; + region = CacheUtils.createRegion("portfolio", af.create(), false); + region.put(1, p); + qs = CacheUtils.getQueryService(); + + keyIndex1 = (IndexProtocol) qs.createIndex(INDEX_NAME, "positions[*]", "/portfolio"); + + Portfolio p2 = new Portfolio(1, 1); + HashMap map2 = new HashMap(); + p2.positions = map2; + map2.put("SUN", 1); + map2.put("IBM", 2); + region.put(1, p2); + + SelectResults results = (SelectResults) qs.newQuery("select * from /portfolio p where p.positions['SUN'] = 1 OR p.positions['IBM'] = 2").execute(); + assertEquals(1, results.size()); + } /** * Test index object's comapreTo Function implementation correctness for indexes. * @throws Exception