// 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;
  }
예제 #5
0
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);
}