31 #include <boost/algorithm/string.hpp>
32 #include <boost/scoped_array.hpp>
64 const uint32_t MAX_APPENDS_OUTSTANDING = 3;
65 const uint16_t BLOCK_HEADER_FORMAT = 0;
70 : m_filesys(filesys) {
72 assert(
sizeof(
float) == 4);
76 : m_filesys(filesys), m_schema(schema) {
78 assert(
sizeof(
float) == 4);
109 lock_guard<mutex> lock(
m_mutex);
124 lock_guard<mutex> lock(
m_mutex);
148 lock_guard<mutex> lock(
m_mutex);
156 return make_shared<CellStoreScanner<CellStoreBlockIndexArray<int64_t>>>(shared_from_this(), scan_ctx, need_index ? &
m_index_map64 : 0);
157 return make_shared<CellStoreScanner<CellStoreBlockIndexArray<uint32_t>>>(shared_from_this(), scan_ctx, need_index ? &
m_index_map32 : 0);
163 int32_t replication = props->get_i32(
"replication", int32_t(-1));
165 if (replication == -1 && table_id) {
167 if (
Config::has(
"Hypertable.RangeServer.Data.DefaultReplication"))
168 replication = Config::get_i32(
"Hypertable.RangeServer.Data.DefaultReplication");
170 else if (
Config::has(
"Hypertable.Metadata.Replication"))
171 replication = Config::get_i32(
"Hypertable.Metadata.Replication");
181 int64_t blocksize = props->get(
"blocksize", 0);
187 int32_t replication = get_replication(props, table_id);
190 blocksize = Config::get_i32(
"Hypertable.RangeServer.CellStore"
191 ".DefaultBlockSize");
192 if (compressor.empty())
193 compressor = Config::get_str(
"Hypertable.RangeServer.CellStore"
194 ".DefaultCompressor");
195 if (!props->has(
"bloom-filter-mode")) {
198 ".CellStore.DefaultBloomFilter"), props);
221 for (
size_t i=0; i<column_family_specs.size(); i++) {
222 if (column_family_specs[i]->get_option_ttl()) {
227 m_column_ttl[ column_family_specs[i]->get_id() ] = column_family_specs[i]->get_option_ttl() * 1000000000LL;
250 bool has_num_hashes = props->has(
"num-hashes");
251 bool has_bits_per_item = props->has(
"bits-per-item");
253 if (has_num_hashes || has_bits_per_item) {
254 if (!(has_num_hashes && has_bits_per_item)) {
255 HT_WARN(
"Bloom filter option --bits-per-item must be used with "
256 "--num-hashes, defaulting to false probability of 0.01");
269 <<
" max-approx-items="<< m_max_approx_items <<
" false-positive="
277 HT_DEBUG_OUT <<
"Creating new BloomFilter for CellStore '"
278 <<
m_filename <<
"' for "<< (is_approx ?
"estimated " :
"")
290 HT_FATAL_OUT <<
"Error creating new BloomFilter for CellStore '"
291 << m_filename <<
"' for "<< (is_approx ?
"estimated " :
"")
292 << m_trailer.filter_items_estimate <<
" items - "<< e <<
HT_END;
295 for (
const auto &blob : *m_bloom_filter_items)
296 m_bloom_filter->insert(blob.start, blob.size);
298 delete m_bloom_filter_items;
299 m_bloom_filter_items = 0;
301 HT_DEBUG_OUT <<
"Created new BloomFilter for CellStore '"
302 << m_filename <<
"'"<<
HT_END;
305 const std::vector<String> &CellStoreV6::get_replaced_files() {
306 lock_guard<mutex> lock(
m_mutex);
313 bool second_try =
false;
327 "CellStore '%s' : tried to read %lld but only got %lld",
333 const uint8_t *ptr = buf.
base;
337 "Bad replaced_files_offset in CellStore trailer fd=%u replaced_files_offset=%lld, "
338 "length=%llu, entries=%u, file='%s'", (
unsigned)
m_fd,
341 ptr = decompressor.add(ptr);
342 decompressor.load(filename);
349 << amount <<
")\n" <<
HT_END;
374 HT_FATAL_OUT <<
"Error loading BloomFilter for CellStore '"
376 <<
" items -"<< e <<
HT_END;
381 bool second_try =
false;
401 "CellStore '%s' : tried to read %lld but only got %lld",
417 uint64_t memory_purged = 0;
420 lock_guard<mutex> lock(
m_mutex);
441 return memory_purged;
478 "Problem writing to FS file '%s' : %s",
m_filename.c_str(),
481 "Problem writing to FS file '%s'",
m_filename.c_str());
491 size_t zlen = zbuf.
fill();
507 size_t value_len = value.
length();
530 m_bloom_filter_items->insert(key.
row, key.
row_len);
533 m_bloom_filter_items->insert(key.
row, key.
row_len + 2);
563 int64_t index_memory = 0;
584 "Problem finalizing CellStore file '%s' : %s",
664 if (m_bloom_filter_items && m_bloom_filter_items->size() > 0) {
684 size_t compressed_len = 0;
686 bool coalesce_with_trailer =
false;
689 compressed_len += compressor.
length();
693 coalesce_with_trailer =
true;
710 if (!coalesce_with_trailer) {
725 double fraction_covered;
757 if (!coalesce_with_trailer) {
766 memset(zbuf.
ptr, 0, padding);
808 if (!
m_bigint && offset >= 4294967296LL) {
811 uint8_t *dst = tmp_buf.
base;
825 size_t key_len = key_compressor->length_uncompressed();
848 base = m_fixed.release(&len);
849 m_fixed.reserve(len);
850 m_fixed.add_unchecked(base, len);
853 base = m_variable.release(&len);
854 m_variable.reserve(len);
855 m_variable.add_unchecked(base, len);
863 const String &end_row, int32_t fd, int64_t file_length,
886 "Bad index offsets in CellStore trailer fd=%u fix=%lld, var=%lld, "
901 lock_guard<mutex> lock(
m_mutex);
933 int64_t amount, index_amount;
937 bool inflating_fixed=
true;
938 bool second_try =
false;
956 "CellStore '%s' : tried to read %lld but only got %lld",
964 inflating_fixed =
false;
973 vbuf.
ptr = buf.
ptr + amount;
984 if (inflating_fixed) {
985 msg =
String(
"Error inflating FIXED index for cellstore '")
990 msg =
"Error inflating VARIABLE index for cellstore '" +
m_filename +
"'";
994 << index_amount <<
")\n" <<
HT_END;
1038 lock_guard<mutex> lock(
m_mutex);
1054 size_t rowlen = scan_ctx->
start_row.length();
1055 uint8_t column_family_id;
1057 boost::scoped_array<char> rowcol(
new char[rowlen + 2]);
1058 memcpy(rowcol.get(), scan_ctx->
start_row.c_str(), rowlen + 1);
1061 if ((ptr = strchr(col,
':')) != 0) {
1062 String family(col, (
size_t)(ptr-col));
1063 column_family_id = schema->get_column_family(family.c_str())->get_id();
1066 column_family_id = schema->get_column_family(col)->get_id();
1068 rowcol[rowlen + 1] = column_family_id;
1077 HT_ASSERT(!
"unpossible bloom filter mode!");
1086 lock_guard<mutex> lock(
m_mutex);
1097 return BLOCK_HEADER_FORMAT;
size_t get_num_hashes()
Getter for the number of hash functions.
void free()
Frees resources.
size_t get_items_actual()
Getter for the actual number of items.
DynamicBuffer & fixed_buf()
int64_t filter_items_actual
uint64_t bloom_filter_access_counter
int64_t m_uncompressed_blocksize
static const char INDEX_FIXED_BLOCK_MAGIC[10]
#define HT_THROW2F(_code_, _ex_, _fmt_,...)
virtual size_t size()
Returns the serialized size of the trailer.
A memory buffer of static size.
Retrieves system information (hardware, installation directory, etc)
int64_t m_max_approx_items
virtual void append(int fd, StaticBuffer &buffer, Flags flags, DispatchHandler *handler)=0
Appends data to a file asynchronously.
Abstract base class for cell store trailer.
virtual void close(int fd, DispatchHandler *handler)=0
Closes a file asynchronously.
virtual void serialize(uint8_t *buf)
Serializes this trailer to the given buffer;.
void add(const Key &key, const ByteString value) override
Inserts a key/value pair into the cell list.
#define HT_IO_ALIGNMENT_PADDING(size)
Cell list scanner over a buffer of cells.
#define HT_WARNF(msg,...)
CellListScannerPtr create_scanner(ScanContext *scan_ctx) override
Creates a scanner on this cell list.
virtual void pread(int fd, size_t amount, uint64_t offset, bool verify_checksum, DispatchHandler *handler)=0
Reads data from a file at the specified position asynchronously.
static const char INDEX_VARIABLE_BLOCK_MAGIC[10]
static int32_t response_code(const Event *event)
Returns the response code from an event event generated in response to a request message.
PropertiesPtr properties
This singleton map stores all options.
std::string String
A String is simply a typedef to std::string.
#define HT_IO_ALIGNED(size)
BloomFilterWithChecksum * m_bloom_filter
Bloom filter.
CellStoreV6(Filesystem *filesys)
static String string_format_message(const Event *event)
Returns error message decoded standard error MESSAGE generated in response to a request message...
void finalize(TableIdentifier *table_identifier) override
Finalizes the creation of a cell store, by writing block index and metadata trailer.
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
std::shared_ptr< KeyCompressor > KeyCompressorPtr
int64_t replaced_files_offset
A class to decompress prefix-compressed strings.
BlockCompressionCodec::Args m_compressor_args
long long unsigned int Llu
Shortcut for printf formats.
BloomFilterMode m_bloom_filter_mode
Declarations for CellStoreScanner.
static void parse_bloom_filter(const std::string &spec, PropertiesPtr &props)
Parsers a bloom filter specification and sets properties.
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
void load_replaced_files()
Scan context information.
uint32_t m_index_refcount
KeyCompressorPtr m_key_compressor
Type
Enumeration for compression type.
uint8_t * ptr
Pointer to the end of the used part of the buffer.
uint16_t key_compression_scheme
bool wait_for_reply(EventPtr &event)
This method is used by a client to synchronize.
A dynamic, resizable and reference counted memory buffer.
virtual void reset()
Clears the internal state.
void add_disk_read(int64_t amount)
uint32_t decode_i32(const uint8_t **bufp, size_t *remainp)
Decode a 32-bit integer in little-endian order.
DynamicBuffer & variable_buf()
bool has(const String &name)
Check existence of a configuration value.
A class managing one or more serializable ByteStrings.
void create_bloom_filter(bool is_approx=false)
void serialize(StaticBuffer &buf)
Serializes the BloomFilter into a static memory buffer.
IndexMemoryStats m_index_stats
static BlockCompressionCodec::Type parse_block_codec_spec(const std::string &spec, BlockCompressionCodec::Args &args)
Given a block codec config string return its type and put config.
size_t total_size()
Getter for the total size (including checksum and metadata)
static Hypertable::MemoryTracker * memory_tracker
uint64_t block_index_access_counter
DispatchHandlerSynchronizer m_sync_handler
std::map< const char *, int64_t, LtCstr, SplitRowDataAlloc > SplitRowDataMapT
CellStoreBlockIndexArray< uint32_t > m_index_map32
32-bit block index
float m_uncompressed_data
double fraction_covered()
static uint64_t access_counter
IndexBuilder m_index_builder
std::shared_ptr< Properties > PropertiesPtr
uint32_t size
The size of the allocated memory buffer (base)
Logging routines and macros.
BloomFilterMode
Enumeration for bloom filter modes.
Compatibility Macros for C/C++.
uint32_t m_outstanding_appends
BloomFilterItems * m_bloom_filter_items
int64_t block_index_memory
void insert(const void *key, size_t len)
Inserts a new blob into the hash.
BlobHashSet BloomFilterItems
void encode_i64(uint8_t **bufp, uint64_t val)
Encode a 64-bit integer in little-endian order.
uint8_t bloom_filter_hash_count
void populate_index_pseudo_table_scanner(CellListScannerBuffer *scanner) override
Populates scanner with key/value pairs generated from CellStore index.
static const int64_t TIMESTAMP_NULL
size_t length() const
Retrieves the length of the serialized string.
static BlockCompressionCodec * create_block_codec(BlockCompressionCodec::Type, const BlockCompressionCodec::Args &args=BlockCompressionCodec::Args())
uint32_t replaced_files_entries
void display_block_info() override
Displays block information to stdout.
Time related declarations.
int64_t filter_items_estimate
size_t get_length_bits()
Getter for the number of bits.
CellStoreTrailerV6 m_trailer
void rescope(const String &start_row, const String &end_row) override
uint8_t bloom_filter_mode
bool own
If true then the buffer (base) will be released when going out of scope; if false then the caller has...
const uint8_t * ptr
The pointer to the serialized data.
BlockCompressionCodec * create_block_compression_codec() override
Creates a block compression codec suitable for decompressing the cell store's blocks.
long long int Lld
Shortcut for printf formats.
uint16_t compression_type
uint32_t table_generation
void load(DynamicBuffer &fixed, DynamicBuffer &variable, int64_t end_of_data, const String &start_row="", const String &end_row="")
void clear()
Clears the buffer.
std::vector< String > m_replaced_files
void open(const String &fname, const String &start_row, const String &end_row, int32_t fd, int64_t file_length, CellStoreTrailer *trailer) override
Opens a cell store with possibly a restricted view.
virtual void write(uint8_t *buf) const
Writes the compressed string to a buffer.
virtual void clear()
Clears the contents of this trailer;.
bool may_contain(ScanContext *scan_ctx) override
Bloom filter lookup.
A class to decompress prefix-compressed strings.
BlockCompressionCodec * m_compressor
void validate(String &filename)
Validates the checksum of the BloomFilter.
Declarations for Protocol.
virtual size_t length() const
Retrieves the length of the compressed string.
#define HT_THROWF(_code_, _fmt_,...)
Provides access to internal components of opaque key.
uint8_t * base
Pointer to the allocated memory buffer.
size_t fill() const
Returns the size of the used portion.
virtual void deflate(const DynamicBuffer &input, DynamicBuffer &output, BlockHeader &header, size_t reserve=0)=0
Compresses a buffer.
static const char DATA_BLOCK_MAGIC[10]
Request/response message event.
void subtract(int64_t amount)
Subtract to memory used.
virtual void add(const char *str)
Adds (and compresses) a string.
This is a generic exception class for Hypertable.
float m_bloom_bits_per_item
int64_t replaced_files_length
bool m_replaced_files_loaded
void populate_pseudo_table_scanner(CellListScannerBuffer *scanner, const String &filename, int32_t keys_per_block, float compression_ratio)
Populates scanner with data for .cellstore.index pseudo table.
CellStoreBlockIndexArray< int64_t > m_index_map64
64-bit block index
uint8_t * release(size_t *lenp=0)
Moves ownership of the buffer to the caller.
std::shared_ptr< Schema > SchemaPtr
Smart pointer to Schema.
uint8_t column_family_code
std::shared_ptr< CellListScanner > CellListScannerPtr
virtual void open(const String &name, uint32_t flags, DispatchHandler *handler)=0
Opens a file asynchronously.
std::vector< ColumnFamilySpec * > ColumnFamilySpecs
Vector of ColumnFamilySpec pointers.
A class to prefix-compress strings.
void rescope(const String &start_row="", const String &end_row="")
BasicBloomFilterWithChecksum BloomFilterWithChecksum
Declarations for CellStoreV6.
int64_t bloom_filter_memory
float m_filter_false_positive_prob
virtual void inflate(const DynamicBuffer &input, DynamicBuffer &output, BlockHeader &header)=0
Decompresses a buffer.
Error codes, Exception handling, error logging.
#define HT_THROW(_code_, _msg_)
static const char * END_ROW_MARKER
void split_row_estimate_data(SplitRowDataMapT &split_row_data) override
Populates split_row_data with unique row and count estimates from block index.
static const uint32_t FLAG_DELETE_CELL_VERSION
void create(const char *fname, size_t max_entries, PropertiesPtr &props, const TableIdentifier *table_id=0) override
Creates a new cell store.
void add(int64_t amount)
Add to memory used.
bool may_contain(const void *key, size_t len) const
Checks if the data set "may" contain the key.
void ensure(size_t len)
Ensure space for additional data Will grow the space to 1.5 of the needed space with existing data un...
static int get_next_file_id()
uint8_t * add_unchecked(const void *data, size_t len)
Adds additional data without boundary checks.
void add_entry(KeyCompressorPtr &key_compressor, int64_t offset)
A class to prefix-compress strings.
void unique_row_count_estimate(CellList::SplitRowDataMapT &split_row_data, int32_t keys_per_block)
Accumulates unique row estimates from block index entries.
uint64_t purge_indexes() override
Purges bloom filter and block indexes.
virtual void create(const String &name, uint32_t flags, int32_t bufsz, int32_t replication, int64_t blksz, DispatchHandler *handler)=0
Creates a file asynchronously.
uint8_t * base()
Getter for the serialized bloom filter data, including metadata and checksums.
KeyDecompressor * create_key_decompressor() override
Creates a key decompressor suitable for decompressing the keys stored in this cell store...
uint16_t block_header_format() override
int64_t get_ts64()
Returns the current time in nanoseconds as a 64bit number.
#define HT_DIRECT_IO_ALIGNMENT
Abstract base class for block compression codecs.
Abstract base class for a filesystem.
int code() const
Returns the error code.
void reserve(size_t len, bool nocopy=false)
Reserve space for additional data Will grow the space to exactly what's needed.
#define HT_THROW2(_code_, _ex_, _msg_)