diff --git a/include/cassandra.h b/include/cassandra.h index ec32d3ae3..9ae31d6b4 100644 --- a/include/cassandra.h +++ b/include/cassandra.h @@ -478,7 +478,7 @@ typedef enum CassConsistency_ { CASS_CONSISTENCY_LOCAL_ONE = 0x000A } CassConsistency; -#define CASS_CONSISTENCY_MAP(XX) \ +#define CASS_CONSISTENCY_MAPPING(XX) \ XX(CASS_CONSISTENCY_UNKNOWN, "UNKNOWN") \ XX(CASS_CONSISTENCY_ANY, "ANY") \ XX(CASS_CONSISTENCY_ONE, "ONE") \ @@ -492,6 +492,8 @@ typedef enum CassConsistency_ { XX(CASS_CONSISTENCY_LOCAL_SERIAL, "LOCAL_SERIAL") \ XX(CASS_CONSISTENCY_LOCAL_ONE, "LOCAL_ONE") +#define CASS_CONSISTENCY_MAP CASS_CONSISTENCY_MAPPING /* Deprecated */ + typedef enum CassWriteType_ { CASS_WRITE_TYPE_UKNOWN, CASS_WRITE_TYPE_SIMPLE, @@ -502,7 +504,7 @@ typedef enum CassWriteType_ { CASS_WRITE_TYPE_CAS } CassWriteType; -#define CASS_WRITE_TYPE_MAP(XX) \ +#define CASS_WRITE_TYPE_MAPPING(XX) \ XX(CASS_WRITE_TYPE_SIMPLE, "SIMPLE") \ XX(CASS_WRITE_TYPE_BATCH, "BATCH") \ XX(CASS_WRITE_TYPE_UNLOGGED_BATCH, "UNLOGGED_BATCH") \ @@ -510,6 +512,8 @@ typedef enum CassWriteType_ { XX(CASS_WRITE_TYPE_BATCH_LOG, "BATCH_LOG") \ XX(CASS_WRITE_TYPE_CAS, "CAS") +#define CASS_WRITE_TYPE_MAP CASS_WRITE_TYPE_MAPPING /* Deprecated */ + typedef enum CassColumnType_ { CASS_COLUMN_TYPE_REGULAR, CASS_COLUMN_TYPE_PARTITION_KEY, @@ -525,35 +529,40 @@ typedef enum CassIndexType_ { CASS_INDEX_TYPE_COMPOSITES } CassIndexType; +#define CASS_VALUE_TYPE_MAPPING(XX) \ + XX(CASS_VALUE_TYPE_CUSTOM, 0x0000, "", "") \ + XX(CASS_VALUE_TYPE_ASCII, 0x0001, "ascii", "org.apache.cassandra.db.marshal.AsciiType") \ + XX(CASS_VALUE_TYPE_BIGINT, 0x0002, "bigint", "org.apache.cassandra.db.marshal.LongType") \ + XX(CASS_VALUE_TYPE_BLOB, 0x0003, "blob", "org.apache.cassandra.db.marshal.BytesType") \ + XX(CASS_VALUE_TYPE_BOOLEAN, 0x0004, "boolean", "org.apache.cassandra.db.marshal.BooleanType") \ + XX(CASS_VALUE_TYPE_COUNTER, 0x0005, "counter", "org.apache.cassandra.db.marshal.CounterColumnType") \ + XX(CASS_VALUE_TYPE_DECIMAL, 0x0006, "decimal", "org.apache.cassandra.db.marshal.DecimalType") \ + XX(CASS_VALUE_TYPE_DOUBLE, 0x0007, "double", "org.apache.cassandra.db.marshal.DoubleType") \ + XX(CASS_VALUE_TYPE_FLOAT, 0x0008, "float", "org.apache.cassandra.db.marshal.FloatType") \ + XX(CASS_VALUE_TYPE_INT, 0x0009, "int", "org.apache.cassandra.db.marshal.Int32Type") \ + XX(CASS_VALUE_TYPE_TEXT, 0x000A, "text", "org.apache.cassandra.db.marshal.UTF8Type") \ + XX(CASS_VALUE_TYPE_TIMESTAMP, 0x000B, "timestamp", "org.apache.cassandra.db.marshal.TimestampType") \ + XX(CASS_VALUE_TYPE_UUID, 0x000C, "uuid", "org.apache.cassandra.db.marshal.UUIDType") \ + XX(CASS_VALUE_TYPE_VARCHAR, 0x000D, "varchar", "") \ + XX(CASS_VALUE_TYPE_VARINT, 0x000E, "varint", "org.apache.cassandra.db.marshal.IntegerType") \ + XX(CASS_VALUE_TYPE_TIMEUUID, 0x000F, "timeuuid", "org.apache.cassandra.db.marshal.TimeUUIDType") \ + XX(CASS_VALUE_TYPE_INET, 0x0010, "inet", "org.apache.cassandra.db.marshal.InetAddressType") \ + XX(CASS_VALUE_TYPE_DATE, 0x0011, "date", "org.apache.cassandra.db.marshal.SimpleDateType") \ + XX(CASS_VALUE_TYPE_TIME, 0x0012, "time", "org.apache.cassandra.db.marshal.TimeType") \ + XX(CASS_VALUE_TYPE_SMALL_INT, 0x0013, "smallint", "org.apache.cassandra.db.marshal.ShortType") \ + XX(CASS_VALUE_TYPE_TINY_INT, 0x0014, "tinyint", "org.apache.cassandra.db.marshal.ByteType") \ + XX(CASS_VALUE_TYPE_DURATION, 0x0015, "duration", "org.apache.cassandra.db.marshal.DurationType") \ + XX(CASS_VALUE_TYPE_LIST, 0x0020, "list", "org.apache.cassandra.db.marshal.ListType") \ + XX(CASS_VALUE_TYPE_MAP, 0x0021, "map", "org.apache.cassandra.db.marshal.MapType") \ + XX(CASS_VALUE_TYPE_SET, 0x0022, "set", "org.apache.cassandra.db.marshal.SetType") \ + XX(CASS_VALUE_TYPE_UDT, 0x0030, "", "") \ + XX(CASS_VALUE_TYPE_TUPLE, 0x0031, "tuple", "org.apache.cassandra.db.marshal.TupleType") + typedef enum CassValueType_ { - CASS_VALUE_TYPE_UNKNOWN = 0xFFFF, - CASS_VALUE_TYPE_CUSTOM = 0x0000, - CASS_VALUE_TYPE_ASCII = 0x0001, - CASS_VALUE_TYPE_BIGINT = 0x0002, - CASS_VALUE_TYPE_BLOB = 0x0003, - CASS_VALUE_TYPE_BOOLEAN = 0x0004, - CASS_VALUE_TYPE_COUNTER = 0x0005, - CASS_VALUE_TYPE_DECIMAL = 0x0006, - CASS_VALUE_TYPE_DOUBLE = 0x0007, - CASS_VALUE_TYPE_FLOAT = 0x0008, - CASS_VALUE_TYPE_INT = 0x0009, - CASS_VALUE_TYPE_TEXT = 0x000A, - CASS_VALUE_TYPE_TIMESTAMP = 0x000B, - CASS_VALUE_TYPE_UUID = 0x000C, - CASS_VALUE_TYPE_VARCHAR = 0x000D, - CASS_VALUE_TYPE_VARINT = 0x000E, - CASS_VALUE_TYPE_TIMEUUID = 0x000F, - CASS_VALUE_TYPE_INET = 0x0010, - CASS_VALUE_TYPE_DATE = 0x0011, - CASS_VALUE_TYPE_TIME = 0x0012, - CASS_VALUE_TYPE_SMALL_INT = 0x0013, - CASS_VALUE_TYPE_TINY_INT = 0x0014, - CASS_VALUE_TYPE_DURATION = 0x0015, - CASS_VALUE_TYPE_LIST = 0x0020, - CASS_VALUE_TYPE_MAP = 0x0021, - CASS_VALUE_TYPE_SET = 0x0022, - CASS_VALUE_TYPE_UDT = 0x0030, - CASS_VALUE_TYPE_TUPLE = 0x0031, + CASS_VALUE_TYPE_UNKNOWN = 0xFFFF, +#define XX_VALUE_TYPE(name, type, cql, klass) name = type, + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE /* @cond IGNORE */ CASS_VALUE_TYPE_LAST_ENTRY /* @endcond */ @@ -595,7 +604,7 @@ typedef enum CassIteratorType_ { CASS_ITERATOR_TYPE_MATERIALIZED_VIEW_META } CassIteratorType; -#define CASS_LOG_LEVEL_MAP(XX) \ +#define CASS_LOG_LEVEL_MAPPING(XX) \ XX(CASS_LOG_DISABLED, "") \ XX(CASS_LOG_CRITICAL, "CRITICAL") \ XX(CASS_LOG_ERROR, "ERROR") \ @@ -604,9 +613,11 @@ typedef enum CassIteratorType_ { XX(CASS_LOG_DEBUG, "DEBUG") \ XX(CASS_LOG_TRACE, "TRACE") +#define CASS_LOG_LEVEL_MAP CASS_LOG_LEVEL_MAPPING /* Deprecated */ + typedef enum CassLogLevel_ { #define XX_LOG(log_level, _) log_level, - CASS_LOG_LEVEL_MAP(XX_LOG) + CASS_LOG_LEVEL_MAPPING(XX_LOG) #undef XX_LOG /* @cond IGNORE */ CASS_LOG_LAST_ENTRY @@ -628,7 +639,7 @@ typedef enum CassErrorSource_ { CASS_ERROR_SOURCE_COMPRESSION } CassErrorSource; -#define CASS_ERROR_MAP(XX) \ +#define CASS_ERROR_MAPPING(XX) \ XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_BAD_PARAMS, 1, "Bad parameters") \ XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_NO_STREAMS, 2, "No streams available") \ XX(CASS_ERROR_SOURCE_LIB, CASS_ERROR_LIB_UNABLE_TO_INIT, 3, "Unable to initialize") \ @@ -687,12 +698,14 @@ typedef enum CassErrorSource_ { XX(CASS_ERROR_SOURCE_SSL, CASS_ERROR_SSL_IDENTITY_MISMATCH, 5, "Certificate does not match host or IP address") \ XX(CASS_ERROR_SOURCE_SSL, CASS_ERROR_SSL_PROTOCOL_ERROR, 6, "Protocol error") +#define CASS_ERROR_MAP CASS_ERROR_MAPPING /* Deprecated */ + #define CASS_ERROR(source, code) ((source << 24) | code) typedef enum CassError_ { CASS_OK = 0, #define XX_ERROR(source, name, code, _) name = CASS_ERROR(source, code), - CASS_ERROR_MAP(XX_ERROR) + CASS_ERROR_MAPPING(XX_ERROR) #undef XX_ERROR /* @cond IGNORE */ CASS_ERROR_LAST_ENTRY diff --git a/src/connection.cpp b/src/connection.cpp index 83f3fd70d..083fa7087 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -1132,7 +1132,7 @@ void Connection::PendingWriteSsl::flush() { encrypt(); - FixedVector bufs; + SmallVector bufs; encrypted_size_ = ssl_session->outgoing().peek_multiple(prev_pos, &bufs); LOG_TRACE("Sending %u encrypted bytes", static_cast(encrypted_size_)); diff --git a/src/data_type.cpp b/src/data_type.cpp index 007f1dfa9..03e642f69 100644 --- a/src/data_type.cpp +++ b/src/data_type.cpp @@ -20,6 +20,7 @@ #include "external.hpp" #include "tuple.hpp" #include "types.hpp" +#include "utils.hpp" #include "user_type_value.hpp" #include @@ -383,68 +384,73 @@ namespace cass { const DataType::ConstPtr DataType::NIL; -void NativeDataTypes::init_class_names() { - if (!by_class_names_.empty()) return; - by_class_names_["org.apache.cassandra.db.marshal.AsciiType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_ASCII)); - by_class_names_["org.apache.cassandra.db.marshal.BooleanType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_BOOLEAN)); - by_class_names_["org.apache.cassandra.db.marshal.ByteType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TINY_INT)); - by_class_names_["org.apache.cassandra.db.marshal.BytesType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_BLOB)); - by_class_names_["org.apache.cassandra.db.marshal.CounterColumnType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_COUNTER)); - by_class_names_["org.apache.cassandra.db.marshal.DateType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIMESTAMP)); - by_class_names_["org.apache.cassandra.db.marshal.DecimalType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DECIMAL)); - by_class_names_["org.apache.cassandra.db.marshal.DoubleType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DOUBLE)); - by_class_names_["org.apache.cassandra.db.marshal.DurationType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DURATION)); - by_class_names_["org.apache.cassandra.db.marshal.FloatType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_FLOAT)); - by_class_names_["org.apache.cassandra.db.marshal.InetAddressType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_INET)); - by_class_names_["org.apache.cassandra.db.marshal.Int32Type"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_INT)); - by_class_names_["org.apache.cassandra.db.marshal.IntegerType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_VARINT)); - by_class_names_["org.apache.cassandra.db.marshal.LongType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_BIGINT)); - by_class_names_["org.apache.cassandra.db.marshal.ShortType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_SMALL_INT)); - by_class_names_["org.apache.cassandra.db.marshal.SimpleDateType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DATE)); - by_class_names_["org.apache.cassandra.db.marshal.TimeType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIME)); - by_class_names_["org.apache.cassandra.db.marshal.TimestampType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIMESTAMP)); - by_class_names_["org.apache.cassandra.db.marshal.TimeUUIDType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIMEUUID)); - by_class_names_["org.apache.cassandra.db.marshal.UTF8Type"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TEXT)); - by_class_names_["org.apache.cassandra.db.marshal.UUIDType"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_UUID)); -} - -const DataType::ConstPtr& NativeDataTypes::by_class_name(const std::string& name) const { - DataTypeMap::const_iterator i = by_class_names_.find(name); - if (i == by_class_names_.end()) return DataType::NIL; +DataType::ConstPtr DataType::create_by_class(StringRef name) { + CassValueType value_type = ValueTypes::by_class(name); + if (value_type == CASS_VALUE_TYPE_UNKNOWN) { + return DataType::NIL; + } + return ConstPtr(new DataType(value_type)); +} + +DataType::ConstPtr DataType::create_by_cql(StringRef name) { + CassValueType value_type = ValueTypes::by_cql(name); + if (value_type == CASS_VALUE_TYPE_UNKNOWN) { + return DataType::NIL; + } + return ConstPtr(new DataType(value_type)); +} + +ValueTypes::HashMap ValueTypes::value_types_by_class_; +ValueTypes::HashMap ValueTypes::value_types_by_cql_; + +static ValueTypes __value_types__; // Initializer + +ValueTypes::ValueTypes() { + value_types_by_class_.set_empty_key(""); + value_types_by_cql_.set_empty_key(""); + +#define XX_VALUE_TYPE(name, type, cql, klass) \ + if (strlen(klass) > 0) value_types_by_class_[klass] = name; \ + if (strlen(cql) > 0) value_types_by_cql_[cql] = name; + + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE +} + +CassValueType ValueTypes::by_class(StringRef name) { + HashMap::const_iterator i = value_types_by_class_.find(name); + if (i == value_types_by_class_.end()) { + return CASS_VALUE_TYPE_UNKNOWN; + } return i->second; } -void NativeDataTypes::init_cql_names() { - if (!by_cql_names_.empty()) return; - by_cql_names_["ascii"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_ASCII)); - by_cql_names_["bigint"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_BIGINT)); - by_cql_names_["blob"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_BLOB)); - by_cql_names_["boolean"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_BOOLEAN)); - by_cql_names_["counter"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_COUNTER)); - by_cql_names_["date"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DATE)); - by_cql_names_["decimal"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DECIMAL)); - by_cql_names_["double"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DOUBLE)); - by_cql_names_["duration"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_DURATION)); - by_cql_names_["float"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_FLOAT)); - by_cql_names_["inet"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_INET)); - by_cql_names_["int"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_INT)); - by_cql_names_["smallint"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_SMALL_INT)); - by_cql_names_["time"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIME)); - by_cql_names_["timestamp"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIMESTAMP)); - by_cql_names_["timeuuid"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TIMEUUID)); - by_cql_names_["tinyint"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TINY_INT)); - by_cql_names_["text"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_TEXT)); - by_cql_names_["uuid"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_UUID)); - by_cql_names_["varchar"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_VARCHAR)); - by_cql_names_["varint"] = DataType::ConstPtr(new DataType(CASS_VALUE_TYPE_VARINT)); -} - -const DataType::ConstPtr& NativeDataTypes::by_cql_name(const std::string& name) const { - DataTypeMap::const_iterator i = by_cql_names_.find(name); - if (i == by_cql_names_.end()) return DataType::NIL; +CassValueType ValueTypes::by_cql(StringRef name) { + HashMap::const_iterator i = value_types_by_cql_.find(name); + if (i == value_types_by_cql_.end()) { + return CASS_VALUE_TYPE_UNKNOWN; + } return i->second; } +const DataType::ConstPtr& SimpleDataTypeCache::by_value_type(uint16_t value_type) { + if (value_type == CASS_VALUE_TYPE_UNKNOWN || + value_type == CASS_VALUE_TYPE_CUSTOM || + value_type == CASS_VALUE_TYPE_LIST || + value_type == CASS_VALUE_TYPE_MAP || + value_type == CASS_VALUE_TYPE_SET || + value_type == CASS_VALUE_TYPE_UDT || + value_type == CASS_VALUE_TYPE_TUPLE || + value_type >= CASS_VALUE_TYPE_LAST_ENTRY) { + return DataType::NIL; + } + DataType::ConstPtr& data_type = cache_[value_type]; + if (!data_type) { + data_type = DataType::ConstPtr( + new DataType(static_cast(value_type))); + } + return data_type; +} bool cass::IsValidDataType::operator()(const Collection* value, const DataType::ConstPtr& data_type) const { diff --git a/src/data_type.hpp b/src/data_type.hpp index 86444e26a..0d85be52c 100644 --- a/src/data_type.hpp +++ b/src/data_type.hpp @@ -22,6 +22,7 @@ #include "hash_table.hpp" #include "macros.hpp" #include "ref_counted.hpp" +#include "small_dense_hash_map.hpp" #include "types.hpp" #include @@ -72,7 +73,11 @@ class DataType : public RefCounted { static const DataType::ConstPtr NIL; - DataType(CassValueType value_type, bool is_frozen = false) + static ConstPtr create_by_class(StringRef name); + static ConstPtr create_by_cql(StringRef name); + + DataType(CassValueType value_type = CASS_VALUE_TYPE_UNKNOWN, + bool is_frozen = false) : value_type_(value_type) , is_frozen_(is_frozen) { } @@ -111,31 +116,9 @@ class DataType : public RefCounted { virtual std::string to_string() const { switch (value_type_) { - case CASS_VALUE_TYPE_ASCII: return "ascii"; - case CASS_VALUE_TYPE_BIGINT: return "bigint"; - case CASS_VALUE_TYPE_BLOB: return "blob"; - case CASS_VALUE_TYPE_BOOLEAN: return "boolean"; - case CASS_VALUE_TYPE_COUNTER: return "counter"; - case CASS_VALUE_TYPE_DECIMAL: return "decimal"; - case CASS_VALUE_TYPE_DOUBLE: return "double"; - case CASS_VALUE_TYPE_DURATION: return "duration"; - case CASS_VALUE_TYPE_FLOAT: return "float"; - case CASS_VALUE_TYPE_INT: return "int"; - case CASS_VALUE_TYPE_TEXT: return "text"; - case CASS_VALUE_TYPE_TIMESTAMP: return "timestamp"; - case CASS_VALUE_TYPE_UUID: return "uuid"; - case CASS_VALUE_TYPE_VARCHAR: return "varchar"; - case CASS_VALUE_TYPE_VARINT: return "varint"; - case CASS_VALUE_TYPE_TIMEUUID: return "timeuuid"; - case CASS_VALUE_TYPE_INET: return "inet"; - case CASS_VALUE_TYPE_DATE: return "date"; - case CASS_VALUE_TYPE_TIME: return "time"; - case CASS_VALUE_TYPE_SMALL_INT: return "smallint"; - case CASS_VALUE_TYPE_TINY_INT: return "tinyint"; - case CASS_VALUE_TYPE_LIST: return "list"; - case CASS_VALUE_TYPE_MAP: return "map"; - case CASS_VALUE_TYPE_SET: return "set"; - case CASS_VALUE_TYPE_TUPLE: return "tuple"; +#define XX_VALUE_TYPE(name, type, cql, klass) case name: return cql; + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE default: return ""; } } @@ -452,18 +435,37 @@ class UserType : public DataType { CaseInsensitiveHashTable fields_; }; -class NativeDataTypes { +class ValueTypes { public: - void init_class_names(); - const DataType::ConstPtr& by_class_name(const std::string& name) const; + ValueTypes(); + + static CassValueType by_class(StringRef name); + static CassValueType by_cql(StringRef name); + +private: + typedef SmallDenseHashMap HashMap; + + static HashMap value_types_by_class_; + static HashMap value_types_by_cql_; +}; + +class SimpleDataTypeCache { +public: + const DataType::ConstPtr& by_class(StringRef name) { + return by_value_type(ValueTypes::by_class(name)); + } + + const DataType::ConstPtr& by_cql(StringRef name) { + return by_value_type(ValueTypes::by_cql(name)); + } - void init_cql_names(); - const DataType::ConstPtr& by_cql_name(const std::string& name) const; + const DataType::ConstPtr& by_value_type(uint16_t value_type); private: - typedef std::map DataTypeMap; - DataTypeMap by_class_names_; - DataTypeMap by_cql_names_; + DataType::ConstPtr cache_[CASS_VALUE_TYPE_LAST_ENTRY]; }; template diff --git a/src/data_type_parser.cpp b/src/data_type_parser.cpp index bf380edaf..84fc59fbf 100644 --- a/src/data_type_parser.cpp +++ b/src/data_type_parser.cpp @@ -65,7 +65,7 @@ bool from_hex(const std::string& hex, std::string* result) { } DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, - const NativeDataTypes& native_types, + SimpleDataTypeCache& cache, KeyspaceMetadata* keyspace, bool is_frozen) { Parser parser(type, 0); @@ -75,9 +75,9 @@ DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, parser.parse_type_name(&type_name); std::transform(type_name.begin(), type_name.end(), type_name.begin(), tolower); - DataType::ConstPtr native_type(native_types.by_cql_name(type_name)); - if (native_type) { - return native_type; + DataType::ConstPtr simple_type(cache.by_cql(type_name)); + if (simple_type) { + return simple_type; } if (type_name == "list") { @@ -86,7 +86,7 @@ DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, LOG_ERROR("Expecting single parameter for list %s", type.c_str()); return DataType::NIL; } - DataType::ConstPtr element_type = parse(params[0], native_types, keyspace); + DataType::ConstPtr element_type = parse(params[0], cache, keyspace); return CollectionType::list(element_type, is_frozen); } @@ -96,7 +96,7 @@ DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, LOG_ERROR("Expecting single parameter for set %s", type.c_str()); return DataType::NIL; } - DataType::ConstPtr element_type = parse(params[0], native_types, keyspace); + DataType::ConstPtr element_type = parse(params[0], cache, keyspace); return CollectionType::set(element_type, is_frozen); } @@ -106,8 +106,8 @@ DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, LOG_ERROR("Expecting two parameters for set %s", type.c_str()); return DataType::NIL; } - DataType::ConstPtr key_type = parse(params[0], native_types, keyspace); - DataType::ConstPtr value_type = parse(params[1], native_types, keyspace); + DataType::ConstPtr key_type = parse(params[0], cache, keyspace); + DataType::ConstPtr value_type = parse(params[1], cache, keyspace); return CollectionType::map(key_type, value_type, is_frozen); } @@ -121,7 +121,7 @@ DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, for (Parser::TypeParamsVec::iterator i = params.begin(), end = params.end(); i != end; ++i) { - types.push_back(parse(*i, native_types, keyspace)); + types.push_back(parse(*i, cache, keyspace)); } return DataType::ConstPtr(new TupleType(types, is_frozen)); } @@ -132,7 +132,7 @@ DataType::ConstPtr DataTypeCqlNameParser::parse(const std::string& type, LOG_ERROR("Expecting single parameter for frozen keyword %s", type.c_str()); return DataType::NIL; } - return parse(params[0], native_types, keyspace, true); + return parse(params[0], cache, keyspace, true); } if (type_name == "empty") { @@ -278,7 +278,7 @@ bool DataTypeClassNameParser::is_tuple_type(const std::string& type) { return starts_with(type, TUPLE_TYPE); } -DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, const NativeDataTypes& native_types) { +DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, SimpleDataTypeCache& cache) { bool is_frozen = DataTypeClassNameParser::is_frozen(type); std::string class_name; @@ -301,7 +301,7 @@ DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, c if (!parser.get_type_params(¶ms) || params.empty()) { return DataType::ConstPtr(); } - DataType::ConstPtr element_type(parse_one(params[0], native_types)); + DataType::ConstPtr element_type(parse_one(params[0], cache)); if (!element_type) { return DataType::ConstPtr(); } @@ -311,7 +311,7 @@ DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, c if (!parser.get_type_params(¶ms) || params.empty()) { return DataType::ConstPtr(); } - DataType::ConstPtr element_type(parse_one(params[0], native_types)); + DataType::ConstPtr element_type(parse_one(params[0], cache)); if (!element_type) { return DataType::ConstPtr(); } @@ -321,8 +321,8 @@ DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, c if (!parser.get_type_params(¶ms) || params.size() < 2) { return DataType::ConstPtr(); } - DataType::ConstPtr key_type(parse_one(params[0], native_types)); - DataType::ConstPtr value_type(parse_one(params[1], native_types)); + DataType::ConstPtr key_type(parse_one(params[0], cache)); + DataType::ConstPtr value_type(parse_one(params[1], cache)); if (!key_type || !value_type) { return DataType::ConstPtr(); } @@ -368,7 +368,7 @@ DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, c UserType::FieldVec fields; for (NameAndTypeParamsVec::const_iterator i = raw_fields.begin(), end = raw_fields.end(); i != end; ++i) { - DataType::ConstPtr data_type = parse_one(i->second, native_types); + DataType::ConstPtr data_type = parse_one(i->second, cache); if (!data_type) { return DataType::ConstPtr(); } @@ -387,7 +387,7 @@ DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, c DataType::Vec types; for (TypeParamsVec::const_iterator i = raw_types.begin(), end = raw_types.end(); i != end; ++i) { - DataType::ConstPtr data_type = parse_one(*i, native_types); + DataType::ConstPtr data_type = parse_one(*i, cache); if (!data_type) { return DataType::ConstPtr(); } @@ -397,22 +397,22 @@ DataType::ConstPtr DataTypeClassNameParser::parse_one(const std::string& type, c return DataType::ConstPtr(new TupleType(types, true)); } - DataType::ConstPtr native_type(native_types.by_class_name(next)); - if (native_type) { - return native_type; + DataType::ConstPtr simple_type(cache.by_class(next)); + if (simple_type) { + return simple_type; } return DataType::ConstPtr(new CustomType(next)); } -ParseResult::Ptr DataTypeClassNameParser::parse_with_composite(const std::string& type, const NativeDataTypes& native_types) { +ParseResult::Ptr DataTypeClassNameParser::parse_with_composite(const std::string& type, SimpleDataTypeCache& cache) { Parser parser(type, 0); std::string next; parser.get_next_name(&next); if (!is_composite(next)) { - DataType::ConstPtr data_type = parse_one(type, native_types); + DataType::ConstPtr data_type = parse_one(type, cache); if (!data_type) { return ParseResult::Ptr(); } @@ -445,7 +445,7 @@ ParseResult::Ptr DataTypeClassNameParser::parse_with_composite(const std::string for (NameAndTypeParamsVec::const_iterator i = params.begin(), end = params.end(); i != end; ++i) { - DataType::ConstPtr data_type = parse_one(i->second, native_types); + DataType::ConstPtr data_type = parse_one(i->second, cache); if (!data_type) { return ParseResult::Ptr(); } @@ -456,7 +456,7 @@ ParseResult::Ptr DataTypeClassNameParser::parse_with_composite(const std::string DataType::Vec types; ParseResult::ReversedVec reversed; for (size_t i = 0; i < count; ++i) { - DataType::ConstPtr data_type = parse_one(sub_class_names[i], native_types); + DataType::ConstPtr data_type = parse_one(sub_class_names[i], cache); if (!data_type) { return ParseResult::Ptr(); } diff --git a/src/data_type_parser.hpp b/src/data_type_parser.hpp index 740efc933..ad8390db6 100644 --- a/src/data_type_parser.hpp +++ b/src/data_type_parser.hpp @@ -83,7 +83,7 @@ class ParserBase { class DataTypeCqlNameParser { public: static DataType::ConstPtr parse(const std::string& type, - const NativeDataTypes& native_types, + SimpleDataTypeCache& cache, KeyspaceMetadata* keyspace, bool is_frozen = false); @@ -147,8 +147,8 @@ class DataTypeClassNameParser { static bool is_user_type(const std::string& type); static bool is_tuple_type(const std::string& type); - static DataType::ConstPtr parse_one(const std::string& type, const NativeDataTypes& native_types); - static ParseResult::Ptr parse_with_composite(const std::string& type, const NativeDataTypes& native_types); + static DataType::ConstPtr parse_one(const std::string& type, SimpleDataTypeCache& cache); + static ParseResult::Ptr parse_with_composite(const std::string& type, SimpleDataTypeCache& cache); private: static bool get_nested_class_name(const std::string& type, std::string* class_name); diff --git a/src/external.cpp b/src/external.cpp index b8fd3cbc8..fc0ccb5d8 100644 --- a/src/external.cpp +++ b/src/external.cpp @@ -32,7 +32,7 @@ const char* cass_error_desc(CassError error) { #define XX(source, _, code, desc) \ case CASS_ERROR(source, code): \ return desc; - CASS_ERROR_MAP(XX) + CASS_ERROR_MAPPING(XX) #undef XX default: return ""; @@ -44,7 +44,7 @@ const char* cass_log_level_string(CassLogLevel log_level) { #define XX(log_level, desc) \ case log_level: \ return desc; - CASS_LOG_LEVEL_MAP(XX) + CASS_LOG_LEVEL_MAPPING(XX) #undef XX default: return ""; @@ -56,7 +56,7 @@ const char* cass_consistency_string(CassConsistency consistency) { #define XX(consistency, desc) \ case consistency: \ return desc; - CASS_CONSISTENCY_MAP(XX) + CASS_CONSISTENCY_MAPPING(XX) #undef XX default: return ""; @@ -68,7 +68,7 @@ const char* cass_write_type_string(CassWriteType write_type) { #define XX(write_type, desc) \ case write_type: \ return desc; - CASS_WRITE_TYPE_MAP(XX) + CASS_WRITE_TYPE_MAPPING(XX) #undef XX default: return ""; diff --git a/src/fixed_vector.hpp b/src/fixed_allocator.hpp similarity index 77% rename from src/fixed_vector.hpp rename to src/fixed_allocator.hpp index 8308ee457..cd3c9d7d1 100644 --- a/src/fixed_vector.hpp +++ b/src/fixed_allocator.hpp @@ -22,7 +22,6 @@ #include #include -#include namespace cass { @@ -111,32 +110,6 @@ class FixedAllocator { Fixed* fixed_; }; -// This vector uses the fixed buffer as long as it doesn't exceed N items. -// This can help to avoid heap allocation in the common cases while also -// handling the cases that do exceed the fixed buffer. - -template -class FixedVector : public std::vector > { -public: - FixedVector() - : std::vector >(FixedAllocator(&fixed_)) { - this->reserve(N); - } - - FixedVector(size_t inital_size) - : std::vector >(FixedAllocator(&fixed_)) { - this->resize(inital_size); - } - - const typename FixedAllocator::Fixed& fixed() const { return fixed_; } - -private: - typename FixedAllocator::Fixed fixed_; - -private: - DISALLOW_COPY_AND_ASSIGN(FixedVector); -}; - } // namespace cass -#endif // FIXED_ALLOCATOR_HPP +#endif diff --git a/src/hash_table.hpp b/src/hash_table.hpp index f3f8a8f24..f147a27cb 100644 --- a/src/hash_table.hpp +++ b/src/hash_table.hpp @@ -17,9 +17,9 @@ #ifndef __CASS_HASH_INDEX_HPP_INCLUDED__ #define __CASS_HASH_INDEX_HPP_INCLUDED__ -#include "fixed_vector.hpp" #include "hash.hpp" #include "macros.hpp" +#include "small_vector.hpp" #include "string_ref.hpp" #include "utils.hpp" @@ -31,7 +31,7 @@ namespace cass { -typedef FixedVector IndexVec; +typedef SmallVector IndexVec; template struct HashTableEntry { @@ -47,7 +47,7 @@ struct HashTableEntry { template class CaseInsensitiveHashTable { public: - typedef FixedVector EntryVec; + typedef SmallVector EntryVec; CaseInsensitiveHashTable(size_t capacity = 16); CaseInsensitiveHashTable(const EntryVec& entries); @@ -72,7 +72,7 @@ class CaseInsensitiveHashTable { private: size_t index_mask_; size_t count_; - FixedVector index_; + SmallVector index_; EntryVec entries_; private: diff --git a/src/macros.hpp b/src/macros.hpp index 5e620e978..81f11bb1a 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -56,4 +56,25 @@ template struct StaticAssert; template <> struct StaticAssert { }; template struct StaticAssertTest { }; +#define STATIC_NEXT_POW_2(N) StaticNextPow2::value + +template +struct StaticNextPow2Helper { + enum { + value = static_cast(StaticNextPow2Helper::value) < N + ? static_cast(1) << C + : static_cast(StaticNextPow2Helper::value) + }; +}; + +template +struct StaticNextPow2Helper<1, N> { + enum { value = 2 }; +}; + +template +struct StaticNextPow2 { + enum { value = StaticNextPow2Helper<8 * sizeof(size_t) - 1, N>::value }; +}; + #endif diff --git a/src/metadata.cpp b/src/metadata.cpp index 289a4e050..90d199b7d 100644 --- a/src/metadata.cpp +++ b/src/metadata.cpp @@ -832,12 +832,12 @@ void Metadata::update_columns(int protocol_version, const VersionNumber& cassand if (is_front_buffer()) { ScopedMutex l(&mutex_); - updating_->update_columns(protocol_version, cassandra_version, native_types_, result); + updating_->update_columns(protocol_version, cassandra_version, cache_, result); if (cassandra_version < VersionNumber(3, 0, 0)) { updating_->update_legacy_indexes(protocol_version, cassandra_version, result); } } else { - updating_->update_columns(protocol_version, cassandra_version, native_types_, result); + updating_->update_columns(protocol_version, cassandra_version, cache_, result); if (cassandra_version < VersionNumber(3, 0, 0)) { updating_->update_legacy_indexes(protocol_version, cassandra_version, result); } @@ -860,9 +860,9 @@ void Metadata::update_user_types(int protocol_version, const VersionNumber& cass if (is_front_buffer()) { ScopedMutex l(&mutex_); - updating_->update_user_types(protocol_version, cassandra_version, native_types_, result); + updating_->update_user_types(protocol_version, cassandra_version, cache_, result); } else { - updating_->update_user_types(protocol_version, cassandra_version, native_types_, result); + updating_->update_user_types(protocol_version, cassandra_version, cache_, result); } } @@ -871,9 +871,9 @@ void Metadata::update_functions(int protocol_version, const VersionNumber& cassa if (is_front_buffer()) { ScopedMutex l(&mutex_); - updating_->update_functions(protocol_version, cassandra_version, native_types_, result); + updating_->update_functions(protocol_version, cassandra_version, cache_, result); } else { - updating_->update_functions(protocol_version, cassandra_version, native_types_, result); + updating_->update_functions(protocol_version, cassandra_version, cache_, result); } } @@ -882,9 +882,9 @@ void Metadata::update_aggregates(int protocol_version, const VersionNumber& cass if (is_front_buffer()) { ScopedMutex l(&mutex_); - updating_->update_aggregates(protocol_version, cassandra_version, native_types_, result); + updating_->update_aggregates(protocol_version, cassandra_version, cache_, result); } else { - updating_->update_aggregates(protocol_version, cassandra_version, native_types_, result); + updating_->update_aggregates(protocol_version, cassandra_version, cache_, result); } } @@ -944,11 +944,6 @@ void Metadata::drop_aggregate(const std::string& keyspace_name, const std::strin } void Metadata::clear_and_update_back(const VersionNumber& cassandra_version) { - if (cassandra_version >= VersionNumber(3, 0, 0)) { - native_types_.init_cql_names(); - } else { - native_types_.init_class_names(); - } back_.clear(); updating_ = &back_; } @@ -1308,7 +1303,7 @@ size_t get_column_count(const ColumnMetadata::Vec& columns, CassColumnType type) return count; } -void TableMetadataBase::build_keys_and_sort(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types) { +void TableMetadataBase::build_keys_and_sort(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache) { // Also, Reorders columns so that the order is: // 1) Parition key // 2) Clustering keys @@ -1351,7 +1346,7 @@ void TableMetadataBase::build_keys_and_sort(int protocol_version, const VersionN } ParseResult::Ptr key_validator - = DataTypeClassNameParser::parse_with_composite(get_string_field("key_validator"), native_types); + = DataTypeClassNameParser::parse_with_composite(get_string_field("key_validator"), cache); size_t size = key_validator->types().size(); partition_key_.reserve(size); for (size_t i = 0; i < size; ++i) { @@ -1385,7 +1380,7 @@ void TableMetadataBase::build_keys_and_sort(int protocol_version, const VersionN // TODO: Figure out how to test these special cases and properly document them here ParseResult::Ptr comparator - = DataTypeClassNameParser::parse_with_composite(get_string_field("comparator"), native_types); + = DataTypeClassNameParser::parse_with_composite(get_string_field("comparator"), cache); size_t size = comparator->types().size(); if (comparator->is_composite()) { if (!comparator->collections().empty() || @@ -1461,7 +1456,7 @@ void TableMetadata::sort_views() { std::sort(views_.begin(), views_.end()); } -void TableMetadata::key_aliases(const NativeDataTypes& native_types, KeyAliases* output) const { +void TableMetadata::key_aliases(SimpleDataTypeCache& cache, KeyAliases* output) const { const Value* aliases = get_field("key_aliases"); if (aliases != NULL) { output->reserve(aliases->count()); @@ -1472,7 +1467,7 @@ void TableMetadata::key_aliases(const NativeDataTypes& native_types, KeyAliases* } if (output->empty()) {// C* 1.2 tables created via CQL2 or thrift don't have col meta or key aliases ParseResult::Ptr key_validator_type - = DataTypeClassNameParser::parse_with_composite(get_string_field("key_validator"), native_types); + = DataTypeClassNameParser::parse_with_composite(get_string_field("key_validator"), cache); const size_t count = key_validator_type->types().size(); std::ostringstream ss("key"); for (size_t i = 0; i < count; ++i) { @@ -1517,7 +1512,7 @@ void TableMetadata::clear_indexes() { indexes_by_name_.clear(); } -FunctionMetadata::FunctionMetadata(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, +FunctionMetadata::FunctionMetadata(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, const std::string& name, const Value* signature, KeyspaceMetadata* keyspace, const RefBuffer::Ptr& buffer, const Row* row) @@ -1542,13 +1537,13 @@ FunctionMetadata::FunctionMetadata(int protocol_version, const VersionNumber& ca if (cassandra_version >= VersionNumber(3, 0, 0)) { while (iterator1.next() && iterator2.next()) { StringRef arg_name(iterator1.value()->to_string_ref()); - DataType::ConstPtr arg_type(DataTypeCqlNameParser::parse(iterator2.value()->to_string(), native_types, keyspace)); + DataType::ConstPtr arg_type(DataTypeCqlNameParser::parse(iterator2.value()->to_string(), cache, keyspace)); args_.push_back(Argument(arg_name, arg_type)); } } else { while (iterator1.next() && iterator2.next()) { StringRef arg_name(iterator1.value()->to_string_ref()); - DataType::ConstPtr arg_type(DataTypeClassNameParser::parse_one(iterator2.value()->to_string(), native_types)); + DataType::ConstPtr arg_type(DataTypeClassNameParser::parse_one(iterator2.value()->to_string(), cache)); args_.push_back(Argument(arg_name, arg_type)); } } @@ -1558,9 +1553,9 @@ FunctionMetadata::FunctionMetadata(int protocol_version, const VersionNumber& ca if (value1 != NULL && value1->value_type() == CASS_VALUE_TYPE_VARCHAR) { if (cassandra_version >= VersionNumber(3, 0, 0)) { - return_type_ = DataTypeCqlNameParser::parse(value1->to_string(), native_types, keyspace); + return_type_ = DataTypeCqlNameParser::parse(value1->to_string(), cache, keyspace); } else { - return_type_ = DataTypeClassNameParser::parse_one(value1->to_string(), native_types); + return_type_ = DataTypeClassNameParser::parse_one(value1->to_string(), cache); } } @@ -1589,7 +1584,7 @@ const DataType* FunctionMetadata::get_arg_type(StringRef name) const { return i->type.get(); } -AggregateMetadata::AggregateMetadata(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, +AggregateMetadata::AggregateMetadata(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, const std::string& name, const Value* signature, KeyspaceMetadata* keyspace, const RefBuffer::Ptr& buffer, const Row* row) @@ -1608,11 +1603,11 @@ AggregateMetadata::AggregateMetadata(int protocol_version, const VersionNumber& CollectionIterator iterator(value); if (cassandra_version >= VersionNumber(3, 0, 0)) { while (iterator.next()) { - arg_types_.push_back(DataTypeCqlNameParser::parse(iterator.value()->to_string(), native_types, keyspace)); + arg_types_.push_back(DataTypeCqlNameParser::parse(iterator.value()->to_string(), cache, keyspace)); } } else { while (iterator.next()) { - arg_types_.push_back(DataTypeClassNameParser::parse_one(iterator.value()->to_string(), native_types)); + arg_types_.push_back(DataTypeClassNameParser::parse_one(iterator.value()->to_string(), cache)); } } } @@ -1621,9 +1616,9 @@ AggregateMetadata::AggregateMetadata(int protocol_version, const VersionNumber& if (value != NULL && value->value_type() == CASS_VALUE_TYPE_VARCHAR) { if (cassandra_version >= VersionNumber(3, 0, 0)) { - return_type_ = DataTypeCqlNameParser::parse(value->to_string(), native_types, keyspace); + return_type_ = DataTypeCqlNameParser::parse(value->to_string(), cache, keyspace); } else { - return_type_ = DataTypeClassNameParser::parse_one(value->to_string(), native_types); + return_type_ = DataTypeClassNameParser::parse_one(value->to_string(), cache); } } @@ -1631,9 +1626,9 @@ AggregateMetadata::AggregateMetadata(int protocol_version, const VersionNumber& if (value != NULL && value->value_type() == CASS_VALUE_TYPE_VARCHAR) { if (cassandra_version >= VersionNumber(3, 0, 0)) { - state_type_ = DataTypeCqlNameParser::parse(value->to_string(), native_types, keyspace); + state_type_ = DataTypeCqlNameParser::parse(value->to_string(), cache, keyspace); } else { - state_type_ = DataTypeClassNameParser::parse_one(value->to_string(), native_types); + state_type_ = DataTypeClassNameParser::parse_one(value->to_string(), cache); } } @@ -1668,7 +1663,7 @@ AggregateMetadata::AggregateMetadata(int protocol_version, const VersionNumber& } else if (cassandra_version >= VersionNumber(3, 0, 0) && value->value_type() == CASS_VALUE_TYPE_VARCHAR) { init_cond_ = Value(protocol_version, - native_types.by_cql_name("varchar"), + cache.by_value_type(CASS_VALUE_TYPE_VARCHAR), value->data(), value->size()); } } @@ -1769,7 +1764,7 @@ CassIndexType IndexMetadata::index_type_from_string(StringRef index_type) { return CASS_INDEX_TYPE_UNKNOWN; } -ColumnMetadata::ColumnMetadata(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, +ColumnMetadata::ColumnMetadata(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, const std::string& name, KeyspaceMetadata* keyspace, const RefBuffer::Ptr& buffer, const Row* row) @@ -1819,7 +1814,7 @@ ColumnMetadata::ColumnMetadata(int protocol_version, const VersionNumber& cassan if (value != NULL && value->value_type() == CASS_VALUE_TYPE_VARCHAR) { std::string type(value->to_string()); - data_type_ = DataTypeCqlNameParser::parse(type, native_types, keyspace); + data_type_ = DataTypeCqlNameParser::parse(type, cache, keyspace); } } else { value = add_field(buffer, row, "type"); @@ -1851,7 +1846,7 @@ ColumnMetadata::ColumnMetadata(int protocol_version, const VersionNumber& cassan if (value != NULL && value->value_type() == CASS_VALUE_TYPE_VARCHAR) { std::string validator(value->to_string()); - data_type_ = DataTypeClassNameParser::parse_one(validator, native_types); + data_type_ = DataTypeClassNameParser::parse_one(validator, cache); is_reversed_ = DataTypeClassNameParser::is_reversed(validator); } @@ -1960,7 +1955,7 @@ void Metadata::InternalData::update_views(int protocol_version, const VersionNum } } -void Metadata::InternalData::update_user_types(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, ResultResponse* result) { +void Metadata::InternalData::update_user_types(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, ResultResponse* result) { ResultIterator rows(result); std::string keyspace_name; @@ -2022,9 +2017,9 @@ void Metadata::InternalData::update_user_types(int protocol_version, const Versi DataType::ConstPtr data_type; if (cassandra_version >= VersionNumber(3, 0, 0)) { - data_type = DataTypeCqlNameParser::parse(type->to_string(), native_types, keyspace); + data_type = DataTypeCqlNameParser::parse(type->to_string(), cache, keyspace); } else { - data_type = DataTypeClassNameParser::parse_one(type->to_string(), native_types); + data_type = DataTypeClassNameParser::parse_one(type->to_string(), cache); } if (!data_type) { @@ -2042,7 +2037,7 @@ void Metadata::InternalData::update_user_types(int protocol_version, const Versi } } -void Metadata::InternalData::update_functions(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, +void Metadata::InternalData::update_functions(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, ResultResponse* result) { RefBuffer::Ptr buffer = result->buffer(); @@ -2069,7 +2064,7 @@ void Metadata::InternalData::update_functions(int protocol_version, const Versio keyspace = get_or_create_keyspace(keyspace_name); } - keyspace->add_function(FunctionMetadata::Ptr(new FunctionMetadata(protocol_version, cassandra_version, native_types, + keyspace->add_function(FunctionMetadata::Ptr(new FunctionMetadata(protocol_version, cassandra_version, cache, function_name, signature, keyspace, buffer, row))); @@ -2077,7 +2072,7 @@ void Metadata::InternalData::update_functions(int protocol_version, const Versio } } -void Metadata::InternalData::update_aggregates(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, ResultResponse* result) { +void Metadata::InternalData::update_aggregates(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, ResultResponse* result) { RefBuffer::Ptr buffer = result->buffer(); ResultIterator rows(result); @@ -2103,7 +2098,7 @@ void Metadata::InternalData::update_aggregates(int protocol_version, const Versi keyspace = get_or_create_keyspace(keyspace_name); } - keyspace->add_aggregate(AggregateMetadata::Ptr(new AggregateMetadata(protocol_version, cassandra_version, native_types, + keyspace->add_aggregate(AggregateMetadata::Ptr(new AggregateMetadata(protocol_version, cassandra_version, cache, aggregate_name, signature, keyspace, buffer, row))); @@ -2139,7 +2134,7 @@ void Metadata::InternalData::drop_aggregate(const std::string& keyspace_name, co i->second.drop_aggregate(full_aggregate_name); } -void Metadata::InternalData::update_columns(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, ResultResponse* result) { +void Metadata::InternalData::update_columns(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, ResultResponse* result) { RefBuffer::Ptr buffer = result->buffer(); ResultIterator rows(result); @@ -2173,7 +2168,7 @@ void Metadata::InternalData::update_columns(int protocol_version, const VersionN if (table_or_view_name != temp_table_or_view_name) { // Build keys for the previous table if (table_or_view) { - table_or_view->build_keys_and_sort(protocol_version, cassandra_version, native_types); + table_or_view->build_keys_and_sort(protocol_version, cassandra_version, cache); } table_or_view_name = temp_table_or_view_name; table_or_view = TableMetadataBase::Ptr(keyspace->get_table(table_or_view_name)); @@ -2185,14 +2180,14 @@ void Metadata::InternalData::update_columns(int protocol_version, const VersionN } if (table_or_view) { - table_or_view->add_column(ColumnMetadata::Ptr(new ColumnMetadata(protocol_version, cassandra_version, native_types, column_name, + table_or_view->add_column(ColumnMetadata::Ptr(new ColumnMetadata(protocol_version, cassandra_version, cache, column_name, keyspace, buffer, row))); } } // Build keys for the last table if (table_or_view) { - table_or_view->build_keys_and_sort(protocol_version, cassandra_version, native_types); + table_or_view->build_keys_and_sort(protocol_version, cassandra_version, cache); } } diff --git a/src/metadata.hpp b/src/metadata.hpp index 367319158..3cc747933 100644 --- a/src/metadata.hpp +++ b/src/metadata.hpp @@ -201,7 +201,7 @@ class FunctionMetadata : public MetadataBase, public RefCounted Map; typedef std::vector Vec; - AggregateMetadata(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, + AggregateMetadata(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, const std::string& name, const Value* signature, KeyspaceMetadata* keyspace, const RefBuffer::Ptr& buffer, const Row* row); @@ -317,7 +317,7 @@ class ColumnMetadata : public MetadataBase, public RefCounted { , data_type_(data_type) , is_reversed_(false) { } - ColumnMetadata(int protocol_version, const VersionNumber& cassandra_version, const NativeDataTypes native_types, + ColumnMetadata(int protocol_version, const VersionNumber& cassandra_version, SimpleDataTypeCache& cache, const std::string& name, KeyspaceMetadata* keyspace, const RefBuffer::Ptr& buffer, const Row* row); @@ -367,7 +367,7 @@ class TableMetadataBase : public MetadataBase, public RefCounted @@ -195,7 +195,7 @@ class RequestHandler : public RefCounted { void stop_request(); private: - typedef FixedVector SpeculativeExecutionVec; + typedef SmallVector SpeculativeExecutionVec; const Request::ConstPtr request_; int64_t timestamp_; diff --git a/src/response.hpp b/src/response.hpp index a6fa9a35d..a48a6d706 100644 --- a/src/response.hpp +++ b/src/response.hpp @@ -39,8 +39,8 @@ class Response : public RefCounted { StringRef name; StringRef value; }; - typedef FixedVector CustomPayloadVec; - typedef FixedVector WarningVec; + typedef SmallVector CustomPayloadVec; + typedef SmallVector WarningVec; Response(uint8_t opcode) : opcode_(opcode) { } diff --git a/src/result_metadata.hpp b/src/result_metadata.hpp index 06eb18811..9810f6740 100644 --- a/src/result_metadata.hpp +++ b/src/result_metadata.hpp @@ -19,10 +19,10 @@ #include "cassandra.h" #include "data_type.hpp" -#include "fixed_vector.hpp" #include "hash_table.hpp" #include "list.hpp" #include "ref_counted.hpp" +#include "small_vector.hpp" #include "string_ref.hpp" #include diff --git a/src/result_response.cpp b/src/result_response.cpp index 071c69898..3e8196774 100644 --- a/src/result_response.cpp +++ b/src/result_response.cpp @@ -20,8 +20,6 @@ #include "result_metadata.hpp" #include "serialization.hpp" -#include - extern "C" { void cass_result_free(const CassResult* result) { @@ -105,15 +103,13 @@ namespace cass { class DataTypeDecoder { public: - DataTypeDecoder(char* input) - : buffer_(input) { - data_type_cache_.set_empty_key(CASS_VALUE_TYPE_LAST_ENTRY); - native_types_.init_class_names(); - } + DataTypeDecoder(char* input, SimpleDataTypeCache& cache) + : buffer_(input) + , cache_(cache) { } char* buffer() const { return buffer_; } - DataType::Ptr decode() { + DataType::ConstPtr decode() { uint16_t value_type; buffer_ = decode_uint16(buffer_, value_type); @@ -133,49 +129,34 @@ class DataTypeDecoder { return decode_tuple(); default: - if (value_type < CASS_VALUE_TYPE_LAST_ENTRY) { - return decode_simple_type(value_type); - } - break; + return cache_.by_value_type(value_type); } - return DataType::Ptr(); + return DataType::NIL; } private: - DataType::Ptr decode_custom() { + DataType::ConstPtr decode_custom() { StringRef class_name; buffer_ = decode_string(buffer_, &class_name); - const DataType::ConstPtr& type = native_types_.by_class_name(class_name.to_string()); - if (type == DataType::NIL) - // If no mapping exists, return an actual custom type. - return DataType::Ptr(new CustomType(class_name.to_string())); - else - return type->copy(); - } + DataType::ConstPtr type = cache_.by_class(class_name); + if (type) return type; - DataType::Ptr decode_simple_type(uint16_t value_type) { - if (data_type_cache_[value_type]) { - return data_type_cache_[value_type]; - } else { - DataType::Ptr data_type( - new DataType(static_cast(value_type))); - data_type_cache_[value_type] = data_type; - return data_type; - } + // If no mapping exists, return an actual custom type. + return DataType::ConstPtr(new CustomType(class_name.to_string())); } - DataType::Ptr decode_collection(CassValueType collection_type) { + DataType::ConstPtr decode_collection(CassValueType collection_type) { DataType::Vec types; types.push_back(decode()); if (collection_type == CASS_VALUE_TYPE_MAP) { types.push_back(decode()); } - return DataType::Ptr(new CollectionType(collection_type, types, false)); + return DataType::ConstPtr(new CollectionType(collection_type, types, false)); } - DataType::Ptr decode_user_type() { + DataType::ConstPtr decode_user_type() { StringRef keyspace; buffer_ = decode_string(buffer_, &keyspace); @@ -191,13 +172,13 @@ class DataTypeDecoder { buffer_ = decode_string(buffer_, &field_name); fields.push_back(UserType::Field(field_name.to_string(), decode())); } - return DataType::Ptr(new UserType(keyspace.to_string(), - type_name.to_string(), - fields, - false)); + return DataType::ConstPtr(new UserType(keyspace.to_string(), + type_name.to_string(), + fields, + false)); } - DataType::Ptr decode_tuple() { + DataType::ConstPtr decode_tuple() { uint16_t n; buffer_ = decode_uint16(buffer_, n); @@ -205,13 +186,12 @@ class DataTypeDecoder { for (uint16_t i = 0; i < n; ++i) { types.push_back(decode()); } - return DataType::Ptr(new TupleType(types, false)); + return DataType::ConstPtr(new TupleType(types, false)); } private: char* buffer_; - sparsehash::dense_hash_map data_type_cache_; - NativeDataTypes native_types_; + SimpleDataTypeCache& cache_; }; bool ResultResponse::decode(int version, char* input, size_t size) { @@ -281,6 +261,8 @@ char* ResultResponse::decode_metadata(char* input, ResultMetadata::Ptr* metadata metadata->reset(new ResultMetadata(column_count)); + SimpleDataTypeCache cache; + for (int i = 0; i < column_count; ++i) { ColumnDefinition def; @@ -293,7 +275,7 @@ char* ResultResponse::decode_metadata(char* input, ResultMetadata::Ptr* metadata buffer = decode_string(buffer, &def.name); - DataTypeDecoder type_decoder(buffer); + DataTypeDecoder type_decoder(buffer, cache); def.data_type = DataType::ConstPtr(type_decoder.decode()); buffer = type_decoder.buffer(); diff --git a/src/ring_buffer.hpp b/src/ring_buffer.hpp index 814a1b620..5474b411d 100644 --- a/src/ring_buffer.hpp +++ b/src/ring_buffer.hpp @@ -42,7 +42,7 @@ #ifndef __CASS_RING_BUFFER_HPP_INCLUDED__ #define __CASS_RING_BUFFER_HPP_INCLUDED__ -#include "fixed_vector.hpp" +#include "small_vector.hpp" #include @@ -104,7 +104,7 @@ class RingBuffer { // Return pointers and sizes of multiple internal data chunks available for // reading from position template - size_t peek_multiple(Position pos, FixedVector* bufs); + size_t peek_multiple(Position pos, SmallVector* bufs); // Find first appearance of `delim` in buffer or `limit` if `delim` // wasn't found. @@ -136,7 +136,7 @@ class RingBuffer { }; template -size_t RingBuffer::peek_multiple(Position pos, FixedVector* bufs) { +size_t RingBuffer::peek_multiple(Position pos, SmallVector* bufs) { Buffer* buf = pos.buf; size_t offset = pos.pos; size_t total = 0; diff --git a/src/small_dense_hash_map.hpp b/src/small_dense_hash_map.hpp new file mode 100644 index 000000000..aba8a82d3 --- /dev/null +++ b/src/small_dense_hash_map.hpp @@ -0,0 +1,72 @@ +/* + Copyright (c) 2014-2016 DataStax + + Licensed 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. +*/ + +#ifndef __CASS_SMALL_DENSE_HASH_MAP_HPP_INCLUDED__ +#define __CASS_SMALL_DENSE_HASH_MAP_HPP_INCLUDED__ + +#include "fixed_allocator.hpp" +#include "macros.hpp" + +#include +#include + +// This should be the same as sparsehash::densehashtable<>::HT_OCCUPANCY_PCT +// which can be found at the bottom of "sparesehash/internal/densehashtable.h". +#define OCCUPANCY_PCT 50 + +#define MIN_BUCKETS(N) STATIC_NEXT_POW_2((((N * 100) / OCCUPANCY_PCT) + 1)) + +namespace cass { + +// This hash map uses a fixed buffer as long as it doesn't exceed N items. +// This can help to avoid heap allocation in cases where the hash map remains +// small and doesn't excceed the fixed buffer. + +template , + class EqualKey = std::equal_to > +class SmallDenseHashMap + : public sparsehash::dense_hash_map< + K, V, HashFcn, EqualKey, + FixedAllocator, MIN_BUCKETS(N)> > { +public: + typedef std::pair Pair; + typedef FixedAllocator, MIN_BUCKETS(N)> Allocator; + typedef sparsehash::dense_hash_map HashMap; + + SmallDenseHashMap() + : HashMap(N, typename HashMap::hasher(), typename HashMap::key_equal(), Allocator(&fixed_)) { + assert(MIN_BUCKETS(N) >= this->bucket_count()); + } + + SmallDenseHashMap(size_t expected_max_items_in_table) + : HashMap(expected_max_items_in_table, HashMap::hasher(), HashMap::key_equal(), Allocator(&fixed_)) { + assert(MIN_BUCKETS(N) >= this->bucket_count()); + } + + const typename Allocator::Fixed& fixed() const { return fixed_; } + +private: + typename Allocator::Fixed fixed_; + +private: + DISALLOW_COPY_AND_ASSIGN(SmallDenseHashMap); +}; + +} // namespace cass + +#endif diff --git a/src/small_vector.hpp b/src/small_vector.hpp new file mode 100644 index 000000000..421111f73 --- /dev/null +++ b/src/small_vector.hpp @@ -0,0 +1,54 @@ +/* + Copyright (c) 2014-2016 DataStax + + Licensed 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. +*/ + +#ifndef __CASS_SMALL_VECTOR_HPP_INCLUDED__ +#define __CASS_SMALL_VECTOR_HPP_INCLUDED__ + +#include "fixed_allocator.hpp" + +#include + +namespace cass { + +// This vector uses a fixed buffer as long as it doesn't exceed N items. +// This can help to avoid heap allocation in cases where the vector remains +// small and doesn't excceed the fixed buffer. + +template +class SmallVector : public std::vector > { +public: + SmallVector() + : std::vector >(FixedAllocator(&fixed_)) { + this->reserve(N); + } + + SmallVector(size_t inital_size) + : std::vector >(FixedAllocator(&fixed_)) { + this->resize(inital_size); + } + + const typename FixedAllocator::Fixed& fixed() const { return fixed_; } + +private: + typename FixedAllocator::Fixed fixed_; + +private: + DISALLOW_COPY_AND_ASSIGN(SmallVector); +}; + +} // namespace cass + +#endif diff --git a/src/string_ref.hpp b/src/string_ref.hpp index 971371e3b..905706e30 100644 --- a/src/string_ref.hpp +++ b/src/string_ref.hpp @@ -17,6 +17,8 @@ #ifndef __CASS_STRING_REF_HPP_INCLUDED__ #define __CASS_STRING_REF_HPP_INCLUDED__ +#include "hash.hpp" + #include #include #include @@ -176,10 +178,22 @@ inline bool ends_with(const StringRef& input, const StringRef& target) { target.data(), target.size(), StringRef::IsEqual()) == 0; } -inline bool iequals(const StringRef& input, const StringRef& target) { - return input.iequals(target); +inline bool iequals(const StringRef& lhs, const StringRef& rhs) { + return lhs.iequals(rhs); } +struct StringRefIHash { + std::size_t operator()(const StringRef& s) const { + return hash::fnv1a(s.data(), s.size(), ::tolower); + } +}; + +struct StringRefIEquals { + bool operator()(const StringRef& lhs, const StringRef& rhs) const { + return lhs.iequals(rhs); + } +}; + } // namespace cass #endif diff --git a/test/unit_tests/src/test_class_type_parser.cpp b/test/unit_tests/src/test_class_type_parser.cpp index ecb90706c..1589e5661 100644 --- a/test/unit_tests/src/test_class_type_parser.cpp +++ b/test/unit_tests/src/test_class_type_parser.cpp @@ -28,16 +28,15 @@ BOOST_AUTO_TEST_CASE(simple) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; - data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.InetAddressType", native_types); + data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.InetAddressType", cache); BOOST_CHECK(data_type->value_type() == CASS_VALUE_TYPE_INET); - data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UTF8Type)", native_types); + data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.UTF8Type)", cache); BOOST_CHECK(data_type->value_type() == CASS_VALUE_TYPE_TEXT); - data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.UTF8Type)", native_types); + data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.UTF8Type)", cache); BOOST_REQUIRE(data_type->value_type() == CASS_VALUE_TYPE_LIST); cass::CollectionType::ConstPtr collection @@ -50,40 +49,38 @@ BOOST_AUTO_TEST_CASE(invalid) { cass_log_set_level(CASS_LOG_DISABLED); - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; // Premature end of string - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType", native_types)); - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(", native_types)); - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(blah", native_types)); - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(blah,", native_types)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType", cache)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(", cache)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(blah", cache)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(blah,", cache)); // Empty - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType()", native_types)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType()", cache)); // Invalid hex - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(blah,ZZZZ", native_types)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(blah,ZZZZ", cache)); // Missing ':' BOOST_CHECK(!cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(" "foo,61646472657373," - "737472656574org.apache.cassandra.db.marshal.UTF8Type)", native_types)); + "737472656574org.apache.cassandra.db.marshal.UTF8Type)", cache)); // Premature end of string - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType", native_types)); - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(", native_types)); - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type", native_types)); - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,", native_types)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType", cache)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(", cache)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type", cache)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(org.apache.cassandra.db.marshal.UTF8Type,", cache)); // Empty - BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType()", native_types)); + BOOST_CHECK(!cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType()", cache)); } BOOST_AUTO_TEST_CASE(udt) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::DataType::ConstPtr data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.UserType(" @@ -92,7 +89,7 @@ BOOST_AUTO_TEST_CASE(udt) "7a6970636f6465:org.apache.cassandra.db.marshal.Int32Type," "70686f6e6573:org.apache.cassandra.db.marshal.SetType(" "org.apache.cassandra.db.marshal.UserType(foo,70686f6e65,6e616d65:org.apache.cassandra.db.marshal.UTF8Type,6e756d626572:org.apache.cassandra.db.marshal.UTF8Type)))", - native_types); + cache); BOOST_REQUIRE(data_type->value_type() == CASS_VALUE_TYPE_UDT); @@ -148,14 +145,13 @@ BOOST_AUTO_TEST_CASE(udt) BOOST_AUTO_TEST_CASE(tuple) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::DataType::ConstPtr data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.TupleType(" "org.apache.cassandra.db.marshal.Int32Type," "org.apache.cassandra.db.marshal.UTF8Type," - "org.apache.cassandra.db.marshal.FloatType)", native_types); + "org.apache.cassandra.db.marshal.FloatType)", cache); BOOST_REQUIRE(data_type->value_type() == CASS_VALUE_TYPE_TUPLE); @@ -170,15 +166,14 @@ BOOST_AUTO_TEST_CASE(tuple) BOOST_AUTO_TEST_CASE(nested_collections) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::DataType::ConstPtr data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.MapType(" "org.apache.cassandra.db.marshal.UTF8Type," "org.apache.cassandra.db.marshal.FrozenType(" "org.apache.cassandra.db.marshal.MapType(" - "org.apache.cassandra.db.marshal.Int32Type,org.apache.cassandra.db.marshal.Int32Type)))", native_types); + "org.apache.cassandra.db.marshal.Int32Type,org.apache.cassandra.db.marshal.Int32Type)))", cache); BOOST_REQUIRE(data_type->value_type() == CASS_VALUE_TYPE_MAP); @@ -201,13 +196,12 @@ BOOST_AUTO_TEST_CASE(nested_collections) BOOST_AUTO_TEST_CASE(composite) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::SharedRefPtr result = cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(" "org.apache.cassandra.db.marshal.AsciiType," - "org.apache.cassandra.db.marshal.Int32Type)", native_types); + "org.apache.cassandra.db.marshal.Int32Type)", cache); BOOST_CHECK(result->is_composite()); @@ -224,11 +218,10 @@ BOOST_AUTO_TEST_CASE(composite) BOOST_AUTO_TEST_CASE(not_composite) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::SharedRefPtr result - = cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.InetAddressType", native_types); + = cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.InetAddressType", cache); BOOST_REQUIRE(result->types().size() == 1); BOOST_CHECK(result->types()[0]->value_type() == CASS_VALUE_TYPE_INET); @@ -239,13 +232,12 @@ BOOST_AUTO_TEST_CASE(not_composite) BOOST_AUTO_TEST_CASE(composite_with_reversed) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::SharedRefPtr result = cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(" "org.apache.cassandra.db.marshal.ReversedType(org.apache.cassandra.db.marshal.AsciiType)," - "org.apache.cassandra.db.marshal.Int32Type)", native_types); + "org.apache.cassandra.db.marshal.Int32Type)", cache); BOOST_CHECK(result->is_composite()); @@ -262,8 +254,7 @@ BOOST_AUTO_TEST_CASE(composite_with_reversed) BOOST_AUTO_TEST_CASE(composite_with_collections) { - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; cass::SharedRefPtr result = cass::DataTypeClassNameParser::parse_with_composite("org.apache.cassandra.db.marshal.CompositeType(" @@ -273,7 +264,7 @@ BOOST_AUTO_TEST_CASE(composite_with_collections) "6162:org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.Int32Type)," "4A4b4C4D4e4F:org.apache.cassandra.db.marshal.SetType(org.apache.cassandra.db.marshal.UTF8Type)," "6A6b6C6D6e6F:org.apache.cassandra.db.marshal.MapType(org.apache.cassandra.db.marshal.UTF8Type, org.apache.cassandra.db.marshal.LongType)" - "))", native_types); + "))", cache); BOOST_CHECK(result->is_composite()); @@ -317,14 +308,13 @@ BOOST_AUTO_TEST_CASE(frozen) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_class_names(); + cass::SimpleDataTypeCache cache; - data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.FrozenType(org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.UTF8Type))", native_types); + data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.FrozenType(org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.UTF8Type))", cache); BOOST_REQUIRE(data_type->value_type() == CASS_VALUE_TYPE_LIST); BOOST_CHECK(data_type->is_frozen()); - data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.FrozenType(org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.UTF8Type)))", native_types); + data_type = cass::DataTypeClassNameParser::parse_one("org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.FrozenType(org.apache.cassandra.db.marshal.ListType(org.apache.cassandra.db.marshal.UTF8Type)))", cache); BOOST_REQUIRE(data_type->value_type() == CASS_VALUE_TYPE_LIST); BOOST_CHECK(!data_type->is_frozen()); diff --git a/test/unit_tests/src/test_cql_type_parser.cpp b/test/unit_tests/src/test_cql_type_parser.cpp index 9880f2d29..f77f80569 100644 --- a/test/unit_tests/src/test_cql_type_parser.cpp +++ b/test/unit_tests/src/test_cql_type_parser.cpp @@ -29,69 +29,68 @@ BOOST_AUTO_TEST_CASE(simple) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_cql_names(); + cass::SimpleDataTypeCache cache; cass::KeyspaceMetadata keyspace("keyspace1"); - data_type = cass::DataTypeCqlNameParser::parse("ascii", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("ascii", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_ASCII); - data_type = cass::DataTypeCqlNameParser::parse("bigint", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("bigint", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_BIGINT); - data_type = cass::DataTypeCqlNameParser::parse("blob", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("blob", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_BLOB); - data_type = cass::DataTypeCqlNameParser::parse("boolean", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("boolean", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_BOOLEAN); - data_type = cass::DataTypeCqlNameParser::parse("counter", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("counter", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_COUNTER); - data_type = cass::DataTypeCqlNameParser::parse("date", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("date", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_DATE); - data_type = cass::DataTypeCqlNameParser::parse("decimal", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("decimal", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_DECIMAL); - data_type = cass::DataTypeCqlNameParser::parse("double", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("double", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_DOUBLE); - data_type = cass::DataTypeCqlNameParser::parse("float", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("float", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_FLOAT); - data_type = cass::DataTypeCqlNameParser::parse("inet", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("inet", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_INET); - data_type = cass::DataTypeCqlNameParser::parse("int", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("int", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_INT); - data_type = cass::DataTypeCqlNameParser::parse("smallint", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("smallint", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_SMALL_INT); - data_type = cass::DataTypeCqlNameParser::parse("time", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("time", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_TIME); - data_type = cass::DataTypeCqlNameParser::parse("timestamp", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("timestamp", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_TIMESTAMP); - data_type = cass::DataTypeCqlNameParser::parse("timeuuid", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("timeuuid", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_TIMEUUID); - data_type = cass::DataTypeCqlNameParser::parse("tinyint", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("tinyint", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_TINY_INT); - data_type = cass::DataTypeCqlNameParser::parse("text", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("text", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_TEXT); - data_type = cass::DataTypeCqlNameParser::parse("uuid", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("uuid", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_UUID); - data_type = cass::DataTypeCqlNameParser::parse("varchar", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("varchar", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_VARCHAR); - data_type = cass::DataTypeCqlNameParser::parse("varint", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("varint", cache, &keyspace); BOOST_CHECK_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_VARINT); } @@ -99,24 +98,23 @@ BOOST_AUTO_TEST_CASE(collections) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_cql_names(); + cass::SimpleDataTypeCache cache; cass::KeyspaceMetadata keyspace("keyspace1"); - data_type = cass::DataTypeCqlNameParser::parse("list", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("list", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_LIST); cass::CollectionType::ConstPtr list = static_cast(data_type); BOOST_REQUIRE_EQUAL(list->types().size(), 1); BOOST_CHECK_EQUAL(list->types()[0]->value_type(), CASS_VALUE_TYPE_INT); - data_type = cass::DataTypeCqlNameParser::parse("set", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("set", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_SET); cass::CollectionType::ConstPtr set = static_cast(data_type); BOOST_REQUIRE_EQUAL(set->types().size(), 1); BOOST_CHECK_EQUAL(set->types()[0]->value_type(), CASS_VALUE_TYPE_INT); - data_type = cass::DataTypeCqlNameParser::parse("map", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("map", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_MAP); cass::CollectionType::ConstPtr map = static_cast(data_type); BOOST_REQUIRE_EQUAL(map->types().size(), 2); @@ -128,12 +126,11 @@ BOOST_AUTO_TEST_CASE(tuple) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_cql_names(); + cass::SimpleDataTypeCache cache; cass::KeyspaceMetadata keyspace("keyspace1"); - data_type = cass::DataTypeCqlNameParser::parse("tuple", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("tuple", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_TUPLE); cass::CollectionType::ConstPtr tuple = static_cast(data_type); BOOST_REQUIRE_EQUAL(tuple->types().size(), 3); @@ -146,14 +143,13 @@ BOOST_AUTO_TEST_CASE(udt) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_cql_names(); + cass::SimpleDataTypeCache cache; cass::KeyspaceMetadata keyspace("keyspace1"); BOOST_CHECK(keyspace.user_types().empty()); - data_type = cass::DataTypeCqlNameParser::parse("type1", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("type1", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_UDT); cass::UserType::ConstPtr udt = static_cast(data_type); @@ -167,13 +163,12 @@ BOOST_AUTO_TEST_CASE(frozen) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_cql_names(); + cass::SimpleDataTypeCache cache; cass::KeyspaceMetadata keyspace("keyspace1"); { - data_type = cass::DataTypeCqlNameParser::parse("frozen>", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("frozen>", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_LIST); cass::CollectionType::ConstPtr list = static_cast(data_type); BOOST_REQUIRE_EQUAL(list->types().size(), 1); @@ -182,7 +177,7 @@ BOOST_AUTO_TEST_CASE(frozen) } { - data_type = cass::DataTypeCqlNameParser::parse("list>>", native_types, &keyspace); + data_type = cass::DataTypeCqlNameParser::parse("list>>", cache, &keyspace); BOOST_REQUIRE_EQUAL(data_type->value_type(), CASS_VALUE_TYPE_LIST); cass::CollectionType::ConstPtr list = static_cast(data_type); BOOST_REQUIRE_EQUAL(list->types().size(), 1); @@ -197,31 +192,30 @@ BOOST_AUTO_TEST_CASE(invalid) { cass::DataType::ConstPtr data_type; - cass::NativeDataTypes native_types; - native_types.init_cql_names(); + cass::SimpleDataTypeCache cache; cass::KeyspaceMetadata keyspace("keyspace1"); // Invalid number of parameters - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list<>", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("set<>", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("map<>", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("tuple<>", native_types, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list<>", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("set<>", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("map<>", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("tuple<>", cache, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("set", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("map", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("map", native_types, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("set", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("map", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("map", cache, &keyspace)); // Invalid brackets - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list<", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list>", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("<>", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("<", native_types, &keyspace)); - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse(">", native_types, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list<", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("list>", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("<>", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("<", cache, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse(">", cache, &keyspace)); // Empty - BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("", native_types, &keyspace)); + BOOST_CHECK(!cass::DataTypeCqlNameParser::parse("", cache, &keyspace)); } BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit_tests/src/test_data_type.cpp b/test/unit_tests/src/test_data_type.cpp index b39dfe9f9..bb1762ec5 100644 --- a/test/unit_tests/src/test_data_type.cpp +++ b/test/unit_tests/src/test_data_type.cpp @@ -18,6 +18,7 @@ # define BOOST_TEST_MODULE cassandra #endif +#include "cassandra.h" #include "data_type.hpp" #include @@ -382,6 +383,66 @@ BOOST_AUTO_TEST_CASE(subtypes) } } +BOOST_AUTO_TEST_CASE(value_types_by_class) +{ +#define XX_VALUE_TYPE(name, type, cql, klass) \ + BOOST_CHECK(strlen(klass) == 0 || \ + cass::ValueTypes::by_class(klass) == name); \ + + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE +} + +BOOST_AUTO_TEST_CASE(value_types_by_class_case_insensitive) +{ +#define XX_VALUE_TYPE(name, type, cql, klass) { \ + std::string upper(klass); \ + std::transform(upper.begin(), upper.end(), upper.begin(), toupper); \ + BOOST_CHECK(upper.empty() || cass::ValueTypes::by_class(upper) == name); \ + } + + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE +} + +BOOST_AUTO_TEST_CASE(value_types_by_cql) +{ +#define XX_VALUE_TYPE(name, type, cql, klass) \ + BOOST_CHECK(strlen(cql) == 0 || \ + cass::ValueTypes::by_cql(cql) == name); \ + + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE +} + +BOOST_AUTO_TEST_CASE(value_types_by_cql_case_insensitive) +{ +#define XX_VALUE_TYPE(name, type, cql, klass) { \ + std::string upper(cql); \ + std::transform(upper.begin(), upper.end(), upper.begin(), toupper); \ + BOOST_CHECK(upper.empty() || cass::ValueTypes::by_cql(upper) == name); \ + } + + CASS_VALUE_TYPE_MAPPING(XX_VALUE_TYPE) +#undef XX_VALUE_TYPE +} + +BOOST_AUTO_TEST_CASE(simple_data_type_cache) +{ + cass::SimpleDataTypeCache cache; + + cass::DataType::ConstPtr by_class = cache.by_class("org.apache.cassandra.db.marshal.AsciiType"); + cass::DataType::ConstPtr by_cql = cache.by_cql("ascii"); + cass::DataType::ConstPtr by_value_type = cache.by_value_type(CASS_VALUE_TYPE_ASCII); + + BOOST_CHECK(by_class->value_type() == CASS_VALUE_TYPE_ASCII); + BOOST_CHECK(by_cql->value_type() == CASS_VALUE_TYPE_ASCII); + BOOST_CHECK(by_value_type->value_type() == CASS_VALUE_TYPE_ASCII); + + BOOST_CHECK(by_class.get() == by_cql.get()); + BOOST_CHECK(by_class.get() == by_value_type.get()); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit_tests/src/test_fixed_vector.cpp b/test/unit_tests/src/test_small_vector.cpp similarity index 92% rename from test/unit_tests/src/test_fixed_vector.cpp rename to test/unit_tests/src/test_small_vector.cpp index 2aec856d2..8256da26e 100644 --- a/test/unit_tests/src/test_fixed_vector.cpp +++ b/test/unit_tests/src/test_small_vector.cpp @@ -18,15 +18,15 @@ # define BOOST_TEST_MODULE cassandra #endif -#include "fixed_vector.hpp" +#include "small_vector.hpp" #include -BOOST_AUTO_TEST_SUITE(fixed_vector) +BOOST_AUTO_TEST_SUITE(small_vector) BOOST_AUTO_TEST_CASE(simple) { - cass::FixedVector vec; + cass::SmallVector vec; BOOST_CHECK(vec.fixed().data.address() == vec.data()); BOOST_CHECK(vec.fixed().is_used == true); diff --git a/test/unit_tests/src/test_utils.cpp b/test/unit_tests/src/test_utils.cpp index ecc5667ef..d6504a7a6 100644 --- a/test/unit_tests/src/test_utils.cpp +++ b/test/unit_tests/src/test_utils.cpp @@ -18,6 +18,7 @@ # define BOOST_TEST_MODULE cassandra #endif +#include "macros.hpp" #include "utils.hpp" #include @@ -72,4 +73,25 @@ BOOST_AUTO_TEST_CASE(num_leading_zeros) BOOST_CHECK_EQUAL(0, cass::num_leading_zeros(1LL << 63 | 1 << 5)); } +BOOST_AUTO_TEST_CASE(next_pow_2) +{ + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(1u), 2u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(1u), 2u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(2u), 2u); + + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(3u), 4u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(4u), 4u); + + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(7u), 8u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(8u), 8u); + + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(9u), 16u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(15u), 16u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(16u), 16u); + + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(17u), 32u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(31u), 32u); + BOOST_CHECK_EQUAL(STATIC_NEXT_POW_2(32u), 32u); +} + BOOST_AUTO_TEST_SUITE_END()