Repository: phoenix
Updated Branches:
  refs/heads/calcite 518356479 -> 74409be82


http://git-wip-us.apache.org/repos/asf/phoenix/blob/59b336ec/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
index 1805d94..1611466 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableImpl.java
@@ -135,6 +135,7 @@ public class PTableImpl implements PTable {
     private boolean rowKeyOrderOptimizable; // TODO: remove when required that 
tables have been upgrade for PHOENIX-2067
     private boolean hasColumnsRequiringUpgrade; // TODO: remove when required 
that tables have been upgrade for PHOENIX-2067
     private int rowTimestampColPos;
+    private long updateCacheFrequency;
 
     public PTableImpl() {
         this.indexes = Collections.emptyList();
@@ -205,7 +206,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), 
table.getBucketNum(), getColumnsToClone(table), parentSchemaName, 
table.getParentTableName(),
                 indexes, table.isImmutableRows(), table.getPhysicalNames(), 
table.getDefaultFamilyName(), viewStatement,
                 table.isWALDisabled(), table.isMultiTenant(), 
table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), 
table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), 
table.rowKeyOrderOptimizable(), table.isTransactional());
+                table.getTableStats(), table.getBaseColumnCount(), 
table.rowKeyOrderOptimizable(), table.isTransactional(), 
table.getUpdateCacheFrequency());
     }
 
     public static PTableImpl makePTable(PTable table, List<PColumn> columns) 
throws SQLException {
@@ -214,7 +215,7 @@ public class PTableImpl implements PTable {
                 table.getSequenceNumber(), table.getPKName(), 
table.getBucketNum(), columns, table.getParentSchemaName(), 
table.getParentTableName(),
                 table.getIndexes(), table.isImmutableRows(), 
table.getPhysicalNames(), table.getDefaultFamilyName(), 
table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), 
table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), 
table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), 
table.rowKeyOrderOptimizable(), table.isTransactional());
+                table.getTableStats(), table.getBaseColumnCount(), 
table.rowKeyOrderOptimizable(), table.isTransactional(), 
table.getUpdateCacheFrequency());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long 
sequenceNumber, List<PColumn> columns) throws SQLException {
@@ -223,7 +224,7 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), 
columns, table.getParentSchemaName(), table.getParentTableName(), 
table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(), table.isWALDisabled(),
                 table.isMultiTenant(), table.getStoreNulls(), 
table.getViewType(), table.getViewIndexId(), table.getIndexType(), 
table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
table.isTransactional());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
table.isTransactional(), table.getUpdateCacheFrequency());
     }
 
     public static PTableImpl makePTable(PTable table, long timeStamp, long 
sequenceNumber, List<PColumn> columns, boolean isImmutableRows) throws 
SQLException {
@@ -232,16 +233,17 @@ public class PTableImpl implements PTable {
                 sequenceNumber, table.getPKName(), table.getBucketNum(), 
columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), 
table.getStoreNulls(), table.getViewType(), table.getViewIndexId(),
-                table.getIndexType(), table.getTableStats(), 
table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
table.isTransactional());
+                table.getIndexType(), table.getTableStats(), 
table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
table.isTransactional(), table.getUpdateCacheFrequency());
     }
     
-    public static PTableImpl makePTable(PTable table, long timeStamp, long 
sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean 
isWalDisabled, boolean isMultitenant, boolean storeNulls, boolean 
isTransactional) throws SQLException {
+    public static PTableImpl makePTable(PTable table, long timeStamp, long 
sequenceNumber, List<PColumn> columns, boolean isImmutableRows, boolean 
isWalDisabled,
+            boolean isMultitenant, boolean storeNulls, boolean 
isTransactional, long updateCacheFrequency) throws SQLException {
         return new PTableImpl(
                 table.getTenantId(), table.getSchemaName(), 
table.getTableName(), table.getType(), table.getIndexState(), timeStamp,
                 sequenceNumber, table.getPKName(), table.getBucketNum(), 
columns, table.getParentSchemaName(), table.getParentTableName(),
                 table.getIndexes(), isImmutableRows, table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(),
                 isWalDisabled, isMultitenant, storeNulls, table.getViewType(), 
table.getViewIndexId(), table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
isTransactional);
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
isTransactional, updateCacheFrequency);
     }
     
     public static PTableImpl makePTable(PTable table, PIndexState state) 
