[ 
https://issues.apache.org/jira/browse/PHOENIX-7108?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17816704#comment-17816704
 ] 

ASF GitHub Bot commented on PHOENIX-7108:
-----------------------------------------

jpisaac commented on code in PR #1799:
URL: https://github.com/apache/phoenix/pull/1799#discussion_r1486627123


##########
phoenix-core/src/main/java/org/apache/phoenix/coprocessor/CompactionScanner.java:
##########
@@ -160,17 +241,312 @@ public void close() throws IOException {
         storeScanner.close();
     }
 
+    private interface TTLTracker {
+        void setTTL(Cell firstCell);
+        RowContext getRowContext();
+    }
+    private class NonPartitionedTableTTLTracker implements TTLTracker {
+
+        private long ttl;
+        private RowContext rowContext;
+
+        public NonPartitionedTableTTLTracker(PTable pTable, 
RegionCoprocessorEnvironment env, Store store) {
+            boolean isSystemTable = pTable.getType() == PTableType.SYSTEM;
+            if (isSystemTable) {
+                ColumnFamilyDescriptor cfd = store.getColumnFamilyDescriptor();
+                ttl = cfd.getTimeToLive();
+            } else {
+                ttl = pTable.getTTL() != TTL_NOT_DEFINED ? pTable.getTTL() : 
DEFAULT_TTL;
+            }
+            LOGGER.info(String.format("NonPartitionedTableTTLTracker params:- 
(physical-name=%s, ttl=%d, isSystemTable=%s)",
+                    pTable.getName().toString(), ttl*1000, isSystemTable));
+        }
+
+        @Override
+        public void setTTL(Cell firstCell) {
+            this.rowContext = new RowContext();
+            this.rowContext.setTTL(ttl);
+
+        }
+
+        @Override
+        public RowContext getRowContext() {
+            if (this.rowContext == null) {
+                this.rowContext = new RowContext();
+                this.rowContext.setTTL(ttl);
+            }
+            return rowContext;
+        }
+    }
+
+    private class PartitionedTableTTLTracker implements TTLTracker {
+        private final Logger LOGGER = LoggerFactory.getLogger(
+                PartitionedTableTTLTracker.class);
+        private PTable baseTable;
+        private TableTTLInfoCache ttlCache;
+        private PrefixIndex index;
+
+        // Default or Table-Level TTL
+        private long ttl;
+        private RowContext rowContext;
+
+        private boolean isIndexTable = false;
+        private boolean isMultiTenant = false;
+        private boolean isSalted = false;
+        private int startingPKPosition;
+        private RowKeyParser rowKeyParser;
+
+        public PartitionedTableTTLTracker(PTable table, 
RegionCoprocessorEnvironment env,
+                boolean isSalted, boolean isIndexTable) {
+
+            try {
+                this.baseTable = table;
+                this.ttlCache = new TableTTLInfoCache();
+                this.index  = new PrefixIndex();
+                this.rowKeyParser = new RowKeyParser(baseTable);
+                this.ttl = table.getTTL() != TTL_NOT_DEFINED ? table.getTTL() 
: DEFAULT_TTL;
+                this.isIndexTable = isIndexTable || localIndex ;
+                this.isSalted = isSalted;
+                this.isMultiTenant = table.isMultiTenant();
+
+                int startingPKPosition = 0;
+                if (this.isMultiTenant && this.isSalted && this.isIndexTable) {
+                    // case multi-tenant + salted + index-table =>
+                    // startingPKPosition = 1 skip the salt-byte and starting 
at the viewIndexId
+                    startingPKPosition = 1;
+                } else if (this.isMultiTenant && this.isSalted) {
+                    // case multi-tenant + salted =>
+                    // startingPKPosition = 2 skip salt byte + tenant-id to 
search the global space
+                    // if above search returned no results
+                    // then search using the following start position
+                    // startingPKPosition = 1 skip salt-byte to search the 
tenant space
+                    startingPKPosition = 2;
+                } else if (this.isMultiTenant && this.isIndexTable) {
+                    // case multi-tenant + index-table =>
+                    // startingPKPosition = 0, the first key will the 
viewIndexId
+                    startingPKPosition = 0;
+                } else if (this.isSalted && this.isIndexTable) {
+                    // case salted + index-table =>
+                    // startingPKPosition = 1 skip salt-byte search using the 
viewIndexId
+                    startingPKPosition = 1;
+                } else if (this.isSalted) {
+                    // case salted =>
+                    // startingPKPosition = 1 skip salt-byte
+                    startingPKPosition = 1;
+                } else if (this.isIndexTable) {
+                    // case index-table =>
+                    // startingPKPosition = 0 the first key will the 
viewIndexId
+                    startingPKPosition = 0;
+                } else if (this.isMultiTenant) {
+                    // case multi-tenant =>
+                    // startingPKPosition = 1 skip tenant-id to search the 
global space
+                    // if above search returned no results
+                    // then search using the following start position
+                    // startingPKPosition = 0 to search the tenant space
+                    startingPKPosition = 1;
+                } else {
+                    // case not multi-tenant + not salted + not index-table  =>
+                    // startingPKPosition = 0
+                    startingPKPosition = 0;
+                }
+
+                this.startingPKPosition = startingPKPosition;
+
+                LOGGER.info(String.format("PartitionedTableTTLTracker params:- 
" +
+                                "region-name = %s, table-name = %s,  " +
+                                "multi-tenant = %s, index-table = %s, salted = 
%s, " +
+                                "default-ttl = %d, startingPKPosition = %d",
+                        region.getRegionInfo().getEncodedName(),
+                        region.getRegionInfo().getTable().getNameAsString(),
+                        this.isMultiTenant,
+                        this.isIndexTable,
+                        this.isSalted,
+                        this.ttl,
+                        this.startingPKPosition));
+
+                List<TableTTLInfo> tableList;
+                tableList = ViewUtil.getRowKeyPrefixesForPartitionedTables(
+                        table.getName().getString(),
+                        env.getConfiguration(),
+                        this.isIndexTable);
+
+                tableList.forEach(m -> {
+                    if (m.getTTL() != TTL_NOT_DEFINED) {
+                        // add the ttlInfo to the cache.
+                        // each new/unique ttlInfo object added returns a 
unique tableId.
+                        int tableId = ttlCache.addTable(m);
+                        // map the row-prefix to the tableId using prefix 
index.
+                        index.put(m.getPrefix(), tableId);
+                        if (LOGGER.isDebugEnabled()) {
+                            LOGGER.debug(String.format("Updated index : " + 
m.toString()));
+                        }
+
+                    }
+                });
+            } catch (Exception e) {
+                LOGGER.error(String.format("Failed to read from catalog: " + 
e.getMessage()));
+            } finally {
+                LOGGER.info(String.format("PartitionedTableTTLTracker " +
+                                "index-entries = %d, cache-entries = %d for 
region = %s",
+                        index.getValidPrefixes(), 
ttlCache.getNumTablesInCache(),
+                        
CompactionScanner.this.store.getRegionInfo().getEncodedName()));
+            }
+
+        }
+        @Override
+        public void setTTL(Cell firstCell) {
+
+            boolean matched = false;
+            TableTTLInfo tableTTLInfo = null;
+            List<Integer> pkPositions = null;
+            long rowTTLInSecs = ttl;
+            long searchOffset = -1;
+            int pkPosition = startingPKPosition;
+            try {
+                if (ttlCache.getNumTablesInCache() == 0) {
+                    // case: no views in the hierarchy had TTL set
+                    // Use the default TTL
+                    this.rowContext = new RowContext();
+                    this.rowContext.setTTL(rowTTLInSecs);
+                    return;
+                }
+                // pkPositions holds the byte offsets for the PKs of the base 
table
+                // for the current row
+                pkPositions = isIndexTable ?
+                        (isSalted ?
+                                Arrays.asList(0, 1) :
+                                Arrays.asList(0)) :
+                        rowKeyParser.parsePKPositions(firstCell);
+                // The startingPKPosition was initialized(constructor) in the 
following manner
+                // case multi-tenant + salted + index-table  => 
startingPKPosition = 1
+                // case multi-tenant + salted => startingPKPosition = 2, 1
+                // case multi-tenant + index-table => startingPKPosition = 0
+                // case salted + index-table => startingPKPosition = 1
+                // case salted => startingPKPosition = 1
+                // case index-table => startingPKPosition = 0
+                // case multi-tenant => startingPKPosition = 1, 0
+                int offset = pkPositions.get(pkPosition);
+                byte[] rowKey = CellUtil.cloneRow(firstCell);
+                // Search using the starting offset (startingPKPosition offset)
+                Integer tableId = index.getTableIdWithPrefix(rowKey, offset);

Review Comment:
   This is an interesting case of overlap between the global space and tenant 
space,  Currently KP1Tenant#KP2 row will match the global keyprefix "KP1".  The 
fix will be to keep the two prefix indexes (global and tenant) separate.





> Provide support for pruning expired rows of views using Phoenix level 
> compactions
> ---------------------------------------------------------------------------------
>
>                 Key: PHOENIX-7108
>                 URL: https://issues.apache.org/jira/browse/PHOENIX-7108
>             Project: Phoenix
>          Issue Type: Sub-task
>            Reporter: Jacob Isaac
>            Assignee: Jacob Isaac
>            Priority: Major
>
> Modify Phoenix compaction framework introduced in PHOENIX-6888 to prune TTL 
> expired rows of views.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to