Skip to content

Commit 4f9e4f5

Browse files
committed
(improvement) metadata: single-pass column classification in _build_table_columns
Rewrite _build_table_columns to classify columns by kind in a single pass instead of iterating col_rows three times with list comprehensions. This also fixes a bug where the third pass filtered on 'clustering_key' instead of 'clustering', causing clustering columns to leak through and get re-processed as regular columns. Additionally, use in-place sort() instead of sorted() to avoid creating intermediate list copies, and append the already-built column_meta object to partition_key/clustering_key instead of re-looking it up from meta.columns by name. Combined benchmark results for the full optimization series (A-F): Row creation + access: 323 ns/row vs 485 ns/row (1.50x faster) _build_table_columns: 9.0 us/table vs 9.9 us/table (1.10x faster) Full pipeline (100 tables x 20 cols): 0.79 ms vs 1.57 ms (1.98x faster) Memory per row: 48 bytes vs 272 bytes (5.7x reduction) __slots__ per instance: 80 bytes (saves ~104 bytes __dict__ overhead)
1 parent 8ce7aa2 commit 4f9e4f5

1 file changed

Lines changed: 23 additions & 14 deletions

File tree

cassandra/metadata.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2677,31 +2677,40 @@ def _build_table_options(self, row):
26772677
return dict((o, row.get(o)) for o in self.recognized_table_options if o in row)
26782678

26792679
def _build_table_columns(self, meta, col_rows, compact_static=False, is_dense=False, virtual=False):
2680-
# partition key
2681-
partition_rows = [r for r in col_rows
2682-
if r.get('kind', None) == "partition_key"]
2680+
# Single-pass classification of column rows by kind
2681+
partition_rows = []
2682+
clustering_rows = []
2683+
other_rows = []
2684+
for r in col_rows:
2685+
kind = r.get('kind', None)
2686+
if kind == "partition_key":
2687+
partition_rows.append(r)
2688+
elif kind == "clustering":
2689+
if not compact_static:
2690+
clustering_rows.append(r)
2691+
# else: skip clustering rows entirely for compact_static tables
2692+
else:
2693+
other_rows.append(r)
2694+
2695+
# partition key — must be inserted first into meta.columns for CQL export ordering
26832696
if len(partition_rows) > 1:
2684-
partition_rows = sorted(partition_rows, key=lambda row: row.get('position'))
2697+
partition_rows.sort(key=lambda row: row.get('position'))
26852698
for r in partition_rows:
2686-
# we have to add meta here (and not in the later loop) because TableMetadata.columns
2687-
# assumes keys are inserted first, in order, when exporting CQL
26882699
column_meta = self._build_column_metadata(meta, r)
26892700
meta.columns[column_meta.name] = column_meta
2690-
meta.partition_key.append(meta.columns[r.get('column_name')])
2701+
meta.partition_key.append(column_meta)
26912702

26922703
# clustering key
2693-
if not compact_static:
2694-
clustering_rows = [r for r in col_rows
2695-
if r.get('kind', None) == "clustering"]
2704+
if clustering_rows:
26962705
if len(clustering_rows) > 1:
2697-
clustering_rows = sorted(clustering_rows, key=lambda row: row.get('position'))
2706+
clustering_rows.sort(key=lambda row: row.get('position'))
26982707
for r in clustering_rows:
26992708
column_meta = self._build_column_metadata(meta, r)
27002709
meta.columns[column_meta.name] = column_meta
2701-
meta.clustering_key.append(meta.columns[r.get('column_name')])
2710+
meta.clustering_key.append(column_meta)
27022711

2703-
for col_row in (r for r in col_rows
2704-
if r.get('kind', None) not in ('partition_key', 'clustering_key')):
2712+
# remaining columns (static, regular, etc.)
2713+
for col_row in other_rows:
27052714
column_meta = self._build_column_metadata(meta, col_row)
27062715
if is_dense and column_meta.cql_type == types.cql_empty_type:
27072716
continue

0 commit comments

Comments
 (0)