throws SQLException {
@@ -251,7 +253,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), 
table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), 
table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), 
table.getIndexType(),
-                table.getTableStats(), table.getBaseColumnCount(), 
table.rowKeyOrderOptimizable(), table.isTransactional());
+                table.getTableStats(), table.getBaseColumnCount(), 
table.rowKeyOrderOptimizable(), table.isTransactional(), 
table.getUpdateCacheFrequency());
     }
 
     public static PTableImpl makePTable(PTable table, boolean 
rowKeyOrderOptimizable) throws SQLException {
@@ -261,7 +263,7 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), 
table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), 
table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), 
table.getIndexType(), table.getTableStats(),
-                table.getBaseColumnCount(), rowKeyOrderOptimizable, 
table.isTransactional());
+                table.getBaseColumnCount(), rowKeyOrderOptimizable, 
table.isTransactional(), table.getUpdateCacheFrequency());
     }
 
     public static PTableImpl makePTable(PTable table, PTableStats stats) 
throws SQLException {
@@ -271,28 +273,33 @@ public class PTableImpl implements PTable {
                 table.getParentSchemaName(), table.getParentTableName(), 
table.getIndexes(),
                 table.isImmutableRows(), table.getPhysicalNames(), 
table.getDefaultFamilyName(), table.getViewStatement(),
                 table.isWALDisabled(), table.isMultiTenant(), 
table.getStoreNulls(), table.getViewType(), table.getViewIndexId(), 
table.getIndexType(), stats,
-                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
table.isTransactional());
+                table.getBaseColumnCount(), table.rowKeyOrderOptimizable(), 
table.isTransactional(), table.getUpdateCacheFrequency());
     }
 
