maedhroz commented on code in PR #4175:
URL: https://github.com/apache/cassandra/pull/4175#discussion_r2164791690


##########
src/java/org/apache/cassandra/service/accord/txn/TxnReference.java:
##########
@@ -163,192 +140,485 @@ public Row getRow(TxnData data)
 
     public Row getRow(FilteredPartition partition)
     {
-        if (column != null && column.isStatic())
+        if (kind == Kind.COLUMN && asColumn().column.isStatic())
             return partition.staticRow();
         assert partition.rowCount() <= 1 : "Multi-row references are not 
allowed";
         if (partition.rowCount() == 0)
             return null;
         return partition.getAtIdx(0);
     }
 
-    public ColumnData getColumnData(Row row)
+    public static final UnversionedSerializer<RowReference> rowSerializer = 
new UnversionedSerializer<>()
     {
-        if (column.isComplex() && path == null)
-            return row.getComplexColumnData(column);
+        @Override
+        public void serialize(RowReference reference, DataOutputPlus out) 
throws IOException
+        {
+            out.writeUnsignedVInt32(reference.tuple);
+        }
 
-        if (path != null && column.type.isMultiCell())
+        @Override
+        public RowReference deserialize(DataInputPlus in) throws IOException
         {
-            if (column.type.isCollection())
-            {
-                CollectionType<?> collectionType = (CollectionType<?>) 
column.type;
+            int tuple = in.readUnsignedVInt32();
+            return row(tuple);
+        }
 
-                if (collectionType.kind == CollectionType.Kind.LIST)
-                    return 
row.getComplexColumnData(column).getCellByIndex(ByteBufferUtil.toInt(path.get(0)));
-            }
+        @Override
+        public long serializedSize(RowReference reference)
+        {
+            return VIntCoding.sizeOfUnsignedVInt(reference.tuple);
+        }
+    };
 
-            return row.getCell(column, path);
+    public static final ParameterisedUnversionedSerializer<ColumnReference, 
TableMetadatas> columnSerializer = new 
ParameterisedUnversionedSerializer<ColumnReference, TableMetadatas>()
+    {
+        @Override
+        public void serialize(ColumnReference reference, TableMetadatas 
tables, DataOutputPlus out) throws IOException
+        {
+            out.writeUnsignedVInt32(reference.tuple);
+            tables.serialize(reference.table, out);
+            columnMetadataSerializer.serialize(reference.column, 
reference.table, out);
+            out.writeBoolean(reference.path != null);
+            if (reference.path != null)
+                CollectionType.cellPathSerializer.serialize(reference.path, 
out);
         }
 
-        return row.getCell(column);
-    }
+        @Override
+        public ColumnReference deserialize(TableMetadatas tables, 
DataInputPlus in) throws IOException
+        {
+            int tuple = in.readUnsignedVInt32();
+            TableMetadata table = tables.deserialize(in);
+            ColumnMetadata column = 
columnMetadataSerializer.deserialize(table, in);
+            CellPath path = in.readBoolean() ? 
CollectionType.cellPathSerializer.deserialize(in) : null;
+            return TxnReference.column(tuple, table, column, path);
+        }
 
-    public ColumnData getColumnData(TxnData data)
-    {
-        Row row = getRow(data);
-        return row != null ? getColumnData(row) : null;
-    }
+        @Override
+        public long serializedSize(ColumnReference reference, TableMetadatas 
tables)
+        {
+            long size = 0;
+            size += VIntCoding.sizeOfUnsignedVInt(reference.tuple);
+            size += tables.serializedSize(reference.table);
+            size += columnMetadataSerializer.serializedSize(reference.column, 
reference.table);
+            size += TypeSizes.BOOL_SIZE;
+            if (reference.path != null)
+                size += 
CollectionType.cellPathSerializer.serializedSize(reference.path);
+            return size;
+        }
+    };
 
-    public ByteBuffer getFrozenCollectionElement(Cell<?> collection)
-    {
-        CollectionType<?> collectionType = (CollectionType<?>) column.type;
-        return 
collectionType.getSerializer().getSerializedValue(collection.buffer(), 
path.get(0), collectionType.nameComparator());
-    }
 
