From d69e73d68ac414a0220bdc18daf753143706ffd1 Mon Sep 17 00:00:00 2001
From: Rob Vaterlaus <rob.vaterlaus@bigswitch.com>
Date: Thu, 16 Feb 2012 23:31:51 -0800
Subject: [PATCH] Added support for storage source counters for query, update,
 and delete operations [#25095875]. Added a REST API to get the list of
 storage source tables used by floodlight.

---
 .../core/internal/Controller.java             |   4 +-
 .../core/web/CoreWebRoutable.java             |   1 +
 .../core/web/StorageSourceTablesResource.java |  17 ++
 .../internal/DeviceManagerImpl.java           |   4 +-
 .../storage/AbstractStorageSource.java        | 158 ++++++++++++++++--
 .../floodlightcontroller/storage/IQuery.java  |   2 +-
 .../storage/IStorageSource.java               |  57 +++++--
 .../storage/memory/MemoryStorageSource.java   |   5 +-
 .../storage/nosql/NoSqlQuery.java             |   3 +-
 .../storage/nosql/NoSqlResultSet.java         |   4 +-
 .../storage/nosql/NoSqlStorageSource.java     |  43 +----
 .../storage/tests/StorageTest.java            |  14 +-
 12 files changed, 237 insertions(+), 75 deletions(-)
 create mode 100644 src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java

diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
index 17ade3fb5..47c7c5060 100644
--- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java
+++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java
@@ -1479,7 +1479,9 @@ public class Controller
     }
     
     protected void initStorageSource() {
-        storageSource = new MemoryStorageSource();
+        MemoryStorageSource memoryStorageSource = new MemoryStorageSource();
+        memoryStorageSource.setCounterStore(counterStore);
+        storageSource = memoryStorageSource;
     }
     
     protected void initMessageFilterManager() {
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index ee8acfd91..73aa1e26f 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -54,6 +54,7 @@ public class CoreWebRoutable implements RestletRoutable {
                 EventHistoryTopologyLinkResource.class);
         router.attach("/event-history/topology-cluster/{count}/json",
                 EventHistoryTopologyClusterResource.class);
+        router.attach("/storage/tables/json", StorageSourceTablesResource.class);
         return router;
     }
 }
diff --git a/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java b/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java
new file mode 100644
index 000000000..e657251e8
--- /dev/null
+++ b/src/main/java/net/floodlightcontroller/core/web/StorageSourceTablesResource.java
@@ -0,0 +1,17 @@
+package net.floodlightcontroller.core.web;
+
+import java.util.Set;
+
+import net.floodlightcontroller.storage.IStorageSource;
+
+import org.restlet.resource.Get;
+import org.restlet.resource.ServerResource;
+
+public class StorageSourceTablesResource extends ServerResource {
+    @Get("json")
+    public Set<String> retrieve() {
+        IStorageSource storageSource = (IStorageSource)getContext().getAttributes().get("storageSource");
+        Set<String> allTableNames = storageSource.getAllTableNames();
+        return allTableNames;
+    }
+}
diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
index b1e3cc149..693ec9132 100755
--- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
+++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java
@@ -1735,10 +1735,10 @@ public class DeviceManagerImpl implements IDeviceManager, IOFMessageListener,
         String deviceId = device.getDlAddrString();
 
         // Remove all of the attachment points