-    public static PTableImpl makePTable(PName tenantId, PName schemaName, 
PName tableName, PTableType type, PIndexState state, long timeStamp, long 
sequenceNumber,
-            PName pkName, Integer bucketNum, List<PColumn> columns, PName 
dataSchemaName, PName dataTableName, List<PTable> indexes,
-            boolean isImmutableRows, List<PName> physicalNames, PName 
defaultFamilyName, String viewExpression, boolean disableWAL, boolean 
multiTenant,
-            boolean storeNulls, ViewType viewType, Short viewIndexId, 
IndexType indexType, boolean rowKeyOrderOptimizable, boolean isTransactional) 
throws SQLException {
+    public static PTableImpl makePTable(PName tenantId, PName schemaName, 
PName tableName, PTableType type,
+            PIndexState state, long timeStamp, long sequenceNumber, PName 
pkName, Integer bucketNum,
+            List<PColumn> columns, PName dataSchemaName, PName dataTableName, 
List<PTable> indexes,
+            boolean isImmutableRows, List<PName> physicalNames, PName 
defaultFamilyName, String viewExpression,
+            boolean disableWAL, boolean multiTenant, boolean storeNulls, 
ViewType viewType, Short viewIndexId,
+            IndexType indexType, boolean rowKeyOrderOptimizable, boolean 
isTransactional, long updateCacheFrequency) throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, 
timeStamp, sequenceNumber, pkName, bucketNum, columns, dataSchemaName,
                 dataTableName, indexes, isImmutableRows, physicalNames, 
defaultFamilyName,
                 viewExpression, disableWAL, multiTenant, storeNulls, viewType, 
viewIndexId,
-                indexType, PTableStats.EMPTY_STATS, 
QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, 
isTransactional);
+                indexType, PTableStats.EMPTY_STATS, 
QueryConstants.BASE_TABLE_BASE_COLUMN_COUNT, rowKeyOrderOptimizable, 
isTransactional, updateCacheFrequency);
     }
 
     public static PTableImpl makePTable(PName tenantId, PName schemaName, 
PName tableName, PTableType type,
             PIndexState state, long timeStamp, long sequenceNumber, PName 
pkName, Integer bucketNum,
             List<PColumn> columns, PName dataSchemaName, PName dataTableName, 
List<PTable> indexes,
             boolean isImmutableRows, List<PName> physicalNames, PName 
defaultFamilyName, String viewExpression,
-            boolean disableWAL, boolean multiTenant, boolean storeNulls, 
ViewType viewType, Short viewIndexId, IndexType indexType, @NotNull PTableStats 
stats, int baseColumnCount, boolean rowKeyOrderOptimizable, boolean 
isTransactional)
+            boolean disableWAL, boolean multiTenant, boolean storeNulls, 
ViewType viewType, Short viewIndexId,
+            IndexType indexType, boolean rowKeyOrderOptimizable, boolean 
isTransactional, long updateCacheFrequency,
+            @NotNull PTableStats stats, int baseColumnCount)
             throws SQLException {
         return new PTableImpl(tenantId, schemaName, tableName, type, state, 
timeStamp, sequenceNumber, pkName,
                 bucketNum, columns, dataSchemaName, dataTableName, indexes, 
isImmutableRows, physicalNames,
-                defaultFamilyName, viewExpression, disableWAL, multiTenant, 
storeNulls, viewType, viewIndexId, indexType, stats, baseColumnCount, 
rowKeyOrderOptimizable, isTransactional);
+                defaultFamilyName, viewExpression, disableWAL, multiTenant, 
storeNulls, viewType, viewIndexId,
+                indexType, stats, baseColumnCount, rowKeyOrderOptimizable, 
isTransactional, updateCacheFrequency);
     }
 
     private PTableImpl(PName tenantId, PName schemaName, PName tableName, 
PTableType type, PIndexState state,
@@ -300,13 +307,19 @@ public class PTableImpl implements PTable {
             PName parentSchemaName, PName parentTableName, List<PTable> 
indexes, boolean isImmutableRows,
             List<PName> physicalNames, PName defaultFamilyName, String 
viewExpression, boolean disableWAL, boolean multiTenant,
             boolean storeNulls, ViewType viewType, Short viewIndexId, 
IndexType indexType,
-            PTableStats stats, int baseColumnCount, boolean 
rowKeyOrderOptimizable, boolean isTransactional) throws SQLException {
+            PTableStats stats, int baseColumnCount, boolean 
rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency) 
throws SQLException {
         init(tenantId, schemaName, tableName, type, state, timeStamp, 
sequenceNumber, pkName, bucketNum, columns,
                 stats, schemaName, parentTableName, indexes, isImmutableRows, 
physicalNames, defaultFamilyName,
-                viewExpression, disableWAL, multiTenant, storeNulls, viewType, 
viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable, 
isTransactional);
+                viewExpression, disableWAL, multiTenant, storeNulls, viewType, 
viewIndexId, indexType, baseColumnCount, rowKeyOrderOptimizable,
+                isTransactional, updateCacheFrequency);
     }
 
     @Override
+    public long getUpdateCacheFrequency() {
+        return updateCacheFrequency;
+    }
+    
+    @Override
     public boolean isMultiTenant() {
         return multiTenant;
     }
