Bug 8503: Remove empty structures in DAO 99/57799/6
authorLorand Jakab <lojakab@cisco.com>
Thu, 25 May 2017 06:29:15 +0000 (09:29 +0300)
committerLori Jakab <lorand.jakab@gmail.com>
Tue, 13 Jun 2017 13:08:22 +0000 (13:08 +0000)
Change-Id: I52bb47edbb2e34c0b72d874b1ceab33125156f42
Signed-off-by: Lorand Jakab <lojakab@cisco.com>
mappingservice/api/src/main/java/org/opendaylight/lispflowmapping/interfaces/dao/ILispDAO.java
mappingservice/inmemorydb/src/main/java/org/opendaylight/lispflowmapping/inmemorydb/HashMapDb.java
mappingservice/inmemorydb/src/test/java/org/opendaylight/lispflowmapping/inmemorydb/HashMapDbTest.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/AuthKeyDb.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/MultiTableMapCache.java
mappingservice/mapcache/src/main/java/org/opendaylight/lispflowmapping/mapcache/SimpleMapCache.java
mappingservice/mapcache/src/test/java/org/opendaylight/lispflowmapping/mapcache/SimpleMapCacheTest.java

index cea11b2d0e3a42942ff668fcb39e82a0f912eb46..06f76661318e91e3a83ab13b923cfbd0d19fca0c 100644 (file)
@@ -149,4 +149,11 @@ public interface ILispDAO {
      * @return The inserted table
      */
     ILispDAO putNestedTable(Object key, String valueKey);
+
+    /**
+     * Check if the DAO is empty.
+     *
+     * @return true if empty
+     */
+    boolean isEmpty();
 }