-    public ByteBuffer getFrozenFieldValue(Cell<?> udt)
+    static final ParameterisedUnversionedSerializer<TxnReference, 
TableMetadatas> serializer = new ParameterisedUnversionedSerializer<>()
     {
-        UserType userType = (UserType) column.type;
-        int field = ByteBufferUtil.getUnsignedShort(path.get(0), 0);
-        return userType.unpack(udt.buffer()).get(field);
-    }
+        @Override
+        public void serialize(TxnReference reference, TableMetadatas tables, 
DataOutputPlus out) throws IOException
+        {
+            out.writeUnsignedVInt32(TinyEnumSet.encode(reference.kind));
+            switch (reference.kind)
+            {
+                case ROW:
+                    rowSerializer.serialize(reference.asRow(), out);
+                    break;
+                case COLUMN:
+                    columnSerializer.serialize(reference.asColumn(), tables, 
out);
+                    break;
+                default:
+                    throw new UnhandledEnum(reference.kind);
+            }
+        }
+
+        @Override
+        public TxnReference deserialize(TableMetadatas tables, DataInputPlus 
in) throws IOException
+        {
+            TinyEnumSet<TxnReference.Kind> kind = new 
TinyEnumSet<>(in.readUnsignedVInt32());
+            if (kind.contains(Kind.ROW)) return rowSerializer.deserialize(in);
+            if (kind.contains(Kind.COLUMN)) return 
columnSerializer.deserialize(tables, in);
+            throw Invariants.illegalArgument("Unexpected kind: " + kind);
+        }
+
+        @Override
+        public long serializedSize(TxnReference reference, TableMetadatas 
tables)
+        {
+            long size = 
VIntCoding.sizeOfUnsignedVInt(TinyEnumSet.encode(reference.kind));
+            switch (reference.kind)
+            {
+                case ROW:
+                    size += rowSerializer.serializedSize(reference.asRow());
+                    break;
+                case COLUMN:
+                    size += 
columnSerializer.serializedSize(reference.asColumn(), tables);
+                    break;
+                default:
+                    throw new UnhandledEnum(reference.kind);
+            }
+            return size;
+        }
+    };
 
-    public AbstractType<?> getFieldSelectionType()
+    public enum Kind { ROW, COLUMN }
+
+    public static class RowReference extends TxnReference
     {
-        assert isFieldSelection() : "No field selection type exists";
-        UserType userType = (UserType) column.type;
-        int field = ByteBufferUtil.getUnsignedShort(path.get(0), 0);
-        return userType.fieldType(field);
+        public RowReference(int tuple)
+        {
+            super(Kind.ROW, tuple);
+        }
+
+        @Override
+        public void collect(TableMetadatas.Collector collector)
+        {
+            // no-op
+        }
+
+        @Override
+        public boolean equals(Object o)
+        {
+            if (o == null || getClass() != o.getClass()) return false;
+            RowReference that = (RowReference) o;
+            return tuple == that.tuple;
+        }
+
+        @Override
+        public int hashCode()
+        {
+            return Objects.hash(tuple);
+        }
+
+        @Override
+        public String toString()
+        {
+            return Integer.toString(tuple);
+        }
     }
 
