Provide a per-table text->blob map for storing extra metadata

patch by Benjamin Lerer; reviewed by Aleksey Yeschenko for CASSANDRA-9426
This commit is contained in:
blerer 2015-08-14 18:04:34 +02:00
parent 1288427669
commit 507ed14840
4 changed files with 103 additions and 27 deletions

View File

@ -200,6 +200,12 @@ public final class CFMetaData
return this;
}
public CFMetaData extensions(Map<String, ByteBuffer> extensions)
{
params = TableParams.builder(params).extensions(extensions).build();
return this;
}
public CFMetaData droppedColumns(Map<ByteBuffer, DroppedColumn> cols)
{
droppedColumns = cols;

View File

@ -99,6 +99,7 @@ public final class SchemaKeyspace
+ "compression map<text, text>,"
+ "dclocal_read_repair_chance double,"
+ "default_time_to_live int,"
+ "extensions map<text, blob>,"
+ "flags set<text>," // SUPER, COUNTER, DENSE, COMPOUND
+ "gc_grace_seconds int,"
+ "id uuid,"
@ -852,7 +853,8 @@ public final class SchemaKeyspace
.add("speculative_retry", params.speculativeRetry.toString())
.map("caching", params.caching.asMap())
.map("compaction", params.compaction.asMap())
.map("compression", params.compression.asMap());
.map("compression", params.compression.asMap())
.map("extensions", params.extensions);
}
public static Mutation makeUpdateTableMutation(KeyspaceMetadata keyspace,
@ -1071,21 +1073,26 @@ public final class SchemaKeyspace
private static TableParams createTableParamsFromRow(UntypedResultSet.Row row)
{
return TableParams.builder()
.bloomFilterFpChance(row.getDouble("bloom_filter_fp_chance"))
.caching(CachingParams.fromMap(row.getTextMap("caching")))
.comment(row.getString("comment"))
.compaction(CompactionParams.fromMap(row.getTextMap("compaction")))
.compression(CompressionParams.fromMap(row.getTextMap("compression")))
.dcLocalReadRepairChance(row.getDouble("dclocal_read_repair_chance"))
.defaultTimeToLive(row.getInt("default_time_to_live"))
.gcGraceSeconds(row.getInt("gc_grace_seconds"))
.maxIndexInterval(row.getInt("max_index_interval"))
.memtableFlushPeriodInMs(row.getInt("memtable_flush_period_in_ms"))
.minIndexInterval(row.getInt("min_index_interval"))
.readRepairChance(row.getDouble("read_repair_chance"))
.speculativeRetry(SpeculativeRetryParam.fromString(row.getString("speculative_retry")))
.build();
TableParams.Builder builder = TableParams.builder();
builder.bloomFilterFpChance(row.getDouble("bloom_filter_fp_chance"))
.caching(CachingParams.fromMap(row.getTextMap("caching")))
.comment(row.getString("comment"))
.compaction(CompactionParams.fromMap(row.getTextMap("compaction")))
.compression(CompressionParams.fromMap(row.getTextMap("compression")))
.dcLocalReadRepairChance(row.getDouble("dclocal_read_repair_chance"))
.defaultTimeToLive(row.getInt("default_time_to_live"))
.gcGraceSeconds(row.getInt("gc_grace_seconds"))
.maxIndexInterval(row.getInt("max_index_interval"))
.memtableFlushPeriodInMs(row.getInt("memtable_flush_period_in_ms"))
.minIndexInterval(row.getInt("min_index_interval"))
.readRepairChance(row.getDouble("read_repair_chance"))
.speculativeRetry(SpeculativeRetryParam.fromString(row.getString("speculative_retry")));
if (row.has("extensions"))
builder.extensions(row.getMap("extensions", UTF8Type.instance, BytesType.instance));
return builder.build();
}
/*

View File

@ -17,11 +17,14 @@
*/
package org.apache.cassandra.schema;
import java.nio.ByteBuffer;
import java.util.Map;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableMap;
import org.apache.cassandra.exceptions.ConfigurationException;
import static java.lang.String.format;
public final class TableParams
@ -37,6 +40,7 @@ public final class TableParams
COMPRESSION,
DCLOCAL_READ_REPAIR_CHANCE,
DEFAULT_TIME_TO_LIVE,
EXTENSIONS,
GC_GRACE_SECONDS,
MAX_INDEX_INTERVAL,
MEMTABLE_FLUSH_PERIOD_IN_MS,
@ -73,6 +77,7 @@ public final class TableParams
public final CachingParams caching;
public final CompactionParams compaction;
public final CompressionParams compression;
public final ImmutableMap<String, ByteBuffer> extensions;
private TableParams(Builder builder)
{
@ -91,6 +96,7 @@ public final class TableParams
caching = builder.caching;
compaction = builder.compaction;
compression = builder.compression;
extensions = builder.extensions;
}
public static Builder builder()
@ -112,7 +118,8 @@ public final class TableParams
.memtableFlushPeriodInMs(params.memtableFlushPeriodInMs)
.minIndexInterval(params.minIndexInterval)
.readRepairChance(params.readRepairChance)
.speculativeRetry(params.speculativeRetry);
.speculativeRetry(params.speculativeRetry)
.extensions(params.extensions);
}
public void validate()
@ -191,7 +198,8 @@ public final class TableParams
&& speculativeRetry.equals(p.speculativeRetry)
&& caching.equals(p.caching)
&& compaction.equals(p.compaction)
&& compression.equals(p.compression);
&& compression.equals(p.compression)
&& extensions.equals(p.extensions);
}
@Override
@ -209,7 +217,8 @@ public final class TableParams
speculativeRetry,
caching,
compaction,
compression);
compression,
extensions);
}
@Override
@ -229,6 +238,7 @@ public final class TableParams
.add(Option.CACHING.toString(), caching)
.add(Option.COMPACTION.toString(), compaction)
.add(Option.COMPRESSION.toString(), compression)
.add(Option.EXTENSIONS.toString(), extensions)
.toString();
}
@ -247,6 +257,7 @@ public final class TableParams
private CachingParams caching = CachingParams.DEFAULT;
private CompactionParams compaction = CompactionParams.DEFAULT;
private CompressionParams compression = CompressionParams.DEFAULT;
private ImmutableMap<String, ByteBuffer> extensions = ImmutableMap.of();
public Builder()
{
@ -334,5 +345,11 @@ public final class TableParams
compression = val;
return this;
}
public Builder extensions(Map<String, ByteBuffer> val)
{
extensions = ImmutableMap.copyOf(val);
return this;
}
}
}

