GEODE-1864: Remove old keys correctly from Compact Map Range Index

Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/8c7932e7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/8c7932e7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/8c7932e7

Branch: refs/heads/develop
Commit: 8c7932e763d824e8704dbf0b073d0e5f52ff94fa
Parents: 4a9e23a
Author: Jason Huynh <huyn...@gmail.com>
Authored: Mon Sep 19 11:03:05 2016 -0700
Committer: Jason Huynh <huyn...@gmail.com>
Committed: Wed Sep 21 16:21:03 2016 -0700

----------------------------------------------------------------------
 .../internal/index/CompactMapRangeIndex.java    |  24 ++-
 .../MapRangeIndexMaintenanceJUnitTest.java      | 171 +++++++++++++++++++
 2 files changed, 194 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/8c7932e7/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactMapRangeIndex.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactMapRangeIndex.java
 
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactMapRangeIndex.java
index ce1ea08..234dfae 100644
--- 
a/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactMapRangeIndex.java
+++ 
b/geode-core/src/main/java/org/apache/geode/cache/query/internal/index/CompactMapRangeIndex.java
@@ -16,9 +16,14 @@
  */
 package org.apache.geode.cache.query.internal.index;
 
+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 org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionAttributes;
 import org.apache.geode.cache.query.IndexStatistics;
@@ -110,6 +115,7 @@ public class CompactMapRangeIndex extends AbstractMapIndex
         Object indexKey = mapEntry.getValue();
         this.saveIndexAddition(mapKey, indexKey, value, entry);
       }
+      removeOldMappings(((Map) key).keySet(), entry);
     }
     else {
       for (Object mapKey : mapKeys) {
@@ -121,7 +127,23 @@ 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;
+     for (Map.Entry<?, ?> keyValue : removedKeyValueEntries) {
+      Object indexKey = keyValue.getKey() == null ? IndexManager.NULL : 
keyValue.getKey();
+       if (!presentKeys.contains(indexKey)) {
+        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/8c7932e7/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java
----------------------------------------------------------------------
diff --git 
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java
 
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java
index 9833e43..f79e10b 100644
--- 
a/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java
+++ 
b/geode-core/src/test/java/org/apache/geode/cache/query/internal/index/MapRangeIndexMaintenanceJUnitTest.java
@@ -362,6 +362,177 @@ public class MapRangeIndexMaintenanceJUnitTest{
     assertEquals(1, result.size());
   }
 
+  @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
+  public void testUpdateWithSameKeysSameValuesShouldRetainIndexMappings() 
throws Exception {
+    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");
+    region.put(1, p);
+
+    SelectResults results = (SelectResults) qs.newQuery("select * from 
/portfolio p where p.positions['SUN'] = 1")
+                                              .execute();
+    assertEquals(1, results.size());
+  }
+
+
+  @Test
+  public void testUpdateWithSameKeysDifferentValuesShouldRetainIndexMappings() 
throws Exception {
+    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;
+    map2.put("SUN",3);
+    map2.put("IBM",4);
+    region.put(1, p2);
+
+    SelectResults results = (SelectResults) qs.newQuery("select * from 
/portfolio p where p.positions['SUN'] = 1")
+                                              .execute();
+    assertEquals(0, results.size());
+
+    results = (SelectResults) qs.newQuery("select * from /portfolio p where 
p.positions['SUN'] = 3")
+                                              .execute();
+    assertEquals(1, results.size());
+  }
+
+
+
+
   /**
    * TestObject with wrong comareTo() implementation implementation.
    * Which throws NullPointer while removing mapping from a MapRangeIndex.

Reply via email to