Updated Branches: refs/heads/trunk 2deee7a4e -> f0c0224da
merge from 1.0 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/f0c0224d Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/f0c0224d Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/f0c0224d Branch: refs/heads/trunk Commit: f0c0224dac44946c6b2f124259999ba9df20fccc Parents: 2deee7a f4064b5 Author: Pavel Yaskevich <[email protected]> Authored: Mon Jan 30 19:20:39 2012 +0200 Committer: Pavel Yaskevich <[email protected]> Committed: Mon Jan 30 19:20:39 2012 +0200 ---------------------------------------------------------------------- src/java/org/apache/cassandra/cql/CFPropDefs.java | 13 +++++++++++++ .../cassandra/cql/CreateColumnFamilyStatement.java | 5 +---- 2 files changed, 14 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c0224d/src/java/org/apache/cassandra/cql/CFPropDefs.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/cql/CFPropDefs.java index 5103b24,0000000..930494a mode 100644,000000..100644 --- a/src/java/org/apache/cassandra/cql/CFPropDefs.java +++ b/src/java/org/apache/cassandra/cql/CFPropDefs.java @@@ -1,268 -1,0 +1,281 @@@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ + +package org.apache.cassandra.cql; + +import com.google.common.collect.Sets; +import org.apache.cassandra.config.CFMetaData; +import org.apache.cassandra.config.ConfigurationException; ++import org.apache.cassandra.db.compaction.AbstractCompactionStrategy; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.TypeParser; +import org.apache.cassandra.thrift.InvalidRequestException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class CFPropDefs { + private static Logger logger = LoggerFactory.getLogger(CFPropDefs.class); + + public static final String KW_COMPARATOR = "comparator"; + public static final String KW_COMMENT = "comment"; + public static final String KW_READREPAIRCHANCE = "read_repair_chance"; + public static final String KW_GCGRACESECONDS = "gc_grace_seconds"; + public static final String KW_DEFAULTVALIDATION = "default_validation"; + public static final String KW_MINCOMPACTIONTHRESHOLD = "min_compaction_threshold"; + public static final String KW_MAXCOMPACTIONTHRESHOLD = "max_compaction_threshold"; + public static final String KW_REPLICATEONWRITE = "replicate_on_write"; + + public static final String KW_COMPACTION_STRATEGY_CLASS = "compaction_strategy_class"; + + // Maps CQL short names to the respective Cassandra comparator/validator class names + public static final Map<String, String> comparators = new HashMap<String, String>(); + public static final Set<String> keywords = new HashSet<String>(); + public static final Set<String> obsoleteKeywords = new HashSet<String>(); + public static final Set<String> allowedKeywords = new HashSet<String>(); + + public static final String COMPACTION_OPTIONS_PREFIX = "compaction_strategy_options"; + public static final String COMPRESSION_PARAMETERS_PREFIX = "compression_parameters"; + + static + { + comparators.put("ascii", "AsciiType"); + comparators.put("bigint", "LongType"); + comparators.put("blob", "BytesType"); + comparators.put("boolean", "BooleanType"); + comparators.put("counter", "CounterColumnType"); + comparators.put("decimal", "DecimalType"); + comparators.put("double", "DoubleType"); + comparators.put("float", "FloatType"); + comparators.put("int", "Int32Type"); + comparators.put("text", "UTF8Type"); + comparators.put("timestamp", "DateType"); + comparators.put("uuid", "UUIDType"); + comparators.put("varchar", "UTF8Type"); + comparators.put("varint", "IntegerType"); + + keywords.add(KW_COMPARATOR); + keywords.add(KW_COMMENT); + keywords.add(KW_READREPAIRCHANCE); + keywords.add(KW_GCGRACESECONDS); + keywords.add(KW_DEFAULTVALIDATION); + keywords.add(KW_MINCOMPACTIONTHRESHOLD); + keywords.add(KW_MAXCOMPACTIONTHRESHOLD); + keywords.add(KW_REPLICATEONWRITE); + keywords.add(KW_COMPACTION_STRATEGY_CLASS); + + obsoleteKeywords.add("row_cache_size"); + obsoleteKeywords.add("key_cache_size"); + obsoleteKeywords.add("row_cache_save_period_in_seconds"); + obsoleteKeywords.add("key_cache_save_period_in_seconds"); + obsoleteKeywords.add("memtable_throughput_in_mb"); + obsoleteKeywords.add("memtable_operations_in_millions"); + obsoleteKeywords.add("memtable_flush_after_mins"); + obsoleteKeywords.add("row_cache_provider"); + + allowedKeywords.addAll(keywords); + allowedKeywords.addAll(obsoleteKeywords); + } + + public final Map<String, String> properties = new HashMap<String, String>(); ++ public Class<? extends AbstractCompactionStrategy> compactionStrategyClass; + public final Map<String, String> compactionStrategyOptions = new HashMap<String, String>(); + public final Map<String, String> compressionParameters = new HashMap<String, String>(); + + public void validate() throws InvalidRequestException + { ++ String compStrategy = getPropertyString(KW_COMPACTION_STRATEGY_CLASS, CFMetaData.DEFAULT_COMPACTION_STRATEGY_CLASS); ++ ++ try ++ { ++ compactionStrategyClass = CFMetaData.createCompactionStrategy(compStrategy); ++ } ++ catch (ConfigurationException e) ++ { ++ throw new InvalidRequestException(e.getMessage()); ++ } ++ + // we need to remove parent:key = value pairs from the main properties + Set<String> propsToRemove = new HashSet<String>(); + + // check if we have compaction/compression options + for (String property : properties.keySet()) + { + if (!property.contains(":")) + continue; + + String key = property.split(":")[1]; + String val = properties.get(property); + + if (property.startsWith(COMPACTION_OPTIONS_PREFIX)) + { + compactionStrategyOptions.put(key, val); + propsToRemove.add(property); + } + + if (property.startsWith(COMPRESSION_PARAMETERS_PREFIX)) + { + compressionParameters.put(key, val); + propsToRemove.add(property); + } + } + + for (String property : propsToRemove) + properties.remove(property); + // Catch the case where someone passed a kwarg that is not recognized. + for (String bogus : Sets.difference(properties.keySet(), allowedKeywords)) + throw new InvalidRequestException(bogus + " is not a valid keyword argument for CREATE COLUMNFAMILY"); + for (String obsolete : Sets.intersection(properties.keySet(), obsoleteKeywords)) + logger.warn("Ignoring obsolete property {}", obsolete); + + // Validate min/max compaction thresholds + Integer minCompaction = getPropertyInt(KW_MINCOMPACTIONTHRESHOLD, null); + Integer maxCompaction = getPropertyInt(KW_MAXCOMPACTIONTHRESHOLD, null); + + if ((minCompaction != null) && (maxCompaction != null)) // Both min and max are set + { + if ((minCompaction > maxCompaction) && (maxCompaction != 0)) + throw new InvalidRequestException(String.format("%s cannot be larger than %s", + KW_MINCOMPACTIONTHRESHOLD, + KW_MAXCOMPACTIONTHRESHOLD)); + } + else if (minCompaction != null) // Only the min threshold is set + { + if (minCompaction > CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD) + throw new InvalidRequestException(String.format("%s cannot be larger than %s, (default %s)", + KW_MINCOMPACTIONTHRESHOLD, + KW_MAXCOMPACTIONTHRESHOLD, + CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD)); + } + else if (maxCompaction != null) // Only the max threshold is set + { + if ((maxCompaction < CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD) && (maxCompaction != 0)) + throw new InvalidRequestException(String.format("%s cannot be smaller than %s, (default %s)", + KW_MAXCOMPACTIONTHRESHOLD, + KW_MINCOMPACTIONTHRESHOLD, + CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD)); + } + } + + /** Map a keyword to the corresponding value */ + public void addProperty(String name, String value) + { + properties.put(name, value); + } + + public Boolean hasProperty(String name) + { + return properties.containsKey(name); + } + + /* If not comparator/validator is not specified, default to text (BytesType is the wrong default for CQL + * since it uses hex terms). If the value specified is not found in the comparators map, assume the user + * knows what they are doing (a custom comparator/validator for example), and pass it on as-is. + */ + + public AbstractType<?> getComparator() throws ConfigurationException + { + return TypeParser.parse((comparators.get(getPropertyString(KW_COMPARATOR, "text")) != null) + ? comparators.get(getPropertyString(KW_COMPARATOR, "text")) + : getPropertyString(KW_COMPARATOR, "text")); + } + + public AbstractType<?> getValidator() throws ConfigurationException + { + return TypeParser.parse((comparators.get(getPropertyString(KW_DEFAULTVALIDATION, "text")) != null) + ? comparators.get(getPropertyString(KW_DEFAULTVALIDATION, "text")) + : getPropertyString(KW_DEFAULTVALIDATION, "text")); + } + + public String getProperty(String name) + { + return properties.get(name); + } + + public String getPropertyString(String key, String defaultValue) + { + String value = properties.get(key); + return value != null ? value : defaultValue; + } + + // Return a property value, typed as a Boolean + public Boolean getPropertyBoolean(String key, Boolean defaultValue) throws InvalidRequestException + { + String value = properties.get(key); + return (value == null) ? defaultValue : value.toLowerCase().matches("(1|true|yes)"); + } + + // Return a property value, typed as a Double + public Double getPropertyDouble(String key, Double defaultValue) throws InvalidRequestException + { + Double result; + String value = properties.get(key); + + if (value == null) + result = defaultValue; + else + { + try + { + result = Double.parseDouble(value); + } + catch (NumberFormatException e) + { + throw new InvalidRequestException(String.format("%s not valid for \"%s\"", value, key)); + } + } + return result; + } + + // Return a property value, typed as an Integer + public Integer getPropertyInt(String key, Integer defaultValue) throws InvalidRequestException + { + Integer result; + String value = properties.get(key); + + if (value == null) + result = defaultValue; + else + { + try + { + result = Integer.parseInt(value); + } + catch (NumberFormatException e) + { + throw new InvalidRequestException(String.format("%s not valid for \"%s\"", value, key)); + } + } + return result; + } + + public String toString() + { + return String.format("CFPropDefs(%s, compaction: %s, compression: %s)", + properties.toString(), + compactionStrategyOptions.toString(), + compressionParameters.toString()); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/f0c0224d/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java ---------------------------------------------------------------------- diff --cc src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java index 93b8331,c0568b9..960cc9d --- a/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java +++ b/src/java/org/apache/cassandra/cql/CreateColumnFamilyStatement.java @@@ -23,12 -23,15 +23,8 @@@ package org.apache.cassandra.cql import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; --import java.util.HashSet; import java.util.List; import java.util.Map; --import java.util.Set; -- --import com.google.common.collect.Sets; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ColumnDefinition; @@@ -179,19 -335,25 +175,20 @@@ public class CreateColumnFamilyStatemen comparator, null); - newCFMD.comment(properties.get(KW_COMMENT)) - .rowCacheSize(getPropertyDouble(KW_ROWCACHESIZE, CFMetaData.DEFAULT_ROW_CACHE_SIZE)) - .keyCacheSize(getPropertyDouble(KW_KEYCACHESIZE, CFMetaData.DEFAULT_KEY_CACHE_SIZE)) - .readRepairChance(getPropertyDouble(KW_READREPAIRCHANCE, CFMetaData.DEFAULT_READ_REPAIR_CHANCE)) - .replicateOnWrite(getPropertyBoolean(KW_REPLICATEONWRITE, CFMetaData.DEFAULT_REPLICATE_ON_WRITE)) - .gcGraceSeconds(getPropertyInt(KW_GCGRACESECONDS, CFMetaData.DEFAULT_GC_GRACE_SECONDS)) - .defaultValidator(getValidator()) - .minCompactionThreshold(getPropertyInt(KW_MINCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD)) - .maxCompactionThreshold(getPropertyInt(KW_MAXCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD)) - .rowCacheSavePeriod(getPropertyInt(KW_ROWCACHESAVEPERIODSECS, CFMetaData.DEFAULT_ROW_CACHE_SAVE_PERIOD_IN_SECONDS)) - .keyCacheSavePeriod(getPropertyInt(KW_KEYCACHESAVEPERIODSECS, CFMetaData.DEFAULT_KEY_CACHE_SAVE_PERIOD_IN_SECONDS)) + newCFMD.comment(cfProps.getProperty(CFPropDefs.KW_COMMENT)) + .readRepairChance(getPropertyDouble(CFPropDefs.KW_READREPAIRCHANCE, CFMetaData.DEFAULT_READ_REPAIR_CHANCE)) + .replicateOnWrite(getPropertyBoolean(CFPropDefs.KW_REPLICATEONWRITE, CFMetaData.DEFAULT_REPLICATE_ON_WRITE)) + .gcGraceSeconds(getPropertyInt(CFPropDefs.KW_GCGRACESECONDS, CFMetaData.DEFAULT_GC_GRACE_SECONDS)) + .defaultValidator(cfProps.getValidator()) + .minCompactionThreshold(getPropertyInt(CFPropDefs.KW_MINCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD)) + .maxCompactionThreshold(getPropertyInt(CFPropDefs.KW_MAXCOMPACTIONTHRESHOLD, CFMetaData.DEFAULT_MAX_COMPACTION_THRESHOLD)) .mergeShardsChance(0.0) .columnMetadata(getColumns(comparator)) - .keyValidator(TypeParser.parse(comparators.get(getKeyType()))) - .rowCacheProvider(FBUtilities.newCacheProvider(getPropertyString(KW_ROW_CACHE_PROVIDER, CFMetaData.DEFAULT_ROW_CACHE_PROVIDER.getClass().getName()))) + .keyValidator(TypeParser.parse(CFPropDefs.comparators.get(getKeyType()))) .keyAlias(keyAlias) - .compactionStrategyClass(compactionStrategyClass) - .compactionStrategyOptions(compactionStrategyOptions) - .compressionParameters(CompressionParameters.create(compressionParameters)) ++ .compactionStrategyClass(cfProps.compactionStrategyClass) + .compactionStrategyOptions(cfProps.compactionStrategyOptions) + .compressionParameters(CompressionParameters.create(cfProps.compressionParameters)) .validate(); } catch (ConfigurationException e)