@@ -331,7 +344,7 @@ public class PTableImpl implements PTable {
             PName pkName, Integer bucketNum, List<PColumn> columns, 
PTableStats stats, PName parentSchemaName, PName parentTableName,
             List<PTable> indexes, boolean isImmutableRows, List<PName> 
physicalNames, PName defaultFamilyName, String viewExpression, boolean 
disableWAL,
             boolean multiTenant, boolean storeNulls, ViewType viewType, Short 
viewIndexId,
-            IndexType indexType , int baseColumnCount, boolean 
rowKeyOrderOptimizable, boolean isTransactional) throws SQLException {
+            IndexType indexType , int baseColumnCount, boolean 
rowKeyOrderOptimizable, boolean isTransactional, long updateCacheFrequency) 
throws SQLException {
         Preconditions.checkNotNull(schemaName);
         Preconditions.checkArgument(tenantId==null || 
tenantId.getBytes().length > 0); // tenantId should be null or not empty
         int estimatedSize = SizedUtil.OBJECT_SIZE * 2 + 23 * 
SizedUtil.POINTER_SIZE + 4 * SizedUtil.INT_SIZE + 2 * SizedUtil.LONG_SIZE + 2 * 
SizedUtil.INT_OBJECT_SIZE +
@@ -363,6 +376,7 @@ public class PTableImpl implements PTable {
         this.isTransactional = isTransactional;
         this.tableStats = stats;
         this.rowKeyOrderOptimizable = rowKeyOrderOptimizable;
+        this.updateCacheFrequency = updateCacheFrequency;
         List<PColumn> pkColumns;
         PColumn[] allColumns;
         
@@ -1060,12 +1074,18 @@ public class PTableImpl implements PTable {
       if (table.hasRowKeyOrderOptimizable()) {
           rowKeyOrderOptimizable = table.getRowKeyOrderOptimizable();
       }
+      long updateCacheFrequency = 0;
+      if (table.hasUpdateCacheFrequency()) {
+          updateCacheFrequency = table.getUpdateCacheFrequency();
+      }
+      
       try {
         PTableImpl result = new PTableImpl();
         result.init(tenantId, schemaName, tableName, tableType, indexState, 
timeStamp, sequenceNumber, pkName,
-          (bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, 
schemaName,dataTableName, indexes,
-              isImmutableRows, physicalNames, defaultFamilyName, 
viewStatement, disableWAL,
-                multiTenant, storeNulls, viewType, viewIndexId, indexType, 
baseColumnCount, rowKeyOrderOptimizable, isTransactional);
+            (bucketNum == NO_SALTING) ? null : bucketNum, columns, stats, 
schemaName,dataTableName, indexes,
+            isImmutableRows, physicalNames, defaultFamilyName, viewStatement, 
disableWAL,
+            multiTenant, storeNulls, viewType, viewIndexId, indexType, 
baseColumnCount, rowKeyOrderOptimizable,
+            isTransactional, updateCacheFrequency);
         return result;
       } catch (SQLException e) {
         throw new RuntimeException(e); // Impossible
@@ -1157,6 +1177,7 @@ public class PTableImpl implements PTable {
       }
       builder.setBaseColumnCount(table.getBaseColumnCount());
       builder.setRowKeyOrderOptimizable(table.rowKeyOrderOptimizable());
+      builder.setUpdateCacheFrequency(table.getUpdateCacheFrequency());
 
       return builder.build();
     }

http://git-wip-us.apache.org/repos/asf/phoenix/blob/59b336ec/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableRef.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableRef.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableRef.java
index 83d0b42..c4bc510 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableRef.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/PTableRef.java
@@ -20,15 +20,16 @@ package org.apache.phoenix.schema;
 public class PTableRef {
     private final PTable table;
     private final int estSize;
+    private final long createTime;
+    private final long resolvedTimeStamp;
        private volatile long lastAccessTime;
-       // timestamp (scn or txn timestamp at which rpc to fetch the table was 
made)
-    private long resolvedTimeStamp;
     
     public PTableRef(PTable table, long lastAccessTime, int estSize, long 
resolvedTime) {
         this.table = table;
         this.lastAccessTime = lastAccessTime;
         this.estSize = estSize;
         this.resolvedTimeStamp = resolvedTime;
+        this.createTime = lastAccessTime;
     }
 
     public PTableRef(PTable table, long lastAccessTime, long resolvedTime) {
@@ -39,6 +40,14 @@ public class PTableRef {
         this (tableRef.table, tableRef.lastAccessTime, tableRef.estSize, 
tableRef.resolvedTimeStamp);
     }
     
+    /**
+     * Tracks how long this entry has been in the cache
+     * @return time in milliseconds for how long this entry has been in the 
cache.
+     */
+    public long getCreateTime() {
+        return createTime;
+    }
+    
     public PTable getTable() {
                return table;
        }
@@ -58,8 +67,4 @@ public class PTableRef {
        public void setLastAccessTime(long lastAccessTime) {
                this.lastAccessTime = lastAccessTime;
        }
-       
-       public void setResolvedTimeStamp(long resolvedTimeStamp) {
-               this.resolvedTimeStamp = resolvedTimeStamp;
-       }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/phoenix/blob/59b336ec/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java 
b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
index 091b929..5967d8b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/schema/TableProperty.java
@@ -26,6 +26,7 @@ import static 
org.apache.phoenix.exception.SQLExceptionCode.VIEW_WITH_PROPERTIES
 import static 
org.apache.phoenix.jdbc.PhoenixDatabaseMetaData.DEFAULT_COLUMN_FAMILY_NAME;
 
 import java.sql.SQLException;
+import java.util.Map;
 
 import org.apache.hadoop.hbase.HColumnDescriptor;
 import org.apache.phoenix.exception.SQLExceptionCode;
@@ -49,6 +50,23 @@ public enum TableProperty {
     STORE_NULLS(PhoenixDatabaseMetaData.STORE_NULLS, 
COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, true, false),
     
     TRANSACTIONAL(PhoenixDatabaseMetaData.TRANSACTIONAL, 
COLUMN_FAMILY_NOT_ALLOWED_TABLE_PROPERTY, true, false),
+
+    UPDATE_CACHE_FREQUENCY(PhoenixDatabaseMetaData.UPDATE_CACHE_FREQUENCY, 
true, true) {
+           @Override
+        public Object getValue(Object value) {
+               if (value instanceof String) {
+                   String strValue = (String) value;
+                   if ("ALWAYS".equalsIgnoreCase(strValue)) {
+                       return 0L;
+                   } else if ("NEVER".equalsIgnoreCase(strValue)) {
+                       return Long.MAX_VALUE;
+                   }
+               } else {
+                   return value == null ? null : ((Number) value).longValue();
+               }
+               return value;
+           }       
+       },
     ;
 
 
@@ -87,6 +105,14 @@ public enum TableProperty {
                return true;
        }
 
+       public Object getValue(Object value) {
+           return value;
+       }
+       
+    public Object getValue(Map<String, Object> props) {
+        return getValue(props.get(this.toString()));
+    }
+    
        // isQualified is true if column family name is specified in property 
name
        public void validate(boolean isMutating, boolean isQualified, 
PTableType tableType) throws SQLException {
                checkForColumnFamily(isQualified);

http://git-wip-us.apache.org/repos/asf/phoenix/blob/59b336ec/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
index 9d5e17c..72f3e01 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/execute/CorrelatePlanTest.java
@@ -36,12 +36,12 @@ import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
 import org.apache.phoenix.compile.ColumnResolver;
 import org.apache.phoenix.compile.FromCompiler;
 import org.apache.phoenix.compile.JoinCompiler;
+import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
 import org.apache.phoenix.compile.QueryPlan;
 import org.apache.phoenix.compile.RowProjector;
 import org.apache.phoenix.compile.SequenceManager;
 import org.apache.phoenix.compile.StatementContext;
 import org.apache.phoenix.compile.TupleProjectionCompiler;
-import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
 import org.apache.phoenix.coprocessor.MetaDataProtocol;
 import org.apache.phoenix.exception.SQLExceptionCode;
 import org.apache.phoenix.expression.ComparisonExpression;
@@ -233,7 +233,7 @@ public class CorrelatePlanTest {
                     PTableType.SUBQUERY, null, 
MetaDataProtocol.MIN_TABLE_TIMESTAMP, PTable.INITIAL_SEQ_NUM,
                     null, null, columns, null, null, 
Collections.<PTable>emptyList(),
                     false, Collections.<PName>emptyList(), null, null, false, 
false, false, null,
-                    null, null, true, false);
+                    null, null, true, false, 0);
             TableRef sourceTable = new TableRef(pTable);
             List<ColumnRef> sourceColumnRefs = Lists.<ColumnRef> 
newArrayList();
             for (PColumn column : sourceTable.getTable().getColumns()) {

http://git-wip-us.apache.org/repos/asf/phoenix/blob/59b336ec/phoenix-core/src/test/java/org/apache/phoenix/schema/PMetaDataImplTest.java
----------------------------------------------------------------------
diff --git 
a/phoenix-core/src/test/java/org/apache/phoenix/schema/PMetaDataImplTest.java 
b/phoenix-core/src/test/java/org/apache/phoenix/schema/PMetaDataImplTest.java
index 14b5f1f..9c92679 100644
--- 
a/phoenix-core/src/test/java/org/apache/phoenix/schema/PMetaDataImplTest.java
+++ 
b/phoenix-core/src/test/java/org/apache/phoenix/schema/PMetaDataImplTest.java
@@ -17,29 +17,37 @@
  */
 package org.apache.phoenix.schema;
 
-import com.google.common.collect.Sets;
-import org.apache.hadoop.hbase.HConstants;
-import org.apache.phoenix.util.TimeKeeper;
-import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 import java.sql.SQLException;
 import java.util.Set;
 
-import static org.junit.Assert.assertEquals;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.phoenix.util.TimeKeeper;
+import org.junit.Test;
+
+import com.google.common.collect.Sets;
 
 public class PMetaDataImplTest {
     
-    private static PMetaData addToTable(PMetaData metaData, String name, int 
size) throws SQLException {
+    private static PMetaData addToTable(PMetaData metaData, String name, int 
size, TestTimeKeeper timeKeeper) throws SQLException {
         PTable table = new PSizedTable(new PTableKey(null,name), size);
-        return metaData.addTable(table, System.currentTimeMillis());
+        PMetaData newMetaData = metaData.addTable(table, 
System.currentTimeMillis());
+        timeKeeper.incrementTime();
+        return newMetaData;
     }
     
-    private static PMetaData removeFromTable(PMetaData metaData, String name) 
throws SQLException {
-        return metaData.removeTable(null, name, null, 
HConstants.LATEST_TIMESTAMP);
+    private static PMetaData removeFromTable(PMetaData metaData, String name, 
TestTimeKeeper timeKeeper) throws SQLException {
+        PMetaData newMetaData =  metaData.removeTable(null, name, null, 
HConstants.LATEST_TIMESTAMP);
+        timeKeeper.incrementTime();
+        return newMetaData;
     }
     
-    private static PTable getFromTable(PMetaData metaData, String name) throws 
TableNotFoundException {
-        return metaData.getTableRef(new PTableKey(null,name)).getTable();
+    private static PTable getFromTable(PMetaData metaData, String name, 
TestTimeKeeper timeKeeper) throws TableNotFoundException {
+        PTable table = metaData.getTableRef(new 
PTableKey(null,name)).getTable();
+        timeKeeper.incrementTime();
+        return table;
     }
     
     private static void assertNames(PMetaData metaData, String... names) {
@@ -56,50 +64,54 @@ public class PMetaDataImplTest {
         
         @Override
         public long getCurrentTime() {
-            return time++;
+            return time;
         }
         
+        public void incrementTime() {
+            time++;
+        }
     }
     
     @Test
     public void testEviction() throws Exception {
         long maxSize = 10;
-        PMetaData metaData = new PMetaDataImpl(5, maxSize, new 
TestTimeKeeper());
-        metaData = addToTable(metaData, "a", 5);
+        TestTimeKeeper timeKeeper = new TestTimeKeeper();
+        PMetaData metaData = new PMetaDataImpl(5, maxSize, timeKeeper);
+        metaData = addToTable(metaData, "a", 5, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "b", 4);
+        metaData = addToTable(metaData, "b", 4, timeKeeper);
         assertEquals(2, metaData.size());
-        metaData = addToTable(metaData, "c", 3);
+        metaData = addToTable(metaData, "c", 3, timeKeeper);
         assertEquals(2, metaData.size());
         assertNames(metaData, "b","c");
 
-        metaData = addToTable(metaData, "b", 8);
+        metaData = addToTable(metaData, "b", 8, timeKeeper);
         assertEquals(1, metaData.size());
         assertNames(metaData, "b");
 
-        metaData = addToTable(metaData, "d", 11);
+        metaData = addToTable(metaData, "d", 11, timeKeeper);
         assertEquals(1, metaData.size());
         assertNames(metaData, "d");
         
-        metaData = removeFromTable(metaData, "d");
+        metaData = removeFromTable(metaData, "d", timeKeeper);
         assertNames(metaData);
         
-        metaData = addToTable(metaData, "a", 4);
+        metaData = addToTable(metaData, "a", 4, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "b", 3);
+        metaData = addToTable(metaData, "b", 3, timeKeeper);
         assertEquals(2, metaData.size());
-        metaData = addToTable(metaData, "c", 2);
+        metaData = addToTable(metaData, "c", 2, timeKeeper);
         assertEquals(3, metaData.size());
         assertNames(metaData, "a", "b","c");
         
-        getFromTable(metaData, "a");
-        metaData = addToTable(metaData, "d", 3);
+        getFromTable(metaData, "a", timeKeeper);
+        metaData = addToTable(metaData, "d", 3, timeKeeper);
         assertEquals(3, metaData.size());
         assertNames(metaData, "c", "a","d");
         
         // Clone maintains insert order
         metaData = metaData.clone();
-        metaData = addToTable(metaData, "e", 6);
+        metaData = addToTable(metaData, "e", 6, timeKeeper);
         assertEquals(2, metaData.size());
         assertNames(metaData, "d","e");
     }
@@ -107,18 +119,19 @@ public class PMetaDataImplTest {
     @Test
     public void shouldNotEvictMoreEntriesThanNecessary() throws Exception {
         long maxSize = 5;
-        PMetaData metaData = new PMetaDataImpl(5, maxSize, new 
TestTimeKeeper());
-        metaData = addToTable(metaData, "a", 1);
+        TestTimeKeeper timeKeeper = new TestTimeKeeper();
+        PMetaData metaData = new PMetaDataImpl(5, maxSize, timeKeeper);
+        metaData = addToTable(metaData, "a", 1, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "b", 1);
+        metaData = addToTable(metaData, "b", 1, timeKeeper);
         assertEquals(2, metaData.size());
         assertNames(metaData, "a", "b");
-        metaData = addToTable(metaData, "c", 3);
+        metaData = addToTable(metaData, "c", 3, timeKeeper);
         assertEquals(3, metaData.size());
         assertNames(metaData, "a", "b", "c");
-        getFromTable(metaData, "a");
-        getFromTable(metaData, "b");
-        metaData = addToTable(metaData, "d", 3);
+        getFromTable(metaData, "a", timeKeeper);
+        getFromTable(metaData, "b", timeKeeper);
+        metaData = addToTable(metaData, "d", 3, timeKeeper);
         assertEquals(3, metaData.size());
         assertNames(metaData, "a", "b", "d");
     }
@@ -126,19 +139,20 @@ public class PMetaDataImplTest {
     @Test
     public void shouldAlwaysKeepAtLeastOneEntryEvenIfTooLarge() throws 
Exception {
         long maxSize = 5;
-        PMetaData metaData = new PMetaDataImpl(5, maxSize, new 
TestTimeKeeper());
-        metaData = addToTable(metaData, "a", 1);
+        TestTimeKeeper timeKeeper = new TestTimeKeeper();
+        PMetaData metaData = new PMetaDataImpl(5, maxSize, timeKeeper);
+        metaData = addToTable(metaData, "a", 1, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "b", 1);
+        metaData = addToTable(metaData, "b", 1, timeKeeper);
         assertEquals(2, metaData.size());
-        metaData = addToTable(metaData, "c", 5);
+        metaData = addToTable(metaData, "c", 5, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "d", 20);
+        metaData = addToTable(metaData, "d", 20, timeKeeper);
         assertEquals(1, metaData.size());
         assertNames(metaData, "d");
-        metaData = addToTable(metaData, "e", 1);
+        metaData = addToTable(metaData, "e", 1, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "f", 2);
+        metaData = addToTable(metaData, "f", 2, timeKeeper);
         assertEquals(2, metaData.size());
         assertNames(metaData, "e", "f");
     }
@@ -146,23 +160,42 @@ public class PMetaDataImplTest {
     @Test
     public void shouldAlwaysKeepOneEntryIfMaxSizeIsZero() throws Exception {
         long maxSize = 0;
-        PMetaData metaData = new PMetaDataImpl(0, maxSize, new 
TestTimeKeeper());
-        metaData = addToTable(metaData, "a", 1);
+        TestTimeKeeper timeKeeper = new TestTimeKeeper();
+        PMetaData metaData = new PMetaDataImpl(0, maxSize, timeKeeper);
+        metaData = addToTable(metaData, "a", 1, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "b", 1);
+        metaData = addToTable(metaData, "b", 1, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "c", 5);
+        metaData = addToTable(metaData, "c", 5, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "d", 20);
+        metaData = addToTable(metaData, "d", 20, timeKeeper);
         assertEquals(1, metaData.size());
         assertNames(metaData, "d");
-        metaData = addToTable(metaData, "e", 1);
+        metaData = addToTable(metaData, "e", 1, timeKeeper);
         assertEquals(1, metaData.size());
-        metaData = addToTable(metaData, "f", 2);
+        metaData = addToTable(metaData, "f", 2, timeKeeper);
         assertEquals(1, metaData.size());
         assertNames(metaData, "f");
     }
 
+    @Test
+    public void testAge() throws Exception {
+        long maxSize = 10;
+        TestTimeKeeper timeKeeper = new TestTimeKeeper();
+        PMetaData metaData = new PMetaDataImpl(5, maxSize, timeKeeper);
+        String tableName = "a";
+        metaData = addToTable(metaData, tableName, 1, timeKeeper);
+        PTableRef aTableRef = metaData.getTableRef(new 
PTableKey(null,tableName));
+        assertNotNull(aTableRef);
+        assertEquals(1, metaData.getAge(aTableRef));
+        tableName = "b";
+        metaData = addToTable(metaData, tableName, 1, timeKeeper);
+        PTableRef bTableRef = metaData.getTableRef(new 
PTableKey(null,tableName));
+        assertNotNull(bTableRef);
+        assertEquals(1, metaData.getAge(bTableRef));
+        assertEquals(2, metaData.getAge(aTableRef));
+    }
+    
     private static class PSizedTable extends PTableImpl {
         private final int size;
         private final PTableKey key;

http://git-wip-us.apache.org/repos/asf/phoenix/blob/59b336ec/phoenix-protocol/src/main/PTable.proto
----------------------------------------------------------------------
diff --git a/phoenix-protocol/src/main/PTable.proto 
b/phoenix-protocol/src/main/PTable.proto
index 3048a40..485dd11 100644
--- a/phoenix-protocol/src/main/PTable.proto
+++ b/phoenix-protocol/src/main/PTable.proto
@@ -87,4 +87,5 @@ message PTable {
   optional int32 baseColumnCount = 25;
   optional bool rowKeyOrderOptimizable = 26;
   optional bool transactional = 27;
+  optional int64 updateCacheFrequency = 28;
 }

Reply via email to