View File

@ -18,18 +18,29 @@
*/
package org.apache.cassandra.schema;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import com.google.common.collect.ImmutableMap;
import org.junit.BeforeClass;
import org.junit.Test;
import org.apache.cassandra.SchemaLoader;
import org.apache.cassandra.config.CFMetaData;
import org.apache.cassandra.config.Schema;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.rows.UnfilteredRowIterators;
import org.apache.cassandra.db.partitions.PartitionUpdate;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.Mutation;
import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.db.marshal.AsciiType;
import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.db.partitions.PartitionUpdate;
import org.apache.cassandra.db.rows.UnfilteredRowIterators;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.thrift.CfDef;
import org.apache.cassandra.thrift.ColumnDef;
@ -38,10 +49,8 @@ import org.apache.cassandra.thrift.ThriftConversion;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class SchemaKeyspaceTest
{
@ -128,6 +137,43 @@ public class SchemaKeyspaceTest
}
}
@Test
public void testExtensions() throws IOException
{
String keyspace = "SandBox";
createTable(keyspace, "CREATE TABLE test (a text primary key, b int, c int)");
CFMetaData metadata = Schema.instance.getCFMetaData(keyspace, "test");
assertTrue("extensions should be empty", metadata.params.extensions.isEmpty());
ImmutableMap<String, ByteBuffer> extensions = ImmutableMap.of("From ... with Love",
ByteBuffer.wrap(new byte[]{0, 0, 7}));
CFMetaData copy = metadata.copy().extensions(extensions);
updateTable(keyspace, metadata, copy);
metadata = Schema.instance.getCFMetaData(keyspace, "test");
assertEquals(extensions, metadata.params.extensions);
}
private static void updateTable(String keyspace, CFMetaData oldTable, CFMetaData newTable) throws IOException
{
KeyspaceMetadata ksm = Schema.instance.getKeyspaceInstance(keyspace).getMetadata();
Mutation mutation = SchemaKeyspace.makeUpdateTableMutation(ksm, oldTable, newTable, FBUtilities.timestampMicros(), false);
SchemaKeyspace.mergeSchema(Collections.singleton(mutation), true);
}
private static void createTable(String keyspace, String cql) throws IOException
{
CFMetaData table = CFMetaData.compile(cql, keyspace);
KeyspaceMetadata ksm = KeyspaceMetadata.create(keyspace, KeyspaceParams.simple(1), Tables.of(table));
Mutation mutation = SchemaKeyspace.makeCreateTableMutation(ksm, table, FBUtilities.timestampMicros());
SchemaKeyspace.mergeSchema(Collections.singleton(mutation), true);
}
private static void checkInverses(CFMetaData cfm) throws Exception
{
KeyspaceMetadata keyspace = Schema.instance.getKSMetaData(cfm.ksName);