protected ColumnNameBuilder makeIndexColumnNameBuilder(ByteBuffer rowKey, ByteBuffer columnName) { int ckCount = baseCfs.metadata.clusteringKeyColumns().size(); CompositeType baseComparator = (CompositeType) baseCfs.getComparator(); ByteBuffer[] components = baseComparator.split(columnName); CompositeType.Builder builder = getIndexComparator().builder(); builder.add(rowKey); for (int i = 0; i < ckCount; i++) builder.add(components[i]); return builder; }
public static CompositeType buildIndexComparator( CFMetaData baseMetadata, ColumnDefinition columnDef) { int ckCount = baseMetadata.clusteringKeyColumns().size(); List<AbstractType<?>> types = new ArrayList<AbstractType<?>>(ckCount + 1); types.add(SecondaryIndex.keyComparator); types.addAll(baseMetadata.comparator.getComponents()); return CompositeType.getInstance(types); }
/** * Returns a {@code String} representation of {@code byteBuffer} validated by {@code type}. * * @param byteBuffer the {@link ByteBuffer} to be converted to {@code String}. * @param type {@link AbstractType} of {@code byteBuffer}. * @return a {@code String} representation of {@code byteBuffer} validated by {@code type}. */ public static String toString(ByteBuffer byteBuffer, AbstractType<?> type) { if (type instanceof CompositeType) { CompositeType composite = (CompositeType) type; List<AbstractType<?>> types = composite.types; ByteBuffer[] components = composite.split(byteBuffer); StringBuilder sb = new StringBuilder(); for (int i = 0; i < components.length; i++) { AbstractType<?> componentType = types.get(i); ByteBuffer component = components[i]; sb.append(componentType.compose(component)); if (i < types.size() - 1) { sb.append(':'); } } return sb.toString(); } else { return type.compose(byteBuffer).toString(); } }
private ByteBuffer getPartitionKey(Map<String, ByteBuffer> keyColumns) { ByteBuffer partitionKey; if (partitionKeyColumns.size() > 1) { ByteBuffer[] keys = new ByteBuffer[partitionKeyColumns.size()]; for (int i = 0; i < keys.length; i++) keys[i] = keyColumns.get(partitionKeyColumns.get(i).getName()); partitionKey = CompositeType.build(keys); } else { partitionKey = keyColumns.get(partitionKeyColumns.get(0).getName()); } return partitionKey; }
private static CFMetaData compositeCFMD(String ksName, String cfName, AbstractType... types) { try { return new CFMetaData( ksName, cfName, ColumnFamilyType.Standard, CompositeType.getInstance(Arrays.asList(types)), null); } catch (ConfigurationException e) { } return null; }
private void testDontPurgeAccidentaly(String k, String cfname) throws IOException, ExecutionException, InterruptedException { // This test catches the regression of CASSANDRA-2786 Keyspace keyspace = Keyspace.open(KEYSPACE1); ColumnFamilyStore cfs = keyspace.getColumnFamilyStore(cfname); // disable compaction while flushing cfs.clearUnsafe(); cfs.disableAutoCompaction(); // Add test row DecoratedKey key = Util.dk(k); RowMutation rm = new RowMutation(KEYSPACE1, key.key); rm.add( cfname, CompositeType.build(ByteBufferUtil.bytes("sc"), ByteBufferUtil.bytes("c")), ByteBufferUtil.EMPTY_BYTE_BUFFER, 0); rm.apply(); cfs.forceBlockingFlush(); Collection<SSTableReader> sstablesBefore = cfs.getSSTables(); QueryFilter filter = QueryFilter.getIdentityFilter(key, cfname, System.currentTimeMillis()); assert !(cfs.getColumnFamily(filter).getColumnCount() == 0); // Remove key rm = new RowMutation(KEYSPACE1, key.key); rm.delete(cfname, 2); rm.apply(); ColumnFamily cf = cfs.getColumnFamily(filter); assert cf == null || cf.getColumnCount() == 0 : "should be empty: " + cf; // Sleep one second so that the removal is indeed purgeable even with gcgrace == 0 Thread.sleep(1000); cfs.forceBlockingFlush(); Collection<SSTableReader> sstablesAfter = cfs.getSSTables(); Collection<SSTableReader> toCompact = new ArrayList<SSTableReader>(); for (SSTableReader sstable : sstablesAfter) if (!sstablesBefore.contains(sstable)) toCompact.add(sstable); Util.compact(cfs, toCompact); cf = cfs.getColumnFamily(filter); assert cf == null || cf.getColumnCount() == 0 : "should be empty: " + cf; }
@Test public void testSuperColumnTombstones() throws IOException, ExecutionException, InterruptedException { Keyspace keyspace = Keyspace.open(KEYSPACE1); ColumnFamilyStore cfs = keyspace.getColumnFamilyStore("Super1"); cfs.disableAutoCompaction(); DecoratedKey key = Util.dk("tskey"); ByteBuffer scName = ByteBufferUtil.bytes("TestSuperColumn"); // a subcolumn RowMutation rm = new RowMutation(KEYSPACE1, key.key); rm.add( "Super1", CompositeType.build(scName, ByteBufferUtil.bytes(0)), ByteBufferUtil.EMPTY_BYTE_BUFFER, FBUtilities.timestampMicros()); rm.apply(); cfs.forceBlockingFlush(); // shadow the subcolumn with a supercolumn tombstone rm = new RowMutation(KEYSPACE1, key.key); rm.deleteRange( "Super1", SuperColumns.startOf(scName), SuperColumns.endOf(scName), FBUtilities.timestampMicros()); rm.apply(); cfs.forceBlockingFlush(); CompactionManager.instance.performMaximal(cfs); assertEquals(1, cfs.getSSTables().size()); // check that the shadowed column is gone SSTableReader sstable = cfs.getSSTables().iterator().next(); Range keyRange = new Range<RowPosition>(key, sstable.partitioner.getMinimumToken().maxKeyBound()); SSTableScanner scanner = sstable.getScanner(DataRange.forKeyRange(keyRange)); OnDiskAtomIterator iter = scanner.next(); assertEquals(key, iter.getKey()); assert iter.next() instanceof RangeTombstone; assert !iter.hasNext(); }
private Statics() { StandardCf.addColumn(new Column(bb("aaaa"))); StandardCf.addColumn(new Column(bb("bbbb"), bb("bbbbb-value"))); StandardCf.addColumn(new Column(bb("cccc"), bb("ccccc-value"), 1000L)); StandardCf.addColumn(new DeletedColumn(bb("dddd"), 500, 1000)); StandardCf.addColumn(new DeletedColumn(bb("eeee"), bb("eeee-value"), 1001)); StandardCf.addColumn(new ExpiringColumn(bb("ffff"), bb("ffff-value"), 2000, 1000)); StandardCf.addColumn(new ExpiringColumn(bb("gggg"), bb("gggg-value"), 2001, 1000, 2002)); SuperCf.addColumn(new Column(CompositeType.build(SC, bb("aaaa")))); SuperCf.addColumn(new Column(CompositeType.build(SC, bb("bbbb")), bb("bbbbb-value"))); SuperCf.addColumn(new Column(CompositeType.build(SC, bb("cccc")), bb("ccccc-value"), 1000L)); SuperCf.addColumn(new DeletedColumn(CompositeType.build(SC, bb("dddd")), 500, 1000)); SuperCf.addColumn( new DeletedColumn(CompositeType.build(SC, bb("eeee")), bb("eeee-value"), 1001)); SuperCf.addColumn( new ExpiringColumn(CompositeType.build(SC, bb("ffff")), bb("ffff-value"), 2000, 1000)); SuperCf.addColumn( new ExpiringColumn( CompositeType.build(SC, bb("gggg")), bb("gggg-value"), 2001, 1000, 2002)); }
protected ByteBuffer getIndexedValue(ByteBuffer rowKey, Column column) { CompositeType keyComparator = (CompositeType) baseCfs.metadata.getKeyValidator(); ByteBuffer[] components = keyComparator.split(rowKey); return components[columnDef.componentIndex]; }
public void announceMigration() throws RequestValidationException { CFMetaData meta = validateColumnFamily(keyspace(), columnFamily()); CFMetaData cfm = meta.clone(); CFDefinition cfDef = meta.getCfDef(); CFDefinition.Name name = columnName == null ? null : cfDef.get(columnName); switch (oType) { case ADD: if (cfDef.isCompact) throw new InvalidRequestException("Cannot add new column to a compact CF"); if (name != null) { switch (name.kind) { case KEY_ALIAS: case COLUMN_ALIAS: throw new InvalidRequestException( String.format( "Invalid column name %s because it conflicts with a PRIMARY KEY part", columnName)); case COLUMN_METADATA: throw new InvalidRequestException( String.format( "Invalid column name %s because it conflicts with an existing column", columnName)); } } AbstractType<?> type = validator.getType(); if (type instanceof CollectionType) { if (!cfDef.isComposite) throw new InvalidRequestException( "Cannot use collection types with non-composite PRIMARY KEY"); if (cfDef.cfm.isSuper()) throw new InvalidRequestException( "Cannot use collection types with Super column family"); Map<ByteBuffer, CollectionType> collections = cfDef.hasCollections ? new HashMap<ByteBuffer, CollectionType>(cfDef.getCollectionType().defined) : new HashMap<ByteBuffer, CollectionType>(); collections.put(columnName.key, (CollectionType) type); ColumnToCollectionType newColType = ColumnToCollectionType.getInstance(collections); List<AbstractType<?>> ctypes = new ArrayList<AbstractType<?>>(((CompositeType) cfm.comparator).types); if (cfDef.hasCollections) ctypes.set(ctypes.size() - 1, newColType); else ctypes.add(newColType); cfm.comparator = CompositeType.getInstance(ctypes); } Integer componentIndex = cfDef.isComposite ? ((CompositeType) meta.comparator).types.size() - (cfDef.hasCollections ? 2 : 1) : null; cfm.addColumnDefinition(ColumnDefinition.regularDef(columnName.key, type, componentIndex)); break; case ALTER: if (name == null) throw new InvalidRequestException( String.format("Column %s was not found in table %s", columnName, columnFamily())); switch (name.kind) { case KEY_ALIAS: AbstractType<?> newType = validator.getType(); if (newType instanceof CounterColumnType) throw new InvalidRequestException( String.format( "counter type is not supported for PRIMARY KEY part %s", columnName)); if (cfDef.hasCompositeKey) { List<AbstractType<?>> newTypes = new ArrayList<AbstractType<?>>(((CompositeType) cfm.getKeyValidator()).types); newTypes.set(name.position, newType); cfm.keyValidator(CompositeType.getInstance(newTypes)); } else { cfm.keyValidator(newType); } break; case COLUMN_ALIAS: assert cfDef.isComposite; List<AbstractType<?>> newTypes = new ArrayList<AbstractType<?>>(((CompositeType) cfm.comparator).types); newTypes.set(name.position, validator.getType()); cfm.comparator = CompositeType.getInstance(newTypes); break; case VALUE_ALIAS: cfm.defaultValidator(validator.getType()); break; case COLUMN_METADATA: ColumnDefinition column = cfm.getColumnDefinition(columnName.key); column.setValidator(validator.getType()); break; } break; case DROP: if (cfDef.isCompact) throw new InvalidRequestException("Cannot drop columns from a compact CF"); if (name == null) throw new InvalidRequestException( String.format("Column %s was not found in table %s", columnName, columnFamily())); switch (name.kind) { case KEY_ALIAS: case COLUMN_ALIAS: throw new InvalidRequestException( String.format("Cannot drop PRIMARY KEY part %s", columnName)); case COLUMN_METADATA: ColumnDefinition toDelete = null; for (ColumnDefinition columnDef : cfm.regularColumns()) { if (columnDef.name.equals(columnName.key)) toDelete = columnDef; } assert toDelete != null; cfm.removeColumnDefinition(toDelete); break; } break; case OPTS: if (cfProps == null) throw new InvalidRequestException( String.format("ALTER COLUMNFAMILY WITH invoked, but no parameters found")); cfProps.validate(); cfProps.applyToCFMetadata(cfm); break; case RENAME: for (Map.Entry<ColumnIdentifier, ColumnIdentifier> entry : renames.entrySet()) { ColumnIdentifier from = entry.getKey(); ColumnIdentifier to = entry.getValue(); cfm.renameColumn(from.key, from.toString(), to.key, to.toString()); } break; } MigrationManager.announceColumnFamilyUpdate(cfm, false); }
/** Transform this raw statement into a CreateTableStatement. */ public ParsedStatement.Prepared prepare() throws RequestValidationException { // Column family name if (!columnFamily().matches("\\w+")) throw new InvalidRequestException( String.format( "\"%s\" is not a valid column family name (must be alphanumeric character only: [0-9A-Za-z]+)", columnFamily())); if (columnFamily().length() > Schema.NAME_LENGTH) throw new InvalidRequestException( String.format( "Column family names shouldn't be more than %s characters long (got \"%s\")", Schema.NAME_LENGTH, columnFamily())); for (Multiset.Entry<ColumnIdentifier> entry : definedNames.entrySet()) if (entry.getCount() > 1) throw new InvalidRequestException( String.format("Multiple definition of identifier %s", entry.getElement())); properties.validate(); CreateTableStatement stmt = new CreateTableStatement(cfName, properties, ifNotExists, staticColumns); Map<ByteBuffer, CollectionType> definedCollections = null; for (Map.Entry<ColumnIdentifier, CQL3Type> entry : definitions.entrySet()) { ColumnIdentifier id = entry.getKey(); CQL3Type pt = entry.getValue(); if (pt.isCollection()) { if (definedCollections == null) definedCollections = new HashMap<ByteBuffer, CollectionType>(); definedCollections.put(id.key, (CollectionType) pt.getType()); } stmt.columns.put(id, pt.getType()); // we'll remove what is not a column below } if (keyAliases.isEmpty()) throw new InvalidRequestException("No PRIMARY KEY specifed (exactly one required)"); else if (keyAliases.size() > 1) throw new InvalidRequestException("Multiple PRIMARY KEYs specifed (exactly one required)"); List<ColumnIdentifier> kAliases = keyAliases.get(0); List<AbstractType<?>> keyTypes = new ArrayList<AbstractType<?>>(kAliases.size()); for (ColumnIdentifier alias : kAliases) { stmt.keyAliases.add(alias.key); AbstractType<?> t = getTypeAndRemove(stmt.columns, alias); if (t instanceof CounterColumnType) throw new InvalidRequestException( String.format("counter type is not supported for PRIMARY KEY part %s", alias)); if (staticColumns.contains(alias)) throw new InvalidRequestException( String.format("Static column %s cannot be part of the PRIMARY KEY", alias)); keyTypes.add(t); } stmt.keyValidator = keyTypes.size() == 1 ? keyTypes.get(0) : CompositeType.getInstance(keyTypes); // Dense means that no part of the comparator stores a CQL column name. This means // COMPACT STORAGE with at least one columnAliases (otherwise it's a thrift "static" CF). stmt.isDense = useCompactStorage && !columnAliases.isEmpty(); // Handle column aliases if (columnAliases.isEmpty()) { if (useCompactStorage) { // There should remain some column definition since it is a non-composite "static" CF if (stmt.columns.isEmpty()) throw new InvalidRequestException( "No definition found that is not part of the PRIMARY KEY"); if (definedCollections != null) throw new InvalidRequestException( "Collection types are not supported with COMPACT STORAGE"); stmt.comparator = CFDefinition.definitionType; } else { List<AbstractType<?>> types = new ArrayList<AbstractType<?>>(definedCollections == null ? 1 : 2); types.add(CFDefinition.definitionType); if (definedCollections != null) types.add(ColumnToCollectionType.getInstance(definedCollections)); stmt.comparator = CompositeType.getInstance(types); } } else { // If we use compact storage and have only one alias, it is a // standard "dynamic" CF, otherwise it's a composite if (useCompactStorage && columnAliases.size() == 1) { if (definedCollections != null) throw new InvalidRequestException( "Collection types are not supported with COMPACT STORAGE"); ColumnIdentifier alias = columnAliases.get(0); stmt.columnAliases.add(alias.key); stmt.comparator = getTypeAndRemove(stmt.columns, alias); if (stmt.comparator instanceof CounterColumnType) throw new InvalidRequestException( String.format("counter type is not supported for PRIMARY KEY part %s", alias)); if (staticColumns.contains(alias)) throw new InvalidRequestException( String.format("Static column %s cannot be part of the PRIMARY KEY", alias)); } else { List<AbstractType<?>> types = new ArrayList<AbstractType<?>>(columnAliases.size() + 1); for (ColumnIdentifier t : columnAliases) { stmt.columnAliases.add(t.key); AbstractType<?> type = getTypeAndRemove(stmt.columns, t); if (type instanceof CounterColumnType) throw new InvalidRequestException( String.format("counter type is not supported for PRIMARY KEY part %s", t)); if (staticColumns.contains(t)) throw new InvalidRequestException( String.format("Static column %s cannot be part of the PRIMARY KEY", t)); types.add(type); } if (useCompactStorage) { if (definedCollections != null) throw new InvalidRequestException( "Collection types are not supported with COMPACT STORAGE"); } else { // For sparse, we must add the last UTF8 component // and the collection type if there is one types.add(CFDefinition.definitionType); if (definedCollections != null) types.add(ColumnToCollectionType.getInstance(definedCollections)); } if (types.isEmpty()) throw new IllegalStateException("Nonsensical empty parameter list for CompositeType"); stmt.comparator = CompositeType.getInstance(types); } } if (!staticColumns.isEmpty()) { // Only CQL3 tables can have static columns if (useCompactStorage) throw new InvalidRequestException( "Static columns are not supported in COMPACT STORAGE tables"); // Static columns only make sense if we have at least one clustering column. Otherwise // everything is static anyway if (columnAliases.isEmpty()) throw new InvalidRequestException( "Static columns are only useful (and thus allowed) if the table has at least one clustering column"); } if (useCompactStorage && !stmt.columnAliases.isEmpty()) { if (stmt.columns.isEmpty()) { // The only value we'll insert will be the empty one, so the default validator don't // matter stmt.defaultValidator = BytesType.instance; // We need to distinguish between // * I'm upgrading from thrift so the valueAlias is null // * I've defined my table with only a PK (and the column value will be empty) // So, we use an empty valueAlias (rather than null) for the second case stmt.valueAlias = ByteBufferUtil.EMPTY_BYTE_BUFFER; } else { if (stmt.columns.size() > 1) throw new InvalidRequestException( String.format( "COMPACT STORAGE with composite PRIMARY KEY allows no more than one column not part of the PRIMARY KEY (got: %s)", StringUtils.join(stmt.columns.keySet(), ", "))); Map.Entry<ColumnIdentifier, AbstractType> lastEntry = stmt.columns.entrySet().iterator().next(); stmt.defaultValidator = lastEntry.getValue(); stmt.valueAlias = lastEntry.getKey().key; stmt.columns.remove(lastEntry.getKey()); } } else { // For compact, we are in the "static" case, so we need at least one column defined. For // non-compact however, having // just the PK is fine since we have CQL3 row marker. if (useCompactStorage && stmt.columns.isEmpty()) throw new InvalidRequestException( "COMPACT STORAGE with non-composite PRIMARY KEY require one column not part of the PRIMARY KEY, none given"); // There is no way to insert/access a column that is not defined for non-compact storage, so // the actual validator don't matter much (except that we want to recognize counter CF as // limitation apply to them). stmt.defaultValidator = !stmt.columns.isEmpty() && (stmt.columns.values().iterator().next() instanceof CounterColumnType) ? CounterColumnType.instance : BytesType.instance; } // If we give a clustering order, we must explicitly do so for all aliases and in the order of // the PK if (!definedOrdering.isEmpty()) { if (definedOrdering.size() > columnAliases.size()) throw new InvalidRequestException( "Only clustering key columns can be defined in CLUSTERING ORDER directive"); int i = 0; for (ColumnIdentifier id : definedOrdering.keySet()) { ColumnIdentifier c = columnAliases.get(i); if (!id.equals(c)) { if (definedOrdering.containsKey(c)) throw new InvalidRequestException( String.format( "The order of columns in the CLUSTERING ORDER directive must be the one of the clustering key (%s must appear before %s)", c, id)); else throw new InvalidRequestException( String.format("Missing CLUSTERING ORDER for column %s", c)); } ++i; } } return new ParsedStatement.Prepared(stmt); }
public class SerializationsTest extends AbstractSerializationsTester { Statics statics = new Statics(); @BeforeClass public static void loadSchema() throws IOException, ConfigurationException { loadSchema(true); } private ByteBuffer startCol = ByteBufferUtil.bytes("Start"); private ByteBuffer stopCol = ByteBufferUtil.bytes("Stop"); private ByteBuffer emptyCol = ByteBufferUtil.bytes(""); public NamesQueryFilter namesPred = new NamesQueryFilter(statics.NamedCols); public NamesQueryFilter namesSCPred = new NamesQueryFilter(statics.NamedSCCols); public SliceQueryFilter emptyRangePred = new SliceQueryFilter(emptyCol, emptyCol, false, 100); public SliceQueryFilter nonEmptyRangePred = new SliceQueryFilter(startCol, stopCol, true, 100); public SliceQueryFilter nonEmptyRangeSCPred = new SliceQueryFilter( CompositeType.build(statics.SC, startCol), CompositeType.build(statics.SC, stopCol), true, 100); private void testRangeSliceCommandWrite() throws IOException { IPartitioner part = StorageService.getPartitioner(); AbstractBounds<RowPosition> bounds = new Range<Token>(part.getRandomToken(), part.getRandomToken()).toRowBounds(); RangeSliceCommand namesCmd = new RangeSliceCommand(statics.KS, "Standard1", statics.readTs, namesPred, bounds, 100); MessageOut<RangeSliceCommand> namesCmdMsg = namesCmd.createMessage(); RangeSliceCommand emptyRangeCmd = new RangeSliceCommand(statics.KS, "Standard1", statics.readTs, emptyRangePred, bounds, 100); MessageOut<RangeSliceCommand> emptyRangeCmdMsg = emptyRangeCmd.createMessage(); RangeSliceCommand regRangeCmd = new RangeSliceCommand( statics.KS, "Standard1", statics.readTs, nonEmptyRangePred, bounds, 100); MessageOut<RangeSliceCommand> regRangeCmdMsg = regRangeCmd.createMessage(); RangeSliceCommand namesCmdSup = new RangeSliceCommand(statics.KS, "Super1", statics.readTs, namesSCPred, bounds, 100); MessageOut<RangeSliceCommand> namesCmdSupMsg = namesCmdSup.createMessage(); RangeSliceCommand emptyRangeCmdSup = new RangeSliceCommand(statics.KS, "Super1", statics.readTs, emptyRangePred, bounds, 100); MessageOut<RangeSliceCommand> emptyRangeCmdSupMsg = emptyRangeCmdSup.createMessage(); RangeSliceCommand regRangeCmdSup = new RangeSliceCommand( statics.KS, "Super1", statics.readTs, nonEmptyRangeSCPred, bounds, 100); MessageOut<RangeSliceCommand> regRangeCmdSupMsg = regRangeCmdSup.createMessage(); DataOutputStream out = getOutput("db.RangeSliceCommand.bin"); namesCmdMsg.serialize(out, getVersion()); emptyRangeCmdMsg.serialize(out, getVersion()); regRangeCmdMsg.serialize(out, getVersion()); namesCmdSupMsg.serialize(out, getVersion()); emptyRangeCmdSupMsg.serialize(out, getVersion()); regRangeCmdSupMsg.serialize(out, getVersion()); out.close(); // test serializedSize testSerializedSize(namesCmd, RangeSliceCommand.serializer); testSerializedSize(emptyRangeCmd, RangeSliceCommand.serializer); testSerializedSize(regRangeCmd, RangeSliceCommand.serializer); testSerializedSize(namesCmdSup, RangeSliceCommand.serializer); testSerializedSize(emptyRangeCmdSup, RangeSliceCommand.serializer); testSerializedSize(regRangeCmdSup, RangeSliceCommand.serializer); } @Test public void testRangeSliceCommandRead() throws IOException { if (EXECUTE_WRITES) testRangeSliceCommandWrite(); DataInputStream in = getInput("db.RangeSliceCommand.bin"); for (int i = 0; i < 6; i++) MessageIn.read(in, getVersion(), -1); in.close(); } private void testSliceByNamesReadCommandWrite() throws IOException { SliceByNamesReadCommand standardCmd = new SliceByNamesReadCommand( statics.KS, statics.Key, statics.StandardCF, statics.readTs, namesPred); SliceByNamesReadCommand superCmd = new SliceByNamesReadCommand( statics.KS, statics.Key, statics.SuperCF, statics.readTs, namesSCPred); DataOutputStream out = getOutput("db.SliceByNamesReadCommand.bin"); SliceByNamesReadCommand.serializer.serialize(standardCmd, out, getVersion()); SliceByNamesReadCommand.serializer.serialize(superCmd, out, getVersion()); ReadCommand.serializer.serialize(standardCmd, out, getVersion()); ReadCommand.serializer.serialize(superCmd, out, getVersion()); standardCmd.createMessage().serialize(out, getVersion()); superCmd.createMessage().serialize(out, getVersion()); out.close(); // test serializedSize testSerializedSize(standardCmd, SliceByNamesReadCommand.serializer); testSerializedSize(superCmd, SliceByNamesReadCommand.serializer); } @Test public void testSliceByNamesReadCommandRead() throws IOException { if (EXECUTE_WRITES) testSliceByNamesReadCommandWrite(); DataInputStream in = getInput("db.SliceByNamesReadCommand.bin"); assert SliceByNamesReadCommand.serializer.deserialize(in, getVersion()) != null; assert SliceByNamesReadCommand.serializer.deserialize(in, getVersion()) != null; assert ReadCommand.serializer.deserialize(in, getVersion()) != null; assert ReadCommand.serializer.deserialize(in, getVersion()) != null; assert MessageIn.read(in, getVersion(), -1) != null; assert MessageIn.read(in, getVersion(), -1) != null; in.close(); } private void testSliceFromReadCommandWrite() throws IOException { SliceFromReadCommand standardCmd = new SliceFromReadCommand( statics.KS, statics.Key, statics.StandardCF, statics.readTs, nonEmptyRangePred); SliceFromReadCommand superCmd = new SliceFromReadCommand( statics.KS, statics.Key, statics.SuperCF, statics.readTs, nonEmptyRangeSCPred); DataOutputStream out = getOutput("db.SliceFromReadCommand.bin"); SliceFromReadCommand.serializer.serialize(standardCmd, out, getVersion()); SliceFromReadCommand.serializer.serialize(superCmd, out, getVersion()); ReadCommand.serializer.serialize(standardCmd, out, getVersion()); ReadCommand.serializer.serialize(superCmd, out, getVersion()); standardCmd.createMessage().serialize(out, getVersion()); superCmd.createMessage().serialize(out, getVersion()); out.close(); // test serializedSize testSerializedSize(standardCmd, SliceFromReadCommand.serializer); testSerializedSize(superCmd, SliceFromReadCommand.serializer); } @Test public void testSliceFromReadCommandRead() throws IOException { if (EXECUTE_WRITES) testSliceFromReadCommandWrite(); DataInputStream in = getInput("db.SliceFromReadCommand.bin"); assert SliceFromReadCommand.serializer.deserialize(in, getVersion()) != null; assert SliceFromReadCommand.serializer.deserialize(in, getVersion()) != null; assert ReadCommand.serializer.deserialize(in, getVersion()) != null; assert ReadCommand.serializer.deserialize(in, getVersion()) != null; assert MessageIn.read(in, getVersion(), -1) != null; assert MessageIn.read(in, getVersion(), -1) != null; in.close(); } private void testRowWrite() throws IOException { DataOutputStream out = getOutput("db.Row.bin"); Row.serializer.serialize(statics.StandardRow, out, getVersion()); Row.serializer.serialize(statics.SuperRow, out, getVersion()); Row.serializer.serialize(statics.NullRow, out, getVersion()); out.close(); // test serializedSize testSerializedSize(statics.StandardRow, Row.serializer); testSerializedSize(statics.SuperRow, Row.serializer); testSerializedSize(statics.NullRow, Row.serializer); } @Test public void testRowRead() throws IOException { if (EXECUTE_WRITES) testRowWrite(); DataInputStream in = getInput("db.Row.bin"); assert Row.serializer.deserialize(in, getVersion()) != null; assert Row.serializer.deserialize(in, getVersion()) != null; assert Row.serializer.deserialize(in, getVersion()) != null; in.close(); } private void testRowMutationWrite() throws IOException { RowMutation standardRowRm = new RowMutation(statics.KS, statics.StandardRow); RowMutation superRowRm = new RowMutation(statics.KS, statics.SuperRow); RowMutation standardRm = new RowMutation(statics.KS, statics.Key, statics.StandardCf); RowMutation superRm = new RowMutation(statics.KS, statics.Key, statics.SuperCf); Map<UUID, ColumnFamily> mods = new HashMap<UUID, ColumnFamily>(); mods.put(statics.StandardCf.metadata().cfId, statics.StandardCf); mods.put(statics.SuperCf.metadata().cfId, statics.SuperCf); RowMutation mixedRm = new RowMutation(statics.KS, statics.Key, mods); DataOutputStream out = getOutput("db.RowMutation.bin"); RowMutation.serializer.serialize(standardRowRm, out, getVersion()); RowMutation.serializer.serialize(superRowRm, out, getVersion()); RowMutation.serializer.serialize(standardRm, out, getVersion()); RowMutation.serializer.serialize(superRm, out, getVersion()); RowMutation.serializer.serialize(mixedRm, out, getVersion()); standardRowRm.createMessage().serialize(out, getVersion()); superRowRm.createMessage().serialize(out, getVersion()); standardRm.createMessage().serialize(out, getVersion()); superRm.createMessage().serialize(out, getVersion()); mixedRm.createMessage().serialize(out, getVersion()); out.close(); // test serializedSize testSerializedSize(standardRowRm, RowMutation.serializer); testSerializedSize(superRowRm, RowMutation.serializer); testSerializedSize(standardRm, RowMutation.serializer); testSerializedSize(superRm, RowMutation.serializer); testSerializedSize(mixedRm, RowMutation.serializer); } @Test public void testRowMutationRead() throws IOException { // row mutation deserialization requires being able to look up the keyspace in the schema, // so we need to rewrite this each time. We can go back to testing on-disk data // once we pull RM.keyspace field out. testRowMutationWrite(); DataInputStream in = getInput("db.RowMutation.bin"); assert RowMutation.serializer.deserialize(in, getVersion()) != null; assert RowMutation.serializer.deserialize(in, getVersion()) != null; assert RowMutation.serializer.deserialize(in, getVersion()) != null; assert RowMutation.serializer.deserialize(in, getVersion()) != null; assert RowMutation.serializer.deserialize(in, getVersion()) != null; assert MessageIn.read(in, getVersion(), -1) != null; assert MessageIn.read(in, getVersion(), -1) != null; assert MessageIn.read(in, getVersion(), -1) != null; assert MessageIn.read(in, getVersion(), -1) != null; assert MessageIn.read(in, getVersion(), -1) != null; in.close(); } private void testTruncateWrite() throws IOException { Truncation tr = new Truncation(statics.KS, "Doesn't Really Matter"); TruncateResponse aff = new TruncateResponse(statics.KS, "Doesn't Matter Either", true); TruncateResponse neg = new TruncateResponse(statics.KS, "Still Doesn't Matter", false); DataOutputStream out = getOutput("db.Truncation.bin"); Truncation.serializer.serialize(tr, out, getVersion()); TruncateResponse.serializer.serialize(aff, out, getVersion()); TruncateResponse.serializer.serialize(neg, out, getVersion()); tr.createMessage().serialize(out, getVersion()); aff.createMessage().serialize(out, getVersion()); neg.createMessage().serialize(out, getVersion()); // todo: notice how CF names weren't validated. out.close(); // test serializedSize testSerializedSize(tr, Truncation.serializer); testSerializedSize(aff, TruncateResponse.serializer); testSerializedSize(neg, TruncateResponse.serializer); } @Test public void testTruncateRead() throws IOException { if (EXECUTE_WRITES) testTruncateWrite(); DataInputStream in = getInput("db.Truncation.bin"); assert Truncation.serializer.deserialize(in, getVersion()) != null; assert TruncateResponse.serializer.deserialize(in, getVersion()) != null; assert TruncateResponse.serializer.deserialize(in, getVersion()) != null; assert MessageIn.read(in, getVersion(), -1) != null; // set up some fake callbacks so deserialization knows that what it's deserializing is a // TruncateResponse MessagingService.instance() .setCallbackForTests(1, new CallbackInfo(null, null, TruncateResponse.serializer)); MessagingService.instance() .setCallbackForTests(2, new CallbackInfo(null, null, TruncateResponse.serializer)); assert MessageIn.read(in, getVersion(), 1) != null; assert MessageIn.read(in, getVersion(), 2) != null; in.close(); } private void testWriteResponseWrite() throws IOException { WriteResponse aff = new WriteResponse(); WriteResponse neg = new WriteResponse(); DataOutputStream out = getOutput("db.WriteResponse.bin"); WriteResponse.serializer.serialize(aff, out, getVersion()); WriteResponse.serializer.serialize(neg, out, getVersion()); out.close(); // test serializedSize testSerializedSize(aff, WriteResponse.serializer); testSerializedSize(neg, WriteResponse.serializer); } @Test public void testWriteResponseRead() throws IOException { if (EXECUTE_WRITES) testWriteResponseWrite(); DataInputStream in = getInput("db.WriteResponse.bin"); assert WriteResponse.serializer.deserialize(in, getVersion()) != null; assert WriteResponse.serializer.deserialize(in, getVersion()) != null; in.close(); } private static ByteBuffer bb(String s) { return ByteBufferUtil.bytes(s); } private static class Statics { private final String KS = "Keyspace1"; private final ByteBuffer Key = ByteBufferUtil.bytes("Key01"); private final SortedSet<ByteBuffer> NamedCols = new TreeSet<ByteBuffer>(BytesType.instance) { { add(ByteBufferUtil.bytes("AAA")); add(ByteBufferUtil.bytes("BBB")); add(ByteBufferUtil.bytes("CCC")); } }; private final ByteBuffer SC = ByteBufferUtil.bytes("SCName"); private final SortedSet<ByteBuffer> NamedSCCols = new TreeSet<ByteBuffer>(BytesType.instance) { { add(CompositeType.build(SC, ByteBufferUtil.bytes("AAA"))); add(CompositeType.build(SC, ByteBufferUtil.bytes("BBB"))); add(CompositeType.build(SC, ByteBufferUtil.bytes("CCC"))); } }; private final String StandardCF = "Standard1"; private final String SuperCF = "Super1"; private final long readTs = 1369935512292L; private final ColumnFamily StandardCf = TreeMapBackedSortedColumns.factory.create(KS, StandardCF); private final ColumnFamily SuperCf = TreeMapBackedSortedColumns.factory.create(KS, SuperCF); private final Row StandardRow = new Row(Util.dk("key0"), StandardCf); private final Row SuperRow = new Row(Util.dk("key1"), SuperCf); private final Row NullRow = new Row(Util.dk("key2"), null); private Statics() { StandardCf.addColumn(new Column(bb("aaaa"))); StandardCf.addColumn(new Column(bb("bbbb"), bb("bbbbb-value"))); StandardCf.addColumn(new Column(bb("cccc"), bb("ccccc-value"), 1000L)); StandardCf.addColumn(new DeletedColumn(bb("dddd"), 500, 1000)); StandardCf.addColumn(new DeletedColumn(bb("eeee"), bb("eeee-value"), 1001)); StandardCf.addColumn(new ExpiringColumn(bb("ffff"), bb("ffff-value"), 2000, 1000)); StandardCf.addColumn(new ExpiringColumn(bb("gggg"), bb("gggg-value"), 2001, 1000, 2002)); SuperCf.addColumn(new Column(CompositeType.build(SC, bb("aaaa")))); SuperCf.addColumn(new Column(CompositeType.build(SC, bb("bbbb")), bb("bbbbb-value"))); SuperCf.addColumn(new Column(CompositeType.build(SC, bb("cccc")), bb("ccccc-value"), 1000L)); SuperCf.addColumn(new DeletedColumn(CompositeType.build(SC, bb("dddd")), 500, 1000)); SuperCf.addColumn( new DeletedColumn(CompositeType.build(SC, bb("eeee")), bb("eeee-value"), 1001)); SuperCf.addColumn( new ExpiringColumn(CompositeType.build(SC, bb("ffff")), bb("ffff-value"), 2000, 1000)); SuperCf.addColumn( new ExpiringColumn( CompositeType.build(SC, bb("gggg")), bb("gggg-value"), 2001, 1000, 2002)); } } }
{ add(CompositeType.build(SC, ByteBufferUtil.bytes("AAA"))); add(CompositeType.build(SC, ByteBufferUtil.bytes("BBB"))); add(CompositeType.build(SC, ByteBufferUtil.bytes("CCC"))); }