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

Reply via email to