tkhurana commented on code in PR #1799:
URL: https://github.com/apache/phoenix/pull/1799#discussion_r1484693860
##########
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);
+ if ((tableId == null) && (!isIndexTable) && (isMultiTenant ||
isSalted)) {
Review Comment:
@jpisaac What if my partition key is a prefix of tenantid ? I define a ttl
on global view and a ttl on a tenant view created on a different global view.
Basically there is one ttl on "KP1" and another on "KP1Tenant#KP2"
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]