-    public ByteBuffer toByteBuffer(TxnData data, AbstractType<?> receiver)
+    public static class ColumnReference extends TxnReference
     {
-        // TODO: confirm all references can be satisfied as part of the txn 
condition
-        AbstractType<?> type = column().type;
+        private final TableMetadata table;
+        private final ColumnMetadata column;
+        @Nullable
+        private final CellPath path;
+
+        public ColumnReference(int tuple, TableMetadata table, ColumnMetadata 
column, @Nullable CellPath path)
+        {
+            super(Kind.COLUMN, tuple);
+            this.table = table;
+            this.column = column;
+            this.path = path;
+        }
+
+        public ColumnMetadata column()
+        {
+            return column;
+        }
+
+        public TableMetadata table()
+        {
+            return table;
+        }
+
+        @Nullable
+        public CellPath path()
+        {
+            return path;
+        }
+
+        public boolean selectsPath()
+        {
+            return path != null;
+        }
+
+        public boolean isElementSelection()
+        {
+            return selectsPath() && column.type.isCollection();
+        }
+
+        public boolean isFieldSelection()
+        {
+            return selectsPath() && column.type.isUDT();
+        }
+
+        public ByteBuffer getPartitionKey(TxnData data)
+        {
+            FilteredPartition partition = getPartition(data);
+            if (partition == null) return null;
+            return partition.metadata().partitionKeyColumns().size() == 1
+                   ? partition.partitionKey().getKey()
+                   : ((CompositeType) 
partition.metadata().partitionKeyType).split(partition.partitionKey().getKey())[column.position()];
+        }
+
+        @Override
+        public void collect(TableMetadatas.Collector collector)
+        {
+            collector.add(table);
+        }
+
+        public ByteBuffer getClusteringKey(TxnData data)
+        {
+            Row row = getRow(data);
+            if (row == null)
+                return null;
+            return row.clustering().bufferAt(column.position());
+        }
 
-        // Modify the type we'll check if the reference is to a collection 
element.
-        if (selectsPath())
+        public ColumnData getColumnData(Row row)
         {
-            if (type.isCollection())
+            if (column.isClusteringColumn())
+                return new ClusteringColumnData(column, 
row.clustering().bufferAt(column.position()));
+            if (column.isComplex() && path == null)
+                return row.getComplexColumnData(column);
+
+            if (path != null && column.type.isMultiCell())
             {
-                CollectionType<?> collectionType = (CollectionType<?>) type;
-                type = collectionType.kind == SET ? 
collectionType.nameComparator() : collectionType.valueComparator();
+                if (column.type.isCollection())
+                {
+                    CollectionType<?> collectionType = (CollectionType<?>) 
column.type;
+
+                    if (collectionType.kind == CollectionType.Kind.LIST)
+                        return 
row.getComplexColumnData(column).getCellByIndex(ByteBufferUtil.toInt(path.get(0)));
+                }
+
+                return row.getCell(column, path);
             }
-            else if (type.isUDT())
-                type = getFieldSelectionType();
+
+            return row.getCell(column);
+        }
+
+        public ColumnData getColumnData(TxnData data)
+        {
+            Row row = getRow(data);
+            return row != null ? getColumnData(row) : null;
         }
 
-        // Account for frozen collection and reversed clustering key 
references:
-        AbstractType<?> receiveType = type.isFrozenCollection() ? 
receiver.freeze().unwrap() : receiver.unwrap();
-        if (!(receiveType == type.unwrap()))
-            throw new IllegalArgumentException("Receiving type " + receiveType 
+ " does not match " + type.unwrap());
+        public ByteBuffer getFrozenCollectionElement(Cell<?> collection)
+        {
+            CollectionType<?> collectionType = (CollectionType<?>) 
column.type.unwrap();
+            return 
collectionType.getSerializer().getSerializedValue(collection.buffer(), 
path.get(0), collectionType.nameComparator());
+        }
 
-        if (column().isPartitionKey())
-            return getPartitionKey(data);
-        else if (column().isClusteringColumn())
-            return getClusteringKey(data);
+        public AbstractType<?> getFrozenCollectionElementType()
+        {
+            CollectionType<?> type = (CollectionType<?>) column.type.unwrap();
+            if (type instanceof ListType) return Int32Type.instance; // by 
index is the only thing supported right now; see getFrozenCollectionElement
+            return type.nameComparator();
+        }
 
-        ColumnData columnData = getColumnData(data);
+        public ByteBuffer getFrozenFieldValue(Cell<?> udt)
+        {
+            UserType userType = (UserType) column.type.unwrap();
+            int field = ByteBufferUtil.getUnsignedShort(path.get(0), 0);
+            List<ByteBuffer> tuple = userType.unpack(udt.buffer());
+            return tuple.size() > field ? tuple.get(field) : null;
+        }
 
-        if (columnData == null)
-            return null;
+        public AbstractType<?> getFieldSelectionType()
+        {
+            assert isFieldSelection() : "No field selection type exists";
+            UserType userType = (UserType) column.type;
+            int field = ByteBufferUtil.getUnsignedShort(path.get(0), 0);

Review Comment:
   Even though `path` is `@Nullable`, I think here and in a couple places 
directly above, all callers are still in situations where `path` should be 
non-null. Not sure if we want to make some assertions here, but things would 
blow up when misused either way.



-- 
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: pr-unsubscr...@cassandra.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: pr-unsubscr...@cassandra.apache.org
For additional commands, e-mail: pr-h...@cassandra.apache.org

Reply via email to