index cb5cd5f1d6c24d6dac528a6d3647e6d626e1988a..03a28fbb4e4c766e44b196f5ce5c51d446d0ce5b 100644 (file)
@@ -224,8 +224,18 @@ public class HashMapDb implements ILispDAO, AutoCloseable {
 
     @Override
     public void removeSpecific(Object key, String valueKey) {
-        if (data.containsKey(key) && data.get(key).containsKey(valueKey)) {
-            data.get(key).remove(valueKey);
+        Map<String, Object> keyToValues = data.get(key);
+        if (keyToValues == null) {
+            return;
+        }
+
+        synchronized (keyToValues) {
+            if (keyToValues.containsKey(valueKey)) {
+                keyToValues.remove(valueKey);
+                if (keyToValues.isEmpty()) {
+                    remove(key);
+                }
+            }
         }
     }
 
@@ -263,4 +273,9 @@ public class HashMapDb implements ILispDAO, AutoCloseable {
         put(TABLES, new MappingEntry<>(key, table));
         return table;
     }
+
+    @Override
+    public boolean isEmpty() {
+        return data.isEmpty();
+    }
 }
index a6b42d9ff32f283abd85cde6d018543ae903a0e3..c0c03843e4ea9c1969b5ca698b45aa04482135cb 100644 (file)
@@ -252,7 +252,7 @@ public class HashMapDbTest {
         map.removeSpecific(dbEntryKey, mapKey3);
         Assert.assertNull("Entry should not be present in DB", map.getSpecific(dbEntryKey, mapKey3));
 
-        Assert.assertEquals("MapEntry should be empty after removal the last entry", 0, map.get(dbEntryKey).size());
+        Assert.assertNull("MapEntry should not be present after removal the last entry", map.get(dbEntryKey));
     }
 
     @Test
index 634f6e1000a2654e10e748fe8c10b95a6094a1fe..c4b20e91720903687b9dc8d5c65529d0f6a9e422 100644 (file)
@@ -35,23 +35,24 @@ public class AuthKeyDb implements IAuthKeyDb {
         this.dao = dao;
     }
 
-    private ILispDAO getVniTable(Eid eid) {
-        long vni = 0;
+    private long getVni(Eid eid) {
         if (eid.getVirtualNetworkId() == null) {
-            vni = 0;
+            return 0;
         } else {
-            vni = eid.getVirtualNetworkId().getValue();
+            return eid.getVirtualNetworkId().getValue();
         }
-        return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
+    }
+
+    private ILispDAO getVniTable(Eid eid) {
+        return (ILispDAO) dao.getSpecific(getVni(eid), SubKeys.VNI);
+    }
+
+    private void removeVniTable(Eid eid) {
+        dao.removeSpecific(getVni(eid), SubKeys.VNI);
     }
 
     private ILispDAO getOrInstantiateVniTable(Eid eid) {
-        long vni = 0;
-        if (eid.getVirtualNetworkId() == null) {
-            vni = 0;
-        } else {
-            vni = eid.getVirtualNetworkId().getValue();
-        }
+        long vni = getVni(eid);
         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
         if (table == null) {
             table = dao.putNestedTable(vni, SubKeys.VNI);
@@ -111,6 +112,9 @@ public class AuthKeyDb implements IAuthKeyDb {
             return;
         }
         table.removeSpecific(key, SubKeys.AUTH_KEY);
+        if (table.isEmpty()) {
+            removeVniTable(eid);
+        }
     }
 
     @Override
index 59b4621d2abf18c49840d86d55d4ef626ea5226e..413b5eae6ba29bdd8c22d9ca4e0270f1ac1382d9 100644 (file)
@@ -33,23 +33,24 @@ public class MultiTableMapCache implements IMapCache {
         this.dao = dao;
     }
 
-    private ILispDAO getVniTable(Eid eid) {
-        long vni = 0;
+    private long getVni(Eid eid) {
         if (eid.getVirtualNetworkId() == null) {
-            vni = 0;
+            return 0;
         } else {
-            vni = eid.getVirtualNetworkId().getValue();
+            return eid.getVirtualNetworkId().getValue();
         }
-        return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
+    }
+
+    private ILispDAO getVniTable(Eid eid) {
+        return (ILispDAO) dao.getSpecific(getVni(eid), SubKeys.VNI);
+    }
+
+    private void removeVniTable(Eid eid) {
+        dao.removeSpecific(getVni(eid), SubKeys.VNI);
     }
 
     private ILispDAO getOrInstantiateVniTable(Eid eid) {
-        long vni = 0;
-        if (eid.getVirtualNetworkId() == null) {
-            vni = 0;
-        } else {
-            vni = eid.getVirtualNetworkId().getValue();
-        }
+        long vni = getVni(eid);
         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
         if (table == null) {
             table = dao.putNestedTable(vni, SubKeys.VNI);
@@ -146,10 +147,16 @@ public class MultiTableMapCache implements IMapCache {
             ILispDAO db = getSDInnerDao(key, table);
             if (db != null) {
                 db.remove(SourceDestKeyHelper.getSrcBinary(key));
+                if (db.isEmpty()) {
+                    removeSDInnerDao(key, table);
+                }
             }
         } else {
             table.remove(key);
         }
+        if (table.isEmpty()) {
+            removeVniTable(eid);
+        }
     }
 
     // SrcDst LCAFs are stored in a 2-tier DAO with dst having priority over src.
@@ -170,6 +177,10 @@ public class MultiTableMapCache implements IMapCache {
         return (ILispDAO) mappingsDb.getSpecific(SourceDestKeyHelper.getDstBinary(address), SubKeys.LCAF_SRCDST);
     }
 
+    private void removeSDInnerDao(Eid address, ILispDAO mappingsDb) {
+        mappingsDb.removeSpecific(SourceDestKeyHelper.getDstBinary(address), SubKeys.LCAF_SRCDST);
+    }
+
     @Override
     public void addData(Eid eid, String subKey, Object data) {
         Eid key = MaskUtil.normalize(eid);
@@ -210,10 +221,16 @@ public class MultiTableMapCache implements IMapCache {
             ILispDAO db = getSDInnerDao(key, table);
             if (db != null) {
                 db.removeSpecific(SourceDestKeyHelper.getSrcBinary(key), subKey);
+                if (db.isEmpty()) {
+                    removeSDInnerDao(key, table);
+                }
             }
         } else {
             table.removeSpecific(key, subKey);
         }
+        if (table.isEmpty()) {
+            removeVniTable(eid);
+        }
     }
 
     @Override
index 93a80966d277c54c9288ca3312babd733ed1b169..9d298bab36739fa0161aea6d6677ca4d1859c36d 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.lispflowmapping.mapcache;
 
 import java.util.AbstractMap.SimpleImmutableEntry;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,23 +40,24 @@ public class SimpleMapCache implements ILispMapCache {
         this.dao = dao;
     }
 
-    private ILispDAO getVniTable(Eid eid) {
-        long vni = 0;
+    private long getVni(Eid eid) {
         if (eid.getVirtualNetworkId() == null) {
-            vni = 0;
+            return 0;
         } else {
-            vni = eid.getVirtualNetworkId().getValue();
+            return eid.getVirtualNetworkId().getValue();
         }
-        return (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
+    }
+
+    private ILispDAO getVniTable(Eid eid) {
+        return (ILispDAO) dao.getSpecific(getVni(eid), SubKeys.VNI);
+    }
+
+    private void removeVniTable(Eid eid) {
+        dao.removeSpecific(getVni(eid), SubKeys.VNI);
     }
 
     private ILispDAO getOrInstantiateVniTable(Eid eid) {
-        long vni = 0;
-        if (eid.getVirtualNetworkId() == null) {
-            vni = 0;
-        } else {
-            vni = eid.getVirtualNetworkId().getValue();
-        }
+        long vni = getVni(eid);
         ILispDAO table = (ILispDAO) dao.getSpecific(vni, SubKeys.VNI);
         if (table == null) {
             table = dao.putNestedTable(vni, SubKeys.VNI);
@@ -206,20 +208,15 @@ public class SimpleMapCache implements ILispMapCache {
 
         Eid key = MaskUtil.normalize(eid);
         table.remove(key);
+        if (table.isEmpty()) {
+            removeVniTable(eid);
+        }
     }
 
     @Override
     public void removeMapping(Eid eid, XtrId xtrId) {
-        ILispDAO table = getVniTable(eid);
-        if (table == null) {
-            return;
-        }
-        Eid key = MaskUtil.normalize(eid);
-        ILispDAO xtrIdTable = (ILispDAO) table.getSpecific(key, SubKeys.XTRID_RECORDS);
-        if (xtrIdTable == null) {
-            return;
-        }
-        xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
+        List<XtrId> xtrIds = Arrays.asList(xtrId);
+        removeXtrIdMappings(eid, xtrIds);
     }
 
     @Override
@@ -236,6 +233,12 @@ public class SimpleMapCache implements ILispMapCache {
         for (XtrId xtrId : xtrIds) {
             xtrIdTable.removeSpecific(xtrId, SubKeys.RECORD);
         }
+        if (xtrIdTable.isEmpty()) {
+            table.removeSpecific(key, SubKeys.XTRID_RECORDS);
+            if (table.isEmpty()) {
+                removeVniTable(eid);
+            }
+        }
     }
 
     @Override
@@ -247,7 +250,7 @@ public class SimpleMapCache implements ILispMapCache {
 
     @Override
     public Object getData(Eid eid, String subKey) {
-        ILispDAO table = getOrInstantiateVniTable(eid);
+        ILispDAO table = getVniTable(eid);
         if (table == null) {
             return null;
         }
@@ -257,12 +260,15 @@ public class SimpleMapCache implements ILispMapCache {
 
     @Override
     public void removeData(Eid eid, String subKey) {
-        ILispDAO table = getOrInstantiateVniTable(eid);
+        ILispDAO table = getVniTable(eid);
         if (table == null) {
             return;
         }
         Eid key = MaskUtil.normalize(eid);
         table.removeSpecific(key, subKey);
+        if (table.isEmpty()) {
+            removeVniTable(eid);
+        }
     }
 
     @Override
index 547b9e366dbc5e715c4b0381aa689b5b9031b932..2fcd1477d986b3b40e917c802d120610b9e0b10d 100644 (file)
@@ -109,6 +109,7 @@ public class SimpleMapCacheTest {
 
         simpleMapCache.removeMapping(EID_IPV4);
         Mockito.verify(tableMock).remove(MaskUtil.normalize(EID_IPV4));
+        Mockito.verify(tableMock).isEmpty();
         Mockito.verifyNoMoreInteractions(tableMock);
     }