// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once #include "attrvector.h" #include "load_utils.h" #include "numeric_sort_blob_writer.h" #include "string_sort_blob_writer.h" #include #include namespace search { template NumericDirectAttribute:: NumericDirectAttribute(const vespalib::string & baseFileName, const Config & c) : B(baseFileName, c), _data(), _idx() { } template NumericDirectAttribute::~NumericDirectAttribute() = default; template bool NumericDirectAttribute::findEnum(typename B::BaseType key, EnumHandle & e) const { if (_data.empty()) { e = 0; return false; } int delta; const int eMax = B::getEnumMax(); for (delta = 1; delta <= eMax; delta <<= 1) { } delta >>= 1; int pos = delta - 1; typename B::BaseType value = key; while (delta != 0) { delta >>= 1; if (pos >= eMax) { pos -= delta; } else { value = _data[pos]; if (value == key) { e = pos; return true; } else if (value < key) { pos += delta; } else { pos -= delta; } } } e = ((key > value) && (pos < eMax)) ? pos + 1 : pos; return false; } template void NumericDirectAttribute::onCommit() { B::_changes.clear(); HDR_ABORT("should not be reached"); } template bool NumericDirectAttribute::addDoc(DocId & ) { return false; } } template NumericDirectAttrVector:: NumericDirectAttrVector(const vespalib::string & baseFileName, const AttributeVector::Config & c) : search::NumericDirectAttribute(baseFileName, c) { if (F::IsMultiValue()) { this->_idx.push_back(0); } } template NumericDirectAttrVector:: NumericDirectAttrVector(const vespalib::string & baseFileName) : search::NumericDirectAttribute(baseFileName, AttributeVector::Config(AttributeVector::BasicType::fromType(BaseType()), F::IsMultiValue() ? search::attribute::CollectionType::ARRAY : search::attribute::CollectionType::SINGLE)) { if (F::IsMultiValue()) { this->_idx.push_back(0); } } template template long NumericDirectAttrVector::on_serialize_for_sort(DocId doc, void* serTo, long available) const { search::attribute::NumericSortBlobWriter writer; vespalib::ConstArrayRef values(this->_data.data() + this->_idx[doc], this->_idx[doc + 1] - this->_idx[doc]); for (auto& v : values) { writer.candidate(v); } return writer.write(serTo, available); } template long NumericDirectAttrVector::onSerializeForAscendingSort(DocId doc, void* serTo, long available, const search::common::BlobConverter* bc) const { if (!F::IsMultiValue()) { return search::NumericDirectAttribute::onSerializeForAscendingSort(doc, serTo, available, bc); } return on_serialize_for_sort(doc, serTo, available); } template long NumericDirectAttrVector::onSerializeForDescendingSort(DocId doc, void* serTo, long available, const search::common::BlobConverter* bc) const { if (!F::IsMultiValue()) { return search::NumericDirectAttribute::onSerializeForDescendingSort(doc, serTo, available, bc); } return on_serialize_for_sort(doc, serTo, available); } template StringDirectAttrVector:: StringDirectAttrVector(const vespalib::string & baseFileName, const Config & c) : search::StringDirectAttribute(baseFileName, c) { if (F::IsMultiValue()) { _idx.push_back(0); } setEnum(true); } template StringDirectAttrVector:: StringDirectAttrVector(const vespalib::string & baseFileName) : search::StringDirectAttribute(baseFileName, Config(BasicType::STRING, F::IsMultiValue() ? search::attribute::CollectionType::ARRAY : search::attribute::CollectionType::SINGLE)) { if (F::IsMultiValue()) { _idx.push_back(0); } setEnum(true); } template long StringDirectAttrVector::on_serialize_for_sort(DocId doc, void* serTo, long available, const search::common::BlobConverter* bc, bool asc) const { search::attribute::StringSortBlobWriter writer(serTo, available, bc, asc); vespalib::ConstArrayRef offsets(this->_offsets.data() + this->_idx[doc], this->_idx[doc + 1] - this->_idx[doc]); for (auto& offset : offsets) { if (!writer.candidate(&this->_buffer[offset])) { return -1; } } return writer.write(); } template long StringDirectAttrVector::onSerializeForAscendingSort(DocId doc, void* serTo, long available, const search::common::BlobConverter* bc) const { if (!F::IsMultiValue()) { return search::StringDirectAttribute::onSerializeForAscendingSort(doc, serTo, available, bc); } return on_serialize_for_sort(doc, serTo, available, bc, true); } template long StringDirectAttrVector::onSerializeForDescendingSort(DocId doc, void* serTo, long available, const search::common::BlobConverter* bc) const { if (!F::IsMultiValue()) { return search::StringDirectAttribute::onSerializeForDescendingSort(doc, serTo, available, bc); } return on_serialize_for_sort(doc, serTo, available, bc, false); }