// TODO(chasseur): Make this heuristic better. std::size_t CompressedPackedRowStoreTupleStorageSubBlock::EstimateBytesPerTuple( const CatalogRelation &relation, const TupleStorageSubBlockDescription &description) { DEBUG_ASSERT(DescriptionIsValid(relation, description)); CompatUnorderedSet<attribute_id>::unordered_set compressed_attributes; for (int compressed_attribute_num = 0; compressed_attribute_num < description.ExtensionSize( CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id); ++compressed_attribute_num) { compressed_attributes.insert(description.GetExtension( CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, compressed_attribute_num)); } size_t total_size = 0; for (CatalogRelation::const_iterator attr_it = relation.begin(); attr_it != relation.end(); ++attr_it) { if (compressed_attributes.find(attr_it->getID()) == compressed_attributes.end()) { total_size += attr_it->getType().estimateAverageByteLength(); } else { // For compressed attributes, estimate 1/3 space. total_size += attr_it->getType().estimateAverageByteLength() / 3; } } return total_size; }
bool CompressedPackedRowStoreTupleStorageSubBlock::DescriptionIsValid( const CatalogRelation &relation, const TupleStorageSubBlockDescription &description) { // Make sure description is initialized and specifies // CompressedPackedRowStore. if (!description.IsInitialized()) { return false; } if (description.sub_block_type() != TupleStorageSubBlockDescription::COMPRESSED_PACKED_ROW_STORE) { return false; } // Make sure relation does not have nullable attributes. if (relation.hasNullableAttributes()) { return false; } // Make sure all the specified compressed attributes exist and can be ordered // by LessComparison. const Comparison &less_comparison = Comparison::GetComparison(Comparison::kLess); CompatUnorderedSet<attribute_id>::unordered_set compressed_variable_length_attributes; for (int compressed_attribute_num = 0; compressed_attribute_num < description.ExtensionSize( CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id); ++compressed_attribute_num) { attribute_id compressed_attribute_id = description.GetExtension( CompressedPackedRowStoreTupleStorageSubBlockDescription::compressed_attribute_id, compressed_attribute_num); if (!relation.hasAttributeWithId(compressed_attribute_id)) { return false; } const Type &attr_type = relation.getAttributeById(compressed_attribute_id).getType(); if (!less_comparison.canCompareTypes(attr_type, attr_type)) { return false; } if (attr_type.isVariableLength()) { compressed_variable_length_attributes.insert(compressed_attribute_id); } } // If the relation has variable-length attributes, make sure they are all // compressed. if (relation.isVariableLength()) { for (CatalogRelation::const_iterator attr_it = relation.begin(); attr_it != relation.end(); ++attr_it) { if (attr_it->getType().isVariableLength()) { if (compressed_variable_length_attributes.find(attr_it->getID()) == compressed_variable_length_attributes.end()) { return false; } } } } return true; }
DefaultBloomFilterSubBlock( const CatalogRelation &relation, const TupleStorageSubBlock &tuple_store, const BloomFilterSubBlockDescription &description, const bool new_block, void *sub_block_memory, const std::size_t sub_block_memory_size) : BloomFilterSubBlock(relation, tuple_store, description, new_block, sub_block_memory, sub_block_memory_size) { // initialize the bloom filters and store them in the sub_block_memory bloom_filter_params_.reset(getBloomFilterConfig()); // number of bytes taken by bloom filter per attribute bloom_filter_size_ = bloom_filter_params_->optimal_parameters.table_size / bits_per_char; CatalogRelation::const_iterator attr_it; void* bloom_filter_addr = sub_block_memory_; bloom_filter_data_.reset(static_cast<unsigned char*>(bloom_filter_addr)); // allocate space for bloom_filter_data_ for (attr_it = relation.begin(); attr_it != relation.end(); ++attr_it) { bloom_filter_addr = (static_cast<unsigned char*>(bloom_filter_addr) + bloom_filter_size_); } // allocate space for bloom_filters_ bloom_filters_.reset(static_cast<BloomFilter*>(bloom_filter_addr)); unsigned int i = 0; for (attr_it = relation.begin(); attr_it != relation.end(); ++attr_it, ++i) { ScopedPtr<BloomFilter> bloomFilter(new BloomFilter(*bloom_filter_params_, bloom_filter_data_.get() + i*bloom_filter_size_ )); memcpy(bloom_filter_addr, bloomFilter.get(), sizeof(*bloomFilter)); bloom_filter_addr = (static_cast<char*>(bloom_filter_addr) + sizeof(BloomFilter)); } } ;
static std::size_t EstimateBytesForTuples(const CatalogRelation &relation, const TupleStorageSubBlockDescription &description) { // initialize bloom filter parameters object ScopedPtr<BloomParameters> bloom_filter_params; bloom_filter_params.reset(getBloomFilterConfig()); // number of bytes taken by bloom filter per attribute std::size_t bloom_filter_size = bloom_filter_params->optimal_parameters.table_size / bits_per_char; size_t total_size = 0; size_t size_per_attribute = bloom_filter_size + sizeof(BloomFilter); CatalogRelation::const_iterator attr_it; for (attr_it = relation.begin(); attr_it != relation.end(); ++attr_it) { total_size += size_per_attribute; } return total_size; }
void PrintToScreen::PrintRelation(const CatalogRelation &relation, StorageManager *storage_manager, FILE *out) { if (!FLAGS_printing_enabled) { return; } vector<int> column_widths; column_widths.reserve(relation.size()); for (CatalogRelation::const_iterator attr_it = relation.begin(); attr_it != relation.end(); ++attr_it) { // Printed column needs to be wide enough to print: // 1. The attribute name (in the printed "header"). // 2. Any value of the attribute's Type. // 3. If the attribute's Type is nullable, the 4-character string "NULL". // We pick the largest of these 3 widths as the column width. int column_width = static_cast<int>(attr_it->getDisplayName().length()); column_width = column_width < attr_it->getType().getPrintWidth() ? attr_it->getType().getPrintWidth() : column_width; column_width = attr_it->getType().isNullable() && (column_width < 4) ? 4 : column_width; column_widths.push_back(column_width); } printHBar(column_widths, out); fputc('|', out); vector<int>::const_iterator width_it = column_widths.begin(); CatalogRelation::const_iterator attr_it = relation.begin(); for (; width_it != column_widths.end(); ++width_it, ++attr_it) { fprintf(out, "%-*s|", *width_it, attr_it->getDisplayName().c_str()); } fputc('\n', out); printHBar(column_widths, out); std::vector<block_id> blocks = relation.getBlocksSnapshot(); for (const block_id current_block_id : blocks) { BlockReference block = storage_manager->getBlock(current_block_id, relation); const TupleStorageSubBlock &tuple_store = block->getTupleStorageSubBlock(); if (tuple_store.isPacked()) { for (tuple_id tid = 0; tid <= tuple_store.getMaxTupleID(); ++tid) { printTuple(tuple_store, tid, column_widths, out); } } else { std::unique_ptr<TupleIdSequence> existence_map(tuple_store.getExistenceMap()); for (tuple_id tid : *existence_map) { printTuple(tuple_store, tid, column_widths, out); } } } printHBar(column_widths, out); }