changed the MetadataCache to cache indexes which haven't been cached so far

git-svn-id: https://asterixdb.googlecode.com/svn/branches/asterix_lsm_stabilization@1061 eaa15691-b419-025a-1212-ee371bd00084
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataCache.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataCache.java
index 66d46f9..0382315 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataCache.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataCache.java
@@ -27,6 +27,7 @@
 import edu.uci.ics.asterix.metadata.entities.Datatype;
 import edu.uci.ics.asterix.metadata.entities.Dataverse;
 import edu.uci.ics.asterix.metadata.entities.Function;
+import edu.uci.ics.asterix.metadata.entities.Index;
 import edu.uci.ics.asterix.metadata.entities.NodeGroup;
 
 /**
@@ -40,6 +41,8 @@
     protected final Map<String, Dataverse> dataverses = new HashMap<String, Dataverse>();
     // Key is dataverse name. Key of value map is dataset name.
     protected final Map<String, Map<String, Dataset>> datasets = new HashMap<String, Map<String, Dataset>>();
+    // Key is dataverse name. Key of value map is dataset name. Key of value map of value map is index name.
+    protected final Map<String, Map<String, Map<String, Index>>> indexes = new HashMap<String, Map<String, Map<String, Index>>>();
     // Key is dataverse name. Key of value map is datatype name.
     protected final Map<String, Map<String, Datatype>> datatypes = new HashMap<String, Map<String, Datatype>>();
     // Key is dataverse name.
@@ -79,15 +82,18 @@
         synchronized (dataverses) {
             synchronized (nodeGroups) {
                 synchronized (datasets) {
-                    synchronized (datatypes) {
-                        synchronized (functions) {
-                            synchronized (adapters) {
-                                dataverses.clear();
-                                nodeGroups.clear();
-                                datasets.clear();
-                                datatypes.clear();
-                                functions.clear();
-                                adapters.clear();
+                    synchronized (indexes) {
+                        synchronized (datatypes) {
+                            synchronized (functions) {
+                                synchronized (adapters) {
+                                    dataverses.clear();
+                                    nodeGroups.clear();
+                                    datasets.clear();
+                                    indexes.clear();
+                                    datatypes.clear();
+                                    functions.clear();
+                                    adapters.clear();
+                                }
                             }
                         }
                     }
@@ -126,6 +132,25 @@
         }
     }
 
+    public Object addIndexIfNotExists(Index index) {
+        synchronized (indexes) {
+            Map<String, Map<String, Index>> datasetMap = indexes.get(index.getDataverseName());
+            if (datasetMap == null) {
+                datasetMap = new HashMap<String, Map<String, Index>>();
+                indexes.put(index.getDataverseName(), datasetMap);
+            }
+            Map<String, Index> indexMap = datasetMap.get(index.getDatasetName());
+            if (indexMap == null) {
+                indexMap = new HashMap<String, Index>();
+                datasetMap.put(index.getDatasetName(), indexMap);
+            }
+            if (!indexMap.containsKey(index.getIndexName())) {
+                return indexMap.put(index.getIndexName(), index);
+            }
+            return null;
+        }
+    }
+
     public Object addDatatypeIfNotExists(Datatype datatype) {
         synchronized (datatypes) {
             Map<String, Datatype> m = datatypes.get(datatype.getDataverseName());
@@ -152,21 +177,24 @@
     public Object dropDataverse(Dataverse dataverse) {
         synchronized (dataverses) {
             synchronized (datasets) {
-                synchronized (datatypes) {
-                    synchronized (functions) {
-                        datasets.remove(dataverse.getDataverseName());
-                        datatypes.remove(dataverse.getDataverseName());
-                        adapters.remove(dataverse.getDataverseName());
-                        List<FunctionSignature> markedFunctionsForRemoval = new ArrayList<FunctionSignature>();
-                        for (FunctionSignature signature : functions.keySet()) {
-                            if (signature.getNamespace().equals(dataverse.getDataverseName())) {
-                                markedFunctionsForRemoval.add(signature);
+                synchronized (indexes) {
+                    synchronized (datatypes) {
+                        synchronized (functions) {
+                            datasets.remove(dataverse.getDataverseName());
+                            indexes.remove(dataverse.getDataverseName());
+                            datatypes.remove(dataverse.getDataverseName());
+                            adapters.remove(dataverse.getDataverseName());
+                            List<FunctionSignature> markedFunctionsForRemoval = new ArrayList<FunctionSignature>();
+                            for (FunctionSignature signature : functions.keySet()) {
+                                if (signature.getNamespace().equals(dataverse.getDataverseName())) {
+                                    markedFunctionsForRemoval.add(signature);
+                                }
                             }
+                            for (FunctionSignature signature : markedFunctionsForRemoval) {
+                                functions.remove(signature);
+                            }
+                            return dataverses.remove(dataverse.getDataverseName());
                         }
-                        for (FunctionSignature signature : markedFunctionsForRemoval) {
-                            functions.remove(signature);
-                        }
-                        return dataverses.remove(dataverse.getDataverseName());
                     }
                 }
             }
@@ -175,11 +203,37 @@
 
     public Object dropDataset(Dataset dataset) {
         synchronized (datasets) {
-            Map<String, Dataset> m = datasets.get(dataset.getDataverseName());
-            if (m == null) {
+            synchronized (indexes) {
+
+                //remove the indexes of the dataset from indexes' cache
+                Map<String, Map<String, Index>> datasetMap = indexes.get(dataset.getDataverseName());
+                if (datasetMap != null) {
+                    datasetMap.remove(dataset.getDatasetName());
+                }
+
+                //remove the dataset from datasets' cache
+                Map<String, Dataset> m = datasets.get(dataset.getDataverseName());
+                if (m == null) {
+                    return null;
+                }
+                return m.remove(dataset.getDatasetName());
+            }
+        }
+    }
+    
+    public Object dropIndex(Index index) {
+        synchronized (indexes) {
+            Map<String, Map<String, Index>> datasetMap = indexes.get(index.getDataverseName());
+            if (datasetMap == null) {
                 return null;
             }
-            return m.remove(dataset.getDatasetName());
+            
+            Map<String, Index> indexMap = datasetMap.get(index.getDatasetName());
+            if (indexMap == null) {
+                return null;
+            }
+            
+            return indexMap.remove(index.getIndexName());
         }
     }
 
@@ -214,6 +268,20 @@
             return m.get(datasetName);
         }
     }
+    
+    public Index getIndex(String dataverseName, String datasetName, String indexName) {
+        synchronized (indexes) {
+            Map<String, Map<String, Index>> datasetMap = indexes.get(dataverseName);
+            if (datasetMap == null) {
+                return null;
+            }
+            Map<String, Index> indexMap = datasetMap.get(datasetName);
+            if (indexMap == null) {
+                return null;
+            }
+            return indexMap.get(indexName);
+        }
+    }
 
     public Datatype getDatatype(String dataverseName, String datatypeName) {
         synchronized (datatypes) {
@@ -311,7 +379,8 @@
             DatasourceAdapter adapterObject = adapters.get(adapter.getAdapterIdentifier().getNamespace()).get(
                     adapter.getAdapterIdentifier().getAdapterName());
             if (adapterObject != null) {
-                Map<String, DatasourceAdapter> adaptersInDataverse = adapters.get(adapter.getAdapterIdentifier().getNamespace());
+                Map<String, DatasourceAdapter> adaptersInDataverse = adapters.get(adapter.getAdapterIdentifier()
+                        .getNamespace());
                 if (adaptersInDataverse == null) {
                     adaptersInDataverse = new HashMap<String, DatasourceAdapter>();
                     adapters.put(adapter.getAdapterIdentifier().getNamespace(), adaptersInDataverse);
@@ -324,7 +393,8 @@
 
     public Object dropAdapter(DatasourceAdapter adapter) {
         synchronized (adapters) {
-            Map<String, DatasourceAdapter> adaptersInDataverse = adapters.get(adapter.getAdapterIdentifier().getNamespace());
+            Map<String, DatasourceAdapter> adaptersInDataverse = adapters.get(adapter.getAdapterIdentifier()
+                    .getNamespace());
             if (adaptersInDataverse != null) {
                 return adaptersInDataverse.remove(adapter.getAdapterIdentifier().getAdapterName());
             }
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataManager.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataManager.java
index 918e804..1fdde73 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataManager.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataManager.java
@@ -347,6 +347,7 @@
         } catch (RemoteException e) {
             throw new MetadataException(e);
         }
+        ctx.addIndex(index);
     }
 
     @Override
@@ -368,16 +369,52 @@
         } catch (RemoteException e) {
             throw new MetadataException(e);
         }
+        ctx.dropIndex(dataverseName, datasetName, indexName);
     }
 
     @Override
     public Index getIndex(MetadataTransactionContext ctx, String dataverseName, String datasetName, String indexName)
             throws MetadataException {
+        
+        // First look in the context to see if this transaction created the
+        // requested index itself (but the index is still uncommitted).
+        Index index = ctx.getIndex(dataverseName, datasetName, indexName);
+        if (index != null) {
+            // Don't add this index to the cache, since it is still
+            // uncommitted.
+            return index;
+        }
+        
+        if (ctx.indexIsDropped(dataverseName, datasetName, indexName)) {
+            // Index has been dropped by this transaction but could still be
+            // in the cache.
+            return null;
+        }
+
+        //TODO 
+        //check what this is for?
+        if (!MetadataConstants.METADATA_DATAVERSE_NAME.equals(dataverseName) && ctx.getDataverse(dataverseName) != null) {
+            // This transaction has dropped and subsequently created the same
+            // dataverse.
+            return null;
+        }
+
+        index = cache.getIndex(dataverseName, datasetName, indexName);
+        if (index != null) {
+            // Index is already in the cache, don't add it again.
+            return index;
+        }
         try {
-            return metadataNode.getIndex(ctx.getJobId(), dataverseName, datasetName, indexName);
+            index = metadataNode.getIndex(ctx.getJobId(), dataverseName, datasetName, indexName);
         } catch (RemoteException e) {
             throw new MetadataException(e);
         }
+        // We fetched the index from the MetadataNode. Add it to the cache
+        // when this transaction commits.
+        if (index != null) {
+            ctx.addIndex(index);
+        }
+        return index;
     }
 
     @Override
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataTransactionContext.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataTransactionContext.java
index 15bd229..8052f75 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataTransactionContext.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/MetadataTransactionContext.java
@@ -24,6 +24,7 @@
 import edu.uci.ics.asterix.metadata.entities.Datatype;
 import edu.uci.ics.asterix.metadata.entities.Dataverse;
 import edu.uci.ics.asterix.metadata.entities.Function;
+import edu.uci.ics.asterix.metadata.entities.Index;
 import edu.uci.ics.asterix.metadata.entities.NodeGroup;
 import edu.uci.ics.asterix.transaction.management.service.transaction.JobId;
 
@@ -56,16 +57,16 @@
     // The APIs in this class make sure that these two caches are kept in sync.
     protected MetadataCache droppedCache = new MetadataCache();
 
-	protected ArrayList<MetadataLogicalOperation> opLog = new ArrayList<MetadataLogicalOperation>();
-	private final JobId jobId;
+    protected ArrayList<MetadataLogicalOperation> opLog = new ArrayList<MetadataLogicalOperation>();
+    private final JobId jobId;
 
-	public MetadataTransactionContext(JobId jobId) {
-		this.jobId = jobId;
-	}
+    public MetadataTransactionContext(JobId jobId) {
+        this.jobId = jobId;
+    }
 
-	public JobId getJobId() {
-		return jobId;
-	}
+    public JobId getJobId() {
+        return jobId;
+    }
 
     public void addDataverse(Dataverse dataverse) {
         droppedCache.dropDataverse(dataverse);
@@ -77,6 +78,11 @@
         logAndApply(new MetadataLogicalOperation(dataset, true));
     }
 
+    public void addIndex(Index index) {
+        droppedCache.dropIndex(index);
+        logAndApply(new MetadataLogicalOperation(index, true));
+    }
+
     public void addDatatype(Datatype datatype) {
         droppedCache.dropDatatype(datatype);
         logAndApply(new MetadataLogicalOperation(datatype, true));
@@ -97,12 +103,18 @@
         logAndApply(new MetadataLogicalOperation(adapter, true));
     }
 
-	public void dropDataset(String dataverseName, String datasetName) {
-		Dataset dataset = new Dataset(dataverseName, datasetName, null, null,
-				null, -1);
-		droppedCache.addDatasetIfNotExists(dataset);
-		logAndApply(new MetadataLogicalOperation(dataset, false));
-	}
+    public void dropDataset(String dataverseName, String datasetName) {
+        Dataset dataset = new Dataset(dataverseName, datasetName, null, null, null, -1);
+        droppedCache.addDatasetIfNotExists(dataset);
+        logAndApply(new MetadataLogicalOperation(dataset, false));
+    }
+
+    public void dropIndex(String dataverseName, String datasetName, String indexName) {
+        Index index = new Index(dataverseName, datasetName, indexName, null, null, false);
+        droppedCache.addIndexIfNotExists(index);
+        logAndApply(new MetadataLogicalOperation(index, false));
+    }
+
     public void dropDataverse(String dataverseName) {
         Dataverse dataverse = new Dataverse(dataverseName, null);
         droppedCache.addDataverseIfNotExists(dataverse);
@@ -150,6 +162,16 @@
         }
         return droppedCache.getDataset(dataverseName, datasetName) != null;
     }
+    
+    public boolean indexIsDropped(String dataverseName, String datasetName, String indexName) {
+        if (droppedCache.getDataverse(dataverseName) != null) {
+            return true;
+        }
+        if (droppedCache.getDataset(dataverseName, datasetName) != null) {
+            return true;
+        }
+        return droppedCache.getIndex(dataverseName, datasetName, indexName) != null;
+    }
 
     public boolean datatypeIsDropped(String dataverseName, String datatypeName) {
         if (droppedCache.getDataverse(dataverseName) != null) {
diff --git a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entities/Index.java b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entities/Index.java
index 2aade27..39f4689 100644
--- a/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entities/Index.java
+++ b/asterix-metadata/src/main/java/edu/uci/ics/asterix/metadata/entities/Index.java
@@ -19,6 +19,8 @@
 import java.util.List;
 
 import edu.uci.ics.asterix.common.config.DatasetConfig.IndexType;
+import edu.uci.ics.asterix.metadata.MetadataCache;
+import edu.uci.ics.asterix.metadata.api.IMetadataEntity;
 import edu.uci.ics.asterix.om.types.ARecordType;
 import edu.uci.ics.asterix.om.types.ATypeTag;
 import edu.uci.ics.asterix.om.types.AUnionType;
@@ -29,7 +31,7 @@
 /**
  * Metadata describing an index.
  */
-public class Index implements Serializable {
+public class Index implements IMetadataEntity {
 
     private static final long serialVersionUID = 1L;
 
@@ -146,4 +148,14 @@
     	}
     	return true;
     }
+
+    @Override
+    public Object addToCache(MetadataCache cache) {
+        return cache.addIndexIfNotExists(this);
+    }
+
+    @Override
+    public Object dropFromCache(MetadataCache cache) {
+        return cache.dropIndex(this);
+    }
 }