2424import java .util .Map ;
2525import java .util .Objects ;
2626
27+ import javax .annotation .Nullable ;
28+
29+ import com .google .common .annotations .VisibleForTesting ;
30+
2731import org .apache .cassandra .cql3 .FieldIdentifier ;
2832import org .apache .cassandra .cql3 .Operation ;
2933import org .apache .cassandra .cql3 .UpdateParameters ;
3539import org .apache .cassandra .cql3 .terms .Term ;
3640import org .apache .cassandra .cql3 .terms .UserTypes ;
3741import org .apache .cassandra .db .DecoratedKey ;
42+ import org .apache .cassandra .db .TypeSizes ;
3843import org .apache .cassandra .db .marshal .AbstractType ;
3944import org .apache .cassandra .db .marshal .CollectionType ;
45+ import org .apache .cassandra .db .marshal .Int32Type ;
4046import org .apache .cassandra .db .marshal .ListType ;
4147import org .apache .cassandra .db .marshal .MapType ;
4248import org .apache .cassandra .db .marshal .SetType ;
5864public class TxnReferenceOperation
5965{
6066 private static final Map <Class <? extends Operation >, Kind > operationKindMap = initOperationKindMap ();
61-
62- private static Map <Class <? extends Operation >, Kind > initOperationKindMap ()
67+
68+ @ VisibleForTesting
69+ static Map <Class <? extends Operation >, Kind > initOperationKindMap ()
6370 {
6471 Map <Class <? extends Operation >, Kind > temp = new HashMap <>();
65- temp .put (Sets .Adder .class , Kind .SetAdder );
6672 temp .put (Constants .Adder .class , Kind .ConstantAdder );
73+ temp .put (Constants .Setter .class , Kind .ConstantSetter );
74+ temp .put (Constants .Substracter .class , Kind .ConstantSubtracter );
6775 temp .put (Lists .Appender .class , Kind .ListAppender );
68- temp .put (Sets .Discarder .class , Kind .SetDiscarder );
6976 temp .put (Lists .Discarder .class , Kind .ListDiscarder );
77+ temp .put (Lists .DiscarderByIndex .class , Kind .ListDiscarderByIndex );
7078 temp .put (Lists .Prepender .class , Kind .ListPrepender );
71- temp .put (Maps .Putter .class , Kind .MapPutter );
7279 temp .put (Lists .Setter .class , Kind .ListSetter );
73- temp .put (Sets .Setter .class , Kind .SetSetter );
80+ temp .put (Lists .SetterByIndex .class , Kind .ListSetterByIndex );
81+ temp .put (Maps .DiscarderByKey .class , Kind .MapDiscarderByKey );
82+ temp .put (Maps .Putter .class , Kind .MapPutter );
7483 temp .put (Maps .Setter .class , Kind .MapSetter );
75- temp .put (UserTypes .Setter .class , Kind .UserTypeSetter );
76- temp .put (Constants .Setter .class , Kind .ConstantSetter );
77- temp .put (Constants .Substracter .class , Kind .ConstantSubtracter );
7884 temp .put (Maps .SetterByKey .class , Kind .MapSetterByKey );
79- temp .put (Lists .SetterByIndex .class , Kind .ListSetterByIndex );
85+ temp .put (Sets .Adder .class , Kind .SetAdder );
86+ temp .put (Sets .Discarder .class , Kind .SetDiscarder );
87+ temp .put (Sets .ElementDiscarder .class , Kind .SetElementDiscarder );
88+ temp .put (Sets .Setter .class , Kind .SetSetter );
89+ temp .put (UserTypes .Setter .class , Kind .UserTypeSetter );
8090 temp .put (UserTypes .SetterByField .class , Kind .UserTypeSetterByField );
8191 return temp ;
8292 }
@@ -103,7 +113,10 @@ public enum Kind
103113 ConstantSubtracter ((byte ) 13 , (column , keyOrIndex , field , value ) -> new Constants .Substracter (column , value )),
104114 MapSetterByKey ((byte ) 14 , (column , keyOrIndex , field , value ) -> new Maps .SetterByKey (column , keyOrIndex , value )),
105115 ListSetterByIndex ((byte ) 15 , (column , keyOrIndex , field , value ) -> new Lists .SetterByIndex (column , keyOrIndex , value )),
106- UserTypeSetterByField ((byte ) 16 , (column , keyOrIndex , field , value ) -> new UserTypes .SetterByField (column , field , value ));
116+ UserTypeSetterByField ((byte ) 16 , (column , keyOrIndex , field , value ) -> new UserTypes .SetterByField (column , field , value )),
117+ ListDiscarderByIndex ((byte ) 17 , (column , keyOrIndex , field , value ) -> new Lists .DiscarderByIndex (column , value )),
118+ MapDiscarderByKey ((byte ) 18 , (column , keyOrIndex , field , value ) -> new Maps .DiscarderByKey (column , value )),
119+ SetElementDiscarder ((byte ) 19 , (column , keyOrIndex , field , value ) -> new Sets .ElementDiscarder (column , value ));
107120
108121 private final byte id ;
109122 private final ToOperation toOperation ;
@@ -154,18 +167,20 @@ public Operation toOperation(ColumnMetadata column, Term keyOrIndex, FieldIdenti
154167
155168 private final Kind kind ;
156169 private final ColumnMetadata receiver ;
157- private final TableMetadata table ;
158- private final ByteBuffer key ;
159- private final ByteBuffer field ;
170+ public final TableMetadata table ;
171+ private final @ Nullable ByteBuffer keyOrIndex ;
172+ private final @ Nullable ByteBuffer field ;
160173 private final TxnReferenceValue value ;
174+ private final @ Nullable AbstractType <?> keyOrIndexType ;
161175 private final AbstractType <?> valueType ;
162176
163- public TxnReferenceOperation (Kind kind , ColumnMetadata receiver , TableMetadata table , ByteBuffer key , ByteBuffer field , TxnReferenceValue value )
177+ public TxnReferenceOperation (Kind kind , ColumnMetadata receiver , TableMetadata table ,
178+ @ Nullable ByteBuffer keyOrIndex , @ Nullable ByteBuffer field , TxnReferenceValue value )
164179 {
165180 this .kind = kind ;
166181 this .receiver = receiver ;
167182 this .table = table ;
168- this .key = key ;
183+ this .keyOrIndex = keyOrIndex ;
169184 this .field = field ;
170185
171186 // We don't expect operators on clustering keys, but unwrap just in case.
@@ -175,20 +190,36 @@ public TxnReferenceOperation(Kind kind, ColumnMetadata receiver, TableMetadata t
175190 {
176191 // The value for a map subtraction is actually a set (see Operation.Substraction)
177192 this .valueType = SetType .getInstance (((MapType <?, ?>) receiverType ).getKeysType (), true );
193+ this .keyOrIndexType = null ;
194+ }
195+ else if (kind == Kind .MapDiscarderByKey || kind == Kind .SetElementDiscarder )
196+ {
197+ CollectionType <?> ct = (CollectionType <?>) receiverType ;
198+ this .keyOrIndexType = null ;
199+ this .valueType = ct .nameComparator ();
178200 }
179201 else if (kind == Kind .MapSetterByKey || kind == Kind .ListSetterByIndex )
180202 {
181- this .valueType = ((CollectionType <?>) receiverType ).valueComparator ();
203+ CollectionType <?> ct = (CollectionType <?>) receiverType ;
204+ this .keyOrIndexType = ct .nameComparator ();
205+ this .valueType = ct .valueComparator ();
206+ }
207+ else if (kind == Kind .ListDiscarderByIndex )
208+ {
209+ this .valueType = Int32Type .instance ;
210+ this .keyOrIndexType = null ;
182211 }
183212 else if (kind == Kind .UserTypeSetterByField )
184213 {
185214 UserType userType = (UserType ) receiverType ;
186215 CellPath fieldPath = userType .cellPathForField (new FieldIdentifier (field ));
187216 this .valueType = userType .fieldType (fieldPath );
217+ this .keyOrIndexType = null ;
188218 }
189219 else
190220 {
191221 this .valueType = receiverType ;
222+ this .keyOrIndexType = null ;
192223 }
193224
194225 this .value = value ;
@@ -202,27 +233,35 @@ public boolean equals(Object o)
202233 TxnReferenceOperation that = (TxnReferenceOperation ) o ;
203234 return Objects .equals (receiver , that .receiver )
204235 && kind == that .kind
205- && Objects .equals (key , that .key )
236+ && Objects .equals (keyOrIndex , that .keyOrIndex )
206237 && Objects .equals (field , that .field )
207238 && Objects .equals (value , that .value );
208239 }
209240
210- public void collect (TableMetadatas .Collector collector )
211- {
212- collector .add (table );
213- value .collect (collector );
214- }
215-
216241 @ Override
217242 public int hashCode ()
218243 {
219- return Objects .hash (receiver , kind , key , field , value );
244+ return Objects .hash (receiver , kind , keyOrIndex , field , value );
220245 }
221246
247+
222248 @ Override
223249 public String toString ()
224250 {
225- return receiver + " = " + value ;
251+ return "TxnReferenceOperation{" +
252+ "kind=" + kind +
253+ ", receiver=" + receiver +
254+ ", table=" + table +
255+ ", key=" + keyOrIndex +
256+ ", field=" + field +
257+ ", value=" + value +
258+ '}' ;
259+ }
260+
261+ public void collect (TableMetadatas .Collector collector )
262+ {
263+ collector .add (table );
264+ value .collect (collector );
226265 }
227266
228267 public ColumnMetadata receiver ()
@@ -236,11 +275,12 @@ public void apply(TxnData data, DecoratedKey key, UpdateParameters up)
236275 operation .execute (key , up );
237276 }
238277
239- private Operation toOperation (TxnData data )
278+ @ VisibleForTesting
279+ Operation toOperation (TxnData data )
240280 {
241281 FieldIdentifier fieldIdentifier = field == null ? null : new FieldIdentifier (field );
242282 Term valueTerm = toTerm (data , valueType );
243- Term keyorIndexTerm = key == null ? null : toTerm (key , valueType );
283+ Term keyorIndexTerm = keyOrIndex == null ? null : toTerm (keyOrIndex , keyOrIndexType );
244284 return kind .toOperation (receiver , keyorIndexTerm , fieldIdentifier , valueTerm );
245285 }
246286
@@ -274,9 +314,9 @@ public void serialize(TxnReferenceOperation operation, TableMetadatas tables, Da
274314 columnMetadataSerializer .serialize (operation .receiver , operation .table , out );
275315 TxnReferenceValue .serializer .serialize (operation .value , tables , out );
276316
277- out .writeBoolean (operation .key != null );
278- if (operation .key != null )
279- ByteBufferUtil .writeWithVIntLength (operation .key , out );
317+ out .writeBoolean (operation .keyOrIndex != null );
318+ if (operation .keyOrIndex != null )
319+ ByteBufferUtil .writeWithVIntLength (operation .keyOrIndex , out );
280320
281321 out .writeBoolean (operation .field != null );
282322 if (operation .field != null )
@@ -303,9 +343,11 @@ public long serializedSize(TxnReferenceOperation operation, TableMetadatas table
303343 size += columnMetadataSerializer .serializedSize (operation .receiver , operation .table );
304344 size += TxnReferenceValue .serializer .serializedSize (operation .value , tables );
305345
306- if (operation .key != null )
307- size += ByteBufferUtil .serializedSizeWithVIntLength (operation .key );
346+ size += TypeSizes .sizeof (operation .keyOrIndex != null );
347+ if (operation .keyOrIndex != null )
348+ size += ByteBufferUtil .serializedSizeWithVIntLength (operation .keyOrIndex );
308349
350+ size += TypeSizes .sizeof (operation .field != null );
309351 if (operation .field != null )
310352 size += ByteBufferUtil .serializedSizeWithVIntLength (operation .field );
311353
0 commit comments