Eliminate use of iterator objects in accessor loops.
diff --git a/storage/BasicColumnStoreTupleStorageSubBlock.cpp b/storage/BasicColumnStoreTupleStorageSubBlock.cpp index 0c913ff..984e09d 100644 --- a/storage/BasicColumnStoreTupleStorageSubBlock.cpp +++ b/storage/BasicColumnStoreTupleStorageSubBlock.cpp
@@ -272,49 +272,45 @@ InvokeOnAnyValueAccessor( accessor, [&](auto *accessor) -> void { // NOLINT(build/c++11) + const std::size_t num_attrs = relation_.size(); + const std::vector<std::size_t> &attrs_max_size = + relation_.getMaximumAttributeByteLengths(); + if (relation_.hasNullableAttributes()) { while (this->hasSpaceToInsert(1) && accessor->next()) { - attribute_id accessor_attr_id = 0; // TODO(chasseur): Column-wise copy is probably preferable to // tuple-at-a-time, but will require some API changes. - for (CatalogRelationSchema::const_iterator attr_it = relation_.begin(); - attr_it != relation_.end(); - ++attr_it) { - const attribute_id attr_id = attr_it->getID(); - const std::size_t attr_size = attr_it->getType().maximumByteLength(); - if (attr_it->getType().isNullable()) { + for (std::size_t curr_attr = 0; curr_attr < num_attrs; ++curr_attr) { + const std::size_t attr_size = attrs_max_size[curr_attr]; + // Check if the attribute is nullable. + if (relation_.getNullableAttributeIndex(curr_attr) != kInvalidCatalogId) { const void *attr_value - = accessor->template getUntypedValue<true>(accessor_attr_id); + = accessor->template getUntypedValue<true>(curr_attr); if (attr_value == nullptr) { - column_null_bitmaps_[attr_id].setBit(header_->num_tuples, true); + column_null_bitmaps_[curr_attr].setBit(header_->num_tuples, true); } else { - memcpy(static_cast<char*>(column_stripes_[attr_id]) + memcpy(static_cast<char*>(column_stripes_[curr_attr]) + header_->num_tuples * attr_size, attr_value, attr_size); } } else { - memcpy(static_cast<char*>(column_stripes_[attr_id]) + memcpy(static_cast<char*>(column_stripes_[curr_attr]) + header_->num_tuples * attr_size, - accessor->template getUntypedValue<false>(accessor_attr_id), + accessor->template getUntypedValue<false>(curr_attr), attr_size); } - ++accessor_attr_id; } ++(header_->num_tuples); } } else { while (this->hasSpaceToInsert(1) && accessor->next()) { - attribute_id accessor_attr_id = 0; - for (CatalogRelationSchema::const_iterator attr_it = relation_.begin(); - attr_it != relation_.end(); - ++attr_it) { - const std::size_t attr_size = attr_it->getType().maximumByteLength(); - memcpy(static_cast<char*>(column_stripes_[attr_it->getID()]) + for (std::size_t curr_attr = 0; curr_attr < num_attrs; ++curr_attr) { + const std::size_t attr_size = attrs_max_size[curr_attr]; + memcpy(static_cast<char*>(column_stripes_[curr_attr]) + header_->num_tuples * attr_size, - accessor->template getUntypedValue<false>(accessor_attr_id), + accessor->template getUntypedValue<false>(curr_attr), attr_size); - ++accessor_attr_id; } ++(header_->num_tuples); } @@ -329,55 +325,51 @@ tuple_id BasicColumnStoreTupleStorageSubBlock::bulkInsertTuplesWithRemappedAttributes( const std::vector<attribute_id> &attribute_map, ValueAccessor *accessor) { - DEBUG_ASSERT(attribute_map.size() == relation_.size()); + DCHECK_EQ(attribute_map.size(), relation_.size()); const tuple_id original_num_tuples = header_->num_tuples; InvokeOnAnyValueAccessor( accessor, [&](auto *accessor) -> void { // NOLINT(build/c++11) + const std::size_t num_attrs = relation_.size(); + const std::vector<std::size_t> &attrs_max_size = + relation_.getMaximumAttributeByteLengths(); + if (relation_.hasNullableAttributes()) { while (this->hasSpaceToInsert(1) && accessor->next()) { - std::vector<attribute_id>::const_iterator attribute_map_it = attribute_map.begin(); // TODO(chasseur): Column-wise copy is probably preferable to // tuple-at-a-time, but will require some API changes. - for (CatalogRelationSchema::const_iterator attr_it = relation_.begin(); - attr_it != relation_.end(); - ++attr_it) { - const attribute_id attr_id = attr_it->getID(); - const std::size_t attr_size = attr_it->getType().maximumByteLength(); - if (attr_it->getType().isNullable()) { + for (std::size_t curr_attr = 0; curr_attr < num_attrs; ++curr_attr) { + const std::size_t attr_size = attrs_max_size[curr_attr]; + // Check if the attribute is nullable. + if (relation_.getNullableAttributeIndex(curr_attr) != kInvalidCatalogId) { const void *attr_value - = accessor->template getUntypedValue<true>(*attribute_map_it); + = accessor->template getUntypedValue<true>(attribute_map[curr_attr]); if (attr_value == nullptr) { - column_null_bitmaps_[attr_id].setBit(header_->num_tuples, true); + column_null_bitmaps_[curr_attr].setBit(header_->num_tuples, true); } else { - memcpy(static_cast<char*>(column_stripes_[attr_id]) + memcpy(static_cast<char*>(column_stripes_[curr_attr]) + header_->num_tuples * attr_size, attr_value, attr_size); } } else { - memcpy(static_cast<char*>(column_stripes_[attr_id]) + memcpy(static_cast<char*>(column_stripes_[curr_attr]) + header_->num_tuples * attr_size, - accessor->template getUntypedValue<false>(*attribute_map_it), + accessor->template getUntypedValue<false>(attribute_map[curr_attr]), attr_size); } - ++attribute_map_it; } ++(header_->num_tuples); } } else { while (this->hasSpaceToInsert(1) && accessor->next()) { - std::vector<attribute_id>::const_iterator attribute_map_it = attribute_map.begin(); - for (CatalogRelationSchema::const_iterator attr_it = relation_.begin(); - attr_it != relation_.end(); - ++attr_it) { - const std::size_t attr_size = attr_it->getType().maximumByteLength(); - memcpy(static_cast<char*>(column_stripes_[attr_it->getID()]) + for (std::size_t curr_attr = 0; curr_attr < num_attrs; ++curr_attr) { + const std::size_t attr_size = attrs_max_size[curr_attr]; + memcpy(static_cast<char*>(column_stripes_[curr_attr]) + header_->num_tuples * attr_size, - accessor->template getUntypedValue<false>(*attribute_map_it), + accessor->template getUntypedValue<false>(attribute_map[curr_attr]), attr_size); - ++attribute_map_it; } ++(header_->num_tuples); }