-        storageSource.deleteRowsAsync(DEVICE_ATTACHMENT_POINT_TABLE_NAME,
+        storageSource.deleteMatchingRowsAsync(DEVICE_ATTACHMENT_POINT_TABLE_NAME,
                 new OperatorPredicate(DEVICE_COLUMN_NAME, 
                         OperatorPredicate.Operator.EQ, deviceId));
-        storageSource.deleteRowsAsync(DEVICE_NETWORK_ADDRESS_TABLE_NAME,
+        storageSource.deleteMatchingRowsAsync(DEVICE_NETWORK_ADDRESS_TABLE_NAME,
                 new OperatorPredicate(DEVICE_COLUMN_NAME, 
                         OperatorPredicate.Operator.EQ, deviceId));
 
diff --git a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
index ecf33eb9c..2c5bd128e 100644
--- a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java
@@ -30,6 +30,10 @@ import java.util.concurrent.Future;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import net.floodlightcontroller.counter.ICounter;
+import net.floodlightcontroller.counter.CounterStore;
+import net.floodlightcontroller.counter.CounterValue.CounterType;
+
 public abstract class AbstractStorageSource implements IStorageSource {
     protected static Logger logger = LoggerFactory.getLogger(AbstractStorageSource.class);
 
@@ -42,7 +46,13 @@ public abstract class AbstractStorageSource implements IStorageSource {
     // to a single worker thread. But for now, we'll keep it simple and just have
     // a single thread for all operations.
     protected static ExecutorService defaultExecutorService = Executors.newSingleThreadExecutor();
+
+    protected final static String STORAGE_QUERY_COUNTER_NAME = "StorageQuery";
+    protected final static String STORAGE_UPDATE_COUNTER_NAME = "StorageUpdate";
+    protected final static String STORAGE_DELETE_COUNTER_NAME = "StorageDelete";
     
+    protected Set<String> allTableNames = new CopyOnWriteArraySet<String>();
+    protected CounterStore counterStore;
     protected ExecutorService executorService = defaultExecutorService;
     protected IStorageExceptionHandler exceptionHandler;
 
@@ -103,14 +113,47 @@ public abstract class AbstractStorageSource implements IStorageSource {
     public abstract void setTablePrimaryKeyName(String tableName, String primaryKeyName);
 
     @Override
-    public abstract void createTable(String tableName, Set<String> indexedColumns);
+    public void createTable(String tableName, Set<String> indexedColumns) {
+        allTableNames.add(tableName);
+    }
 
+    @Override
+    public Set<String> getAllTableNames() {
+        return allTableNames;
+    }
+    
+    public void setCounterStore(CounterStore counterStore) {
+        this.counterStore = counterStore;
+    }
+    
+    protected void updateCounters(String baseName, String tableName) {
+        if (counterStore != null) {
+            String counterName;
+            if (tableName != null) {
+                updateCounters(baseName, null);
+                counterName = baseName + CounterStore.TitleDelimitor + tableName;
+            } else {
+                counterName = baseName;
+            }
+            ICounter counter = counterStore.getCounter(counterName);
+            if (counter == null) {
+                counter = counterStore.createCounter(counterName, CounterType.LONG);
+            }
+            counter.increment();
+        }
+    }
+    
     @Override
     public abstract IQuery createQuery(String tableName, String[] columnNames,
             IPredicate predicate, RowOrdering ordering);
 
     @Override
-    public abstract IResultSet executeQuery(IQuery query);
+    public IResultSet executeQuery(IQuery query) {
+        updateCounters(STORAGE_QUERY_COUNTER_NAME, query.getTableName());
+        return executeQueryImpl(query);
+    }
+    
+    protected abstract IResultSet executeQueryImpl(IQuery query);
 
     @Override
     public IResultSet executeQuery(String tableName, String[] columnNames,
@@ -184,12 +227,23 @@ public abstract class AbstractStorageSource implements IStorageSource {
     }
 
     @Override
-    public Future<?> updateRowsAsync(final String tableName,
+    public Future<?> updateRowsAsync(final String tableName, final List<Map<String,Object>> rows) {
+        Future<?> future = executorService.submit(    
+            new StorageRunnable() {
+                public void doStorageOperation() {
+                    updateRows(tableName, rows);
+                }
+            }, null);
+        return future;
+    }
+
+    @Override
+    public Future<?> updateMatchingRowsAsync(final String tableName,
             final IPredicate predicate, final Map<String,Object> values) {
         Future<?> future = executorService.submit(    
             new StorageRunnable() {
                 public void doStorageOperation() {
-                    updateRows(tableName, predicate, values);
+                    updateMatchingRows(tableName, predicate, values);
                 }
             }, null);
         return future;
@@ -231,11 +285,22 @@ public abstract class AbstractStorageSource implements IStorageSource {
     }
 
     @Override
-    public Future<?> deleteRowsAsync(final String tableName, final IPredicate predicate) {
+    public Future<?> deleteRowsAsync(final String tableName, final Set<Object> rowKeys) {
+        Future<?> future = executorService.submit(
+                new StorageRunnable() {
+                    public void doStorageOperation() {
+                        deleteRows(tableName, rowKeys);
+                    }
+                }, null);
+        return future;
+    }
+
+    @Override
+    public Future<?> deleteMatchingRowsAsync(final String tableName, final IPredicate predicate) {
         Future<?> future = executorService.submit(
                 new StorageRunnable() {
                     public void doStorageOperation() {
-                        deleteRows(tableName, predicate);
+                        deleteMatchingRows(tableName, predicate);
                     }
                 }, null);
         return future;
@@ -264,24 +329,89 @@ public abstract class AbstractStorageSource implements IStorageSource {
     }
 
     @Override
-    public abstract void insertRow(String tableName, Map<String, Object> values);
+    public void insertRow(String tableName, Map<String, Object> values) {
+        updateCounters(STORAGE_UPDATE_COUNTER_NAME, tableName);
+        insertRowImpl(tableName, values);
+    }
 
+    protected abstract void insertRowImpl(String tableName, Map<String, Object> values);
+
+    
     @Override
-    public abstract void updateRows(String tableName, IPredicate predicate,
-            Map<String, Object> values);
+    public void updateRows(String tableName, List<Map<String,Object>> rows) {
+        updateCounters(STORAGE_UPDATE_COUNTER_NAME, tableName);
+        updateRowsImpl(tableName, rows);
+    }
+
+    protected abstract void updateRowsImpl(String tableName, List<Map<String,Object>> rows);
+
+    @Override
+    public void updateMatchingRows(String tableName, IPredicate predicate,
+            Map<String, Object> values) {
+        updateCounters(STORAGE_UPDATE_COUNTER_NAME, tableName);
+        updateMatchingRowsImpl(tableName, predicate, values);
+    }
+    
+    protected abstract void updateMatchingRowsImpl(String tableName, IPredicate predicate,
+                                    Map<String, Object> values);
+
+    @Override
+    public void updateRow(String tableName, Object rowKey,
+            Map<String, Object> values) {
+        updateCounters(STORAGE_UPDATE_COUNTER_NAME, tableName);
+        updateRowImpl(tableName, rowKey, values);
+    }
+    
+    protected abstract void updateRowImpl(String tableName, Object rowKey,
+                                   Map<String, Object> values);
 
     @Override
-    public abstract void updateRow(String tableName, Object rowKey,
-            Map<String, Object> values);
+    public void updateRow(String tableName, Map<String, Object> values) {
+        updateCounters(STORAGE_UPDATE_COUNTER_NAME, tableName);
+        updateRowImpl(tableName, values);
+    }
+    
+    protected abstract void updateRowImpl(String tableName, Map<String, Object> values);
 
     @Override
-    public abstract void updateRow(String tableName, Map<String, Object> values);
+    public void deleteRow(String tableName, Object rowKey) {
+        updateCounters(STORAGE_DELETE_COUNTER_NAME, tableName);
+        deleteRowImpl(tableName, rowKey);
+    }
+    
+    protected abstract void deleteRowImpl(String tableName, Object rowKey);
 
     @Override
-    public abstract void deleteRow(String tableName, Object rowKey);
+    public void deleteRows(String tableName, Set<Object> rowKeys) {
+        updateCounters(STORAGE_DELETE_COUNTER_NAME, tableName);
+        deleteRowsImpl(tableName, rowKeys);
+    }
+
+    protected abstract void deleteRowsImpl(String tableName, Set<Object> rowKeys);
 
     @Override
-    public abstract IResultSet getRow(String tableName, Object rowKey);
+    public void deleteMatchingRows(String tableName, IPredicate predicate) {
+        IResultSet resultSet = null;
+        try {
+            resultSet = executeQuery(tableName, null, predicate, null);
+            while (resultSet.next()) {
+                resultSet.deleteRow();
+            }
+            resultSet.save();
+        }
+        finally {
+            if (resultSet != null)
+                resultSet.close();
+        }
+    }
+    
+    @Override
+    public IResultSet getRow(String tableName, Object rowKey) {
+        updateCounters(STORAGE_QUERY_COUNTER_NAME, tableName);
+        return getRowImpl(tableName, rowKey);
+    }
+
+    protected abstract IResultSet getRowImpl(String tableName, Object rowKey);
 
     @Override
     public synchronized void addListener(String tableName, IStorageSourceListener listener) {
diff --git a/src/main/java/net/floodlightcontroller/storage/IQuery.java b/src/main/java/net/floodlightcontroller/storage/IQuery.java
index bc8460536..b75b8ae59 100644
--- a/src/main/java/net/floodlightcontroller/storage/IQuery.java
+++ b/src/main/java/net/floodlightcontroller/storage/IQuery.java
@@ -34,6 +34,6 @@ package net.floodlightcontroller.storage;
  *
  */
 public interface IQuery {
-
+    String getTableName();
     void setParameter(String name, Object value);
 }
diff --git a/src/main/java/net/floodlightcontroller/storage/IStorageSource.java b/src/main/java/net/floodlightcontroller/storage/IStorageSource.java
index f1f29f8af..d4d1195e1 100644
--- a/src/main/java/net/floodlightcontroller/storage/IStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/IStorageSource.java
@@ -52,6 +52,11 @@ public interface IStorageSource {
      */
     void createTable(String tableName, Set<String> indexedColumns);
     
+    /**
+     * @return the set of all tables that have been created via createTable
+     */
+    Set<String> getAllTableNames();
+    
     /** Create a query object representing the given query parameters. The query
      * object can be passed to executeQuery to actually perform the query and obtain
      * a result set.
@@ -102,13 +107,19 @@ public interface IStorageSource {
             RowOrdering ordering, IRowMapper rowMapper);
     
     /** Insert a new row in the table with the given column data.
-     * The primary key for the row in the table is indicated with the special column
-     * name of "id". If there's no "id" values specified in the map of values, then
-     * a unique id will be automatically assigned to the row.
+     * If the primary key is the default value of "id" and is not specified in the
+     * then a unique id will be automatically assigned to the row.
      * @param tableName The name of the table to which to add the row
      * @param values The map of column names/values to add to the table.
      */
     void insertRow(String tableName, Map<String,Object> values);
+
+    /** Update or insert a list of rows in the table.
+     * The primary key must be included in the map of values for each row.
+     * @param tableName The table to update or insert into
+     * @param values The map of column names/values to update the rows
+     */
+    void updateRows(String tableName, List<Map<String,Object>> rows);
     
     /** Update the rows in the given table. Any rows matching the predicate
      * are updated with the column names/values specified in the values map.
@@ -117,7 +128,7 @@ public interface IStorageSource {
      * @param predicate The predicate to use to select which rows to update
      * @param values The map of column names/values to update the rows.
      */
-    void updateRows(String tableName, IPredicate predicate, Map<String,Object> values);
+    void updateMatchingRows(String tableName, IPredicate predicate, Map<String,Object> values);
     
     /** Update or insert a row in the table with the given row key (primary
      * key) and column names/values. (If the values map contains the special
@@ -129,25 +140,32 @@ public interface IStorageSource {
     void updateRow(String tableName, Object rowKey, Map<String,Object> values);
     
     /** Update or insert a row in the table with the given column data.
-     * The primary key is indicated with the special column name of "id".
+     * The primary key must be included in the map of values.
      * @param tableName The table to update or insert into
      * @param values The map of column names/values to update the rows
      */
     void updateRow(String tableName, Map<String,Object> values);
     
-    /** Delete the row with the given row ID (primary key).
+    /** Delete the row with the given primary key.
      * 
      * @param tableName The table from which to delete the row
      * @param rowKey The primary key of the row to delete.
      */
     void deleteRow(String tableName, Object rowKey);
 
+    /** Delete the rows with the given keys.
+     * 
+     * @param tableName The table from which to delete the rows
+     * @param rowKeys The set of primary keys of the rows to delete.
+     */
+    void deleteRows(String tableName, Set<Object> rowKeys);
+    
     /**
      * Delete the rows that match the predicate
      * @param tableName
      * @param predicate
      */
-    void deleteRows(String tableName, IPredicate predicate);
+    void deleteMatchingRows(String tableName, IPredicate predicate);
     
     /** Query for a row with the given ID (primary key).
      * 
@@ -186,6 +204,7 @@ public interface IStorageSource {
     
     /**
      * Asynchronous variant of executeQuery
+     * 
      * @param tableName
      * @param columnNames
      * @param predicate
@@ -205,16 +224,23 @@ public interface IStorageSource {
      * @return
      */
     public Future<?> insertRowAsync(final String tableName, final Map<String,Object> values);
-    
+
     /**
      * Asynchronous variant of updateRows
+     * @param tableName
+     * @param rows
+     */
+    public Future<?> updateRowsAsync(final String tableName, final List<Map<String,Object>> rows);
+
+    /**
+     * Asynchronous variant of updateMatchingRows
      * 
      * @param tableName
      * @param predicate
      * @param values
      * @return
      */
-    public Future<?> updateRowsAsync(final String tableName, final IPredicate predicate,
+    public Future<?> updateMatchingRowsAsync(final String tableName, final IPredicate predicate,
             final Map<String,Object> values);
 
     /**
@@ -245,7 +271,16 @@ public interface IStorageSource {
      * @return
      */
     public Future<?> deleteRowAsync(final String tableName, final Object rowKey);
-    
+
+    /**
+     * Asynchronous version of deleteRows
+     * 
+     * @param tableName
+     * @param rowKeys
+     * @return
+     */
+    public Future<?> deleteRowsAsync(final String tableName, final Set<Object> rowKeys);
+
     /**
      * Asynchronous version of deleteRows
      * 
@@ -253,7 +288,7 @@ public interface IStorageSource {
      * @param predicate
      * @return
      */
-    public Future<?> deleteRowsAsync(final String tableName, final IPredicate predicate);
+    public Future<?> deleteMatchingRowsAsync(final String tableName, final IPredicate predicate);
     
     /**
      * Asynchronous version of getRow
diff --git a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
index d4c1ca417..181bd9fd1 100644
--- a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java
@@ -140,7 +140,7 @@ public class MemoryStorageSource extends NoSqlStorageSource {
     }
     
     @Override
-    protected void updateRows(String tableName, List<Map<String,Object>> updateRowList) {
+    protected void updateRowsImpl(String tableName, List<Map<String,Object>> updateRowList) {
         MemoryTable table = getTable(tableName, false);
         String primaryKeyName = getTablePrimaryKeyName(tableName);
         synchronized (table) {
@@ -159,7 +159,7 @@ public class MemoryStorageSource extends NoSqlStorageSource {
     }
     
     @Override
-    protected void deleteRows(String tableName, Set<Object> rowKeys) {
+    protected void deleteRowsImpl(String tableName, Set<Object> rowKeys) {
         MemoryTable table = getTable(tableName, false);
         synchronized (table) {
             for (Object rowKey : rowKeys) {
@@ -170,6 +170,7 @@ public class MemoryStorageSource extends NoSqlStorageSource {
     
     @Override
     public void createTable(String tableName, Set<String> indexedColumnNames) {
+        super.createTable(tableName, indexedColumnNames);
         getTable(tableName, true);
     }
     
diff --git a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlQuery.java b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlQuery.java
index 659beb03f..05f8fc7c9 100644
--- a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlQuery.java
+++ b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlQuery.java
@@ -46,7 +46,8 @@ public class NoSqlQuery implements IQuery {
         parameterMap.put(name, (Comparable<?>)value);
     }
 
-    String getTableName() {
+    @Override
+    public String getTableName() {
         return tableName;
     }
     
diff --git a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlResultSet.java b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlResultSet.java
index 8b80f8da7..b3a8c20df 100644
--- a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlResultSet.java
+++ b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlResultSet.java
@@ -100,12 +100,12 @@ public class NoSqlResultSet implements IResultSet {
         endCurrentRowUpdate();
         
         if (rowUpdateList != null) {
-            storageSource.updateRowsAndNotify(tableName, rowUpdateList);
+            storageSource.updateRows(tableName, rowUpdateList);
             rowUpdateList = null;
         }
         
         if (rowDeleteSet != null) {
-            storageSource.deleteRowsAndNotify(tableName, rowDeleteSet);
+            storageSource.deleteRows(tableName, rowDeleteSet);
             rowDeleteSet = null;
         }
     }
diff --git a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java
index c3a691a4e..37e02f71d 100644
--- a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java
+++ b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java
@@ -532,6 +532,7 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     
     @Override
     public void createTable(String tableName, Set<String> indexedColumns) {
+        super.createTable(tableName, indexedColumns);
         if (indexedColumns == null) return;
         for (String columnName : indexedColumns) {
             setColumnIndexMode(tableName, columnName,
@@ -544,6 +545,7 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
             throw new NullPointerException();
         tablePrimaryKeyMap.put(tableName, primaryKeyName);
     }
+    
     protected String getTablePrimaryKeyName(String tableName) {
         String primaryKeyName = tablePrimaryKeyMap.get(tableName);
         if (primaryKeyName == null)
@@ -708,19 +710,13 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     }
 
     @Override
-    public IResultSet executeQuery(IQuery query) {
+    public IResultSet executeQueryImpl(IQuery query) {
         NoSqlQuery noSqlQuery = (NoSqlQuery) query;
         return executeParameterizedQuery(noSqlQuery.getTableName(),
                 noSqlQuery.getColumnNameList(), noSqlQuery.getPredicate(),
                 noSqlQuery.getRowOrdering(), noSqlQuery.getParameterMap());
     }
 
-    @Override
-    public IResultSet executeQuery(String tableName, String[] columnNameList,
-            IPredicate predicate, RowOrdering rowOrdering) {
-        return executeParameterizedQuery(tableName, columnNameList, predicate, rowOrdering, null);
-    }
-
     protected void sendNotification(String tableName, StorageSourceNotification.Action action,
             List<Map<String,Object>> rows) {
         Set<Object> rowKeys = new HashSet<Object>();
@@ -747,7 +743,7 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     }
 
     @Override
-    public void insertRow(String tableName, Map<String, Object> values) {
+    public void insertRowImpl(String tableName, Map<String, Object> values) {
         ArrayList<Map<String,Object>> rowList = new ArrayList<Map<String,Object>>();
         rowList.add(values);
         insertRowsAndNotify(tableName, rowList);
@@ -764,7 +760,7 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     }
 
     @Override
-    public void updateRows(String tableName, IPredicate predicate, Map<String,Object> values) {
+    public void updateMatchingRowsImpl(String tableName, IPredicate predicate, Map<String,Object> values) {
         String primaryKeyName = getTablePrimaryKeyName(tableName);
         String[] columnNameList = {primaryKeyName};
         IResultSet resultSet = executeQuery(tableName, columnNameList, predicate, null);
@@ -777,7 +773,7 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     }
     
     @Override
-    public void updateRow(String tableName, Object rowKey, Map<String,Object> values) {
+    public void updateRowImpl(String tableName, Object rowKey, Map<String,Object> values) {
         Map<String,Object> valuesWithKey = new HashMap<String,Object>(values);
         String primaryKeyName = getTablePrimaryKeyName(tableName);
         valuesWithKey.put(primaryKeyName, rowKey);
@@ -787,7 +783,7 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     }
 
    @Override
-    public void updateRow(String tableName, Map<String,Object> values) {
+    public void updateRowImpl(String tableName, Map<String,Object> values) {
         List<Map<String,Object>> rowKeys = new ArrayList<Map<String,Object>>();
         rowKeys.add(values);
         updateRowsAndNotify(tableName, rowKeys);
@@ -799,30 +795,14 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
    }
 
     @Override
-    public void deleteRow(String tableName, Object key) {
+    public void deleteRowImpl(String tableName, Object key) {
         HashSet<Object> keys = new HashSet<Object>();
         keys.add(key);
         deleteRowsAndNotify(tableName, keys);
     }
 
     @Override
-    public void deleteRows(String tableName, IPredicate predicate) {
-        IResultSet resultSet = null;
-        try {
-            resultSet = executeQuery(tableName, null, predicate, null);
-            while (resultSet.next()) {
-                resultSet.deleteRow();
-            }
-            resultSet.save();
-        }
-        finally {
-            if (resultSet != null)
-                resultSet.close();
-        }
-    }
-    
-    @Override
-    public IResultSet getRow(String tableName, Object rowKey) {
+    public IResultSet getRowImpl(String tableName, Object rowKey) {
         List<Map<String,Object>> rowList = new ArrayList<Map<String,Object>>();
         Map<String,Object> row = getRow(tableName, null, rowKey);
         if (row != null)
@@ -847,9 +827,4 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource {
     protected abstract void insertRows(String tableName, List<Map<String,Object>> insertRowList);
     
     protected abstract void updateRows(String tableName, Set<Object> rowKeys, Map<String,Object> updateColumnMap);
-    
-    protected abstract void updateRows(String tableName, List<Map<String,Object>> updateRowList);
-    
-    protected abstract void deleteRows(String tableName, Set<Object> rowKeyList);
-
 }
diff --git a/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java b/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java
index 45584e227..78957a3fd 100644
--- a/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java
+++ b/src/test/java/net/floodlightcontroller/storage/tests/StorageTest.java
@@ -335,19 +335,19 @@ public abstract class StorageTest extends FloodlightTestCase {
     }
     
     @Test
-    public void testDeleteRows() {
+    public void testDeleteMatchingRows() {
         Object[][] expectedResults = {
                 {"111-11-1111", "John", "Smith", 40, true},
                 {"777-77-7777", "Bjorn", "Borg", 55, true},
                 {"888-88-8888", "John", "McEnroe", 53, false}
         };
-        storageSource.deleteRows(PERSON_TABLE_NAME, new OperatorPredicate(PERSON_AGE, OperatorPredicate.Operator.LT, 40));
+        storageSource.deleteMatchingRows(PERSON_TABLE_NAME, new OperatorPredicate(PERSON_AGE, OperatorPredicate.Operator.LT, 40));
         
         // Now query again to verify that the rows were deleted
         IResultSet resultSet = storageSource.executeQuery(PERSON_TABLE_NAME, PERSON_COLUMN_LIST, null, new RowOrdering(PERSON_SSN));
         checkExpectedResults(resultSet, PERSON_COLUMN_LIST, expectedResults);
         
-        storageSource.deleteRows(PERSON_TABLE_NAME, null);
+        storageSource.deleteMatchingRows(PERSON_TABLE_NAME, null);
 
         // Now query again to verify that all rows were deleted
         resultSet = storageSource.executeQuery(PERSON_TABLE_NAME, PERSON_COLUMN_LIST, null, new RowOrdering(PERSON_SSN));
@@ -674,13 +674,13 @@ public abstract class StorageTest extends FloodlightTestCase {
     }
     
     @Test
-    public void testAsyncUpdateRows() {
+    public void testAsyncUpdateMatchingRows() {
         Map<String,Object> updateValues = new HashMap<String,Object>();
         updateValues.put(PERSON_FIRST_NAME, "Tennis");
         updateValues.put(PERSON_AGE, 60);
 
         IPredicate predicate = new OperatorPredicate(PERSON_SSN, OperatorPredicate.Operator.EQ, "777-77-7777");
-        Future<?> future = storageSource.updateRowsAsync(PERSON_TABLE_NAME, predicate, updateValues);
+        Future<?> future = storageSource.updateMatchingRowsAsync(PERSON_TABLE_NAME, predicate, updateValues);
         waitForFuture(future);
         try {
             IResultSet resultSet = storageSource.getRow(PERSON_TABLE_NAME, "777-77-7777");
@@ -707,8 +707,8 @@ public abstract class StorageTest extends FloodlightTestCase {
     }
     
     @Test
-    public void testAsyncDeleteRows() {
-        Future<?> future = storageSource.deleteRowsAsync(PERSON_TABLE_NAME, null);
+    public void testAsyncDeleteMatchingRows() {
+        Future<?> future = storageSource.deleteMatchingRowsAsync(PERSON_TABLE_NAME, null);
         waitForFuture(future);
         try {
             IResultSet resultSet = storageSource.executeQuery(PERSON_TABLE_NAME, null, null, new RowOrdering(PERSON_SSN));
-- 
GitLab