summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp2
-rw-r--r--searchcore/src/vespa/searchcore/proton/matching/result_processor.cpp10
-rw-r--r--searchlib/src/tests/sortspec/multilevelsort.cpp176
-rw-r--r--searchlib/src/vespa/searchlib/common/sortresults.cpp44
-rw-r--r--searchlib/src/vespa/searchlib/common/sortresults.h15
-rw-r--r--searchlib/src/vespa/searchlib/common/sortspec.cpp10
-rw-r--r--searchlib/src/vespa/searchlib/common/sortspec.h2
7 files changed, 148 insertions, 111 deletions
diff --git a/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp b/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp
index 6f4ebe2b537..4668b8c65ab 100644
--- a/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp
+++ b/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp
@@ -1989,7 +1989,7 @@ TEST(DocumentMetaStoreTest, serialize_for_sort)
EXPECT_EQ(SZ, dms.serializeForAscendingSort(2, asc_dest, sizeof(asc_dest), nullptr));
EXPECT_TRUE(dms.getGid(2, gid));
EXPECT_EQ(0, memcmp(asc_dest, gid.get(), SZ));
-
+
uint8_t desc_dest[SZ];
EXPECT_EQ(SZ, dms.serializeForDescendingSort(2, desc_dest, sizeof(desc_dest), nullptr));
for (size_t i(0); i < SZ; i++) {
diff --git a/searchcore/src/vespa/searchcore/proton/matching/result_processor.cpp b/searchcore/src/vespa/searchcore/proton/matching/result_processor.cpp
index f332ca5ec26..ce1f30593c5 100644
--- a/searchcore/src/vespa/searchcore/proton/matching/result_processor.cpp
+++ b/searchcore/src/vespa/searchcore/proton/matching/result_processor.cpp
@@ -28,7 +28,7 @@ ResultProcessor::Result::~Result() = default;
ResultProcessor::Sort::Sort(uint32_t partitionId, const vespalib::Doom & doom, IAttributeContext &ac, const vespalib::string &ss)
: sorter(FastS_DefaultResultSorter::instance()),
_ucaFactory(std::make_unique<search::uca::UcaConverterFactory>()),
- sortSpec(partitionId, doom, *_ucaFactory)
+ sortSpec("[no-metastore]", partitionId, doom, *_ucaFactory)
{
if (!ss.empty() && sortSpec.Init(ss.c_str(), ac)) {
sorter = &sortSpec;
@@ -46,9 +46,9 @@ ResultProcessor::Context::~Context() = default;
void
ResultProcessor::GroupingSource::merge(Source &s) {
- GroupingSource &rhs = static_cast<GroupingSource&>(s);
- assert((ctx == 0) == (rhs.ctx == 0));
- if (ctx != 0) {
+ auto &rhs = dynamic_cast<GroupingSource&>(s);
+ assert((ctx == nullptr) == (rhs.ctx == nullptr));
+ if (ctx != nullptr) {
search::grouping::GroupingManager man(*ctx);
man.merge(*rhs.ctx);
}
@@ -112,7 +112,7 @@ ResultProcessor::extract_docid_ordering(const PartialResult &result) const
}
std::sort(list.begin(), list.end(), [](const auto &a, const auto &b){ return (a.first < b.first); });
return list;
-};
+}
ResultProcessor::Result::UP
ResultProcessor::makeReply(PartialResultUP full_result)
diff --git a/searchlib/src/tests/sortspec/multilevelsort.cpp b/searchlib/src/tests/sortspec/multilevelsort.cpp
index 82bdf99ab2c..87dc6608c3f 100644
--- a/searchlib/src/tests/sortspec/multilevelsort.cpp
+++ b/searchlib/src/tests/sortspec/multilevelsort.cpp
@@ -16,11 +16,6 @@ LOG_SETUP("multilevelsort_test");
using namespace search;
-typedef FastS_SortSpec::VectorRef VectorRef;
-typedef IntegerAttributeTemplate<int8_t> Int8;
-typedef IntegerAttributeTemplate<int16_t> Int16;
-typedef IntegerAttributeTemplate<int32_t> Int32;
-typedef IntegerAttributeTemplate<int64_t> Int64;
typedef FloatingPointAttributeTemplate<float> Float;
typedef FloatingPointAttributeTemplate<double> Double;
typedef std::map<std::string, AttributeVector::SP > VectorMap;
@@ -53,16 +48,16 @@ public:
};
private:
template<typename T>
- T getRandomValue() {
+ static T getRandomValue() {
T min = std::numeric_limits<T>::min();
T max = std::numeric_limits<T>::max();
return static_cast<T>(double(min) + (double(max) - double(min)) * (double(rand()) / double(RAND_MAX)));
}
template<typename T>
- void fill(IntegerAttribute *attr, uint32_t size, uint32_t unique = 0);
+ static void fill(IntegerAttribute *attr, uint32_t size, uint32_t unique = 0);
template<typename T>
- void fill(FloatingPointAttribute *attr, uint32_t size, uint32_t unique = 0);
- void fill(StringAttribute *attr, uint32_t size, const std::vector<std::string> &values);
+ static void fill(FloatingPointAttribute *attr, uint32_t size, uint32_t unique = 0);
+ static void fill(StringAttribute *attr, uint32_t size, const std::vector<std::string> &values);
template <typename V>
int compareTemplate(AttributeVector *vector, uint32_t a, uint32_t b);
int compare(AttributeVector *vector, AttrType type, uint32_t a, uint32_t b);
@@ -181,7 +176,7 @@ MultilevelSortTest::compare(AttributeVector *vector, AttrType type, uint32_t a,
} else if (type == DOUBLE) {
return compareTemplate<double>(vector, a, b);
} else if (type == STRING) {
- StringAttribute *vString = static_cast<StringAttribute*>(vector);
+ StringAttribute *vString = dynamic_cast<StringAttribute*>(vector);
const char *va = vString->get(a);
const char *vb = vString->get(b);
std::string sa(va);
@@ -199,106 +194,99 @@ MultilevelSortTest::compare(AttributeVector *vector, AttrType type, uint32_t a,
}
void
-MultilevelSortTest::sortAndCheck(const std::vector<Spec> &spec, uint32_t num,
+MultilevelSortTest::sortAndCheck(const std::vector<Spec> &specs, uint32_t num,
uint32_t unique, const std::vector<std::string> &strValues)
{
VectorMap vec;
// generate attribute vectors
- for (uint32_t i = 0; i < spec.size(); ++i) {
- std::string name = spec[i]._name;
- AttrType type = spec[i]._type;
+ for (const auto & spec : specs) {
+ std::string name = spec._name;
+ AttrType type = spec._type;
if (type == INT8) {
Config cfg(BasicType::INT8, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill<int8_t>(static_cast<IntegerAttribute *>(vec[name].get()), num, unique);
+ fill<int8_t>(dynamic_cast<IntegerAttribute *>(vec[name].get()), num, unique);
} else if (type == INT16) {
Config cfg(BasicType::INT16, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill<int16_t>(static_cast<IntegerAttribute *>(vec[name].get()), num, unique);
+ fill<int16_t>(dynamic_cast<IntegerAttribute *>(vec[name].get()), num, unique);
} else if (type == INT32) {
Config cfg(BasicType::INT32, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill<int32_t>(static_cast<IntegerAttribute *>(vec[name].get()), num, unique);
+ fill<int32_t>(dynamic_cast<IntegerAttribute *>(vec[name].get()), num, unique);
} else if (type == INT64) {
Config cfg(BasicType::INT64, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill<int64_t>(static_cast<IntegerAttribute *>(vec[name].get()), num, unique);
+ fill<int64_t>(dynamic_cast<IntegerAttribute *>(vec[name].get()), num, unique);
} else if (type == FLOAT) {
Config cfg(BasicType::FLOAT, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill<float>(static_cast<FloatingPointAttribute *>(vec[name].get()), num, unique);
+ fill<float>(dynamic_cast<FloatingPointAttribute *>(vec[name].get()), num, unique);
} else if (type == DOUBLE) {
Config cfg(BasicType::DOUBLE, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill<double>(static_cast<FloatingPointAttribute *>(vec[name].get()), num, unique);
+ fill<double>(dynamic_cast<FloatingPointAttribute *>(vec[name].get()), num, unique);
} else if (type == STRING) {
Config cfg(BasicType::STRING, CollectionType::SINGLE);
vec[name] = AttributeFactory::createAttribute(name, cfg);
- fill(static_cast<StringAttribute *>(vec[name].get()), num, strValues);
+ fill(dynamic_cast<StringAttribute *>(vec[name].get()), num, strValues);
}
if (vec[name])
vec[name]->commit();
}
- RankedHit *hits = new RankedHit[num];
+ std::vector<RankedHit> hits;
+ hits.reserve(num);
for (uint32_t i = 0; i < num; ++i) {
- hits[i]._docId = i;
- hits[i]._rankValue = getRandomValue<uint32_t>();
+ hits.emplace_back(i, getRandomValue<uint32_t>());
}
vespalib::TestClock clock;
vespalib::Doom doom(clock.clock(), vespalib::steady_time::max());
search::uca::UcaConverterFactory ucaFactory;
- FastS_SortSpec sorter(7, doom, ucaFactory);
+ FastS_SortSpec sorter("no-metastore", 7, doom, ucaFactory);
// init sorter with sort data
- for(uint32_t i = 0; i < spec.size(); ++i) {
+ for (const auto & spec : specs) {
AttributeGuard ag;
- if (spec[i]._type == RANK) {
- sorter._vectors.push_back
- (VectorRef(spec[i]._asc ? FastS_SortSpec::ASC_RANK :
- FastS_SortSpec::DESC_RANK, nullptr, nullptr));
- } else if (spec[i]._type == DOCID) {
- sorter._vectors.push_back
- (VectorRef(spec[i]._asc ? FastS_SortSpec::ASC_DOCID :
- FastS_SortSpec::DESC_DOCID, nullptr, nullptr));
+ if (spec._type == RANK) {
+ sorter._vectors.emplace_back(spec._asc ? FastS_SortSpec::ASC_RANK : FastS_SortSpec::DESC_RANK, nullptr, nullptr);
+ } else if (spec._type == DOCID) {
+ sorter._vectors.emplace_back(spec._asc ? FastS_SortSpec::ASC_DOCID : FastS_SortSpec::DESC_DOCID, nullptr, nullptr);
} else {
- const search::attribute::IAttributeVector * v = vec[spec[i]._name].get();
- sorter._vectors.push_back
- (VectorRef(spec[i]._asc ? FastS_SortSpec::ASC_VECTOR :
- FastS_SortSpec::DESC_VECTOR, v, nullptr));
+ const search::attribute::IAttributeVector * v = vec[spec._name].get();
+ sorter._vectors.emplace_back(spec._asc ? FastS_SortSpec::ASC_VECTOR : FastS_SortSpec::DESC_VECTOR, v, nullptr);
}
}
vespalib::Timer timer;
- sorter.sortResults(hits, num, num);
+ sorter.sortResults(&hits[0], num, num);
LOG(info, "sort time = %" PRId64 " ms", vespalib::count_ms(timer.elapsed()));
- uint32_t *offsets = new uint32_t[num + 1];
- char *buf = new char[sorter.getSortDataSize(0, num)];
- sorter.copySortData(0, num, offsets, buf);
+ std::vector<uint32_t> offsets(num + 1, 0);
+ auto buf = std::make_unique<char []>(sorter.getSortDataSize(0, num));
+ sorter.copySortData(0, num, &offsets[0], buf.get());
// check results
for (uint32_t i = 0; i < num - 1; ++i) {
- for (uint32_t j = 0; j < spec.size(); ++j) {
+ for (const Spec & spec : specs) {
int cmp = 0;
- if (spec[j]._type == RANK) {
+ if (spec._type == RANK) {
if (hits[i].getRank() < hits[i+1].getRank()) {
cmp = -1;
} else if (hits[i].getRank() > hits[i+1].getRank()) {
cmp = 1;
}
- } else if (spec[j]._type == DOCID) {
+ } else if (spec._type == DOCID) {
if (hits[i].getDocId() < hits[i+1].getDocId()) {
cmp = -1;
} else if (hits[i].getDocId() > hits[i+1].getDocId()) {
cmp = 1;
}
} else {
- AttributeVector *av = vec[spec[j]._name].get();
- cmp = compare(av, spec[j]._type,
- hits[i].getDocId(), hits[i+1].getDocId());
+ AttributeVector *av = vec[spec._name].get();
+ cmp = compare(av, spec._type, hits[i].getDocId(), hits[i+1].getDocId());
}
- if (spec[j]._asc) {
+ if (spec._asc) {
EXPECT_TRUE(cmp <= 0);
if (cmp < 0) {
break;
@@ -311,56 +299,51 @@ MultilevelSortTest::sortAndCheck(const std::vector<Spec> &spec, uint32_t num,
}
}
// check binary sort data
- uint32_t minLen = std::min(sorter._sortDataArray[i]._len,
- sorter._sortDataArray[i+1]._len);
+ uint32_t minLen = std::min(sorter._sortDataArray[i]._len, sorter._sortDataArray[i+1]._len);
int cmp = memcmp(&sorter._binarySortData[0] + sorter._sortDataArray[i]._idx,
&sorter._binarySortData[0] + sorter._sortDataArray[i+1]._idx,
minLen);
EXPECT_TRUE(cmp <= 0);
EXPECT_TRUE(sorter._sortDataArray[i]._len == (offsets[i+1] - offsets[i]));
cmp = memcmp(&sorter._binarySortData[0] + sorter._sortDataArray[i]._idx,
- buf + offsets[i], sorter._sortDataArray[i]._len);
+ buf.get() + offsets[i], sorter._sortDataArray[i]._len);
EXPECT_TRUE(cmp == 0);
}
EXPECT_TRUE(sorter._sortDataArray[num-1]._len == (offsets[num] - offsets[num-1]));
int cmp = memcmp(&sorter._binarySortData[0] + sorter._sortDataArray[num-1]._idx,
- buf + offsets[num-1], sorter._sortDataArray[num-1]._len);
+ buf.get() + offsets[num-1], sorter._sortDataArray[num-1]._len);
EXPECT_TRUE(cmp == 0);
-
- delete [] hits;
- delete [] offsets;
- delete [] buf;
}
void MultilevelSortTest::testSort()
{
{
std::vector<Spec> spec;
- spec.push_back(Spec("int8", INT8));
- spec.push_back(Spec("int16", INT16));
- spec.push_back(Spec("int32", INT32));
- spec.push_back(Spec("int64", INT64));
- spec.push_back(Spec("float", FLOAT));
- spec.push_back(Spec("double", DOUBLE));
- spec.push_back(Spec("string", STRING));
- spec.push_back(Spec("rank", RANK));
- spec.push_back(Spec("docid", DOCID));
+ spec.emplace_back("int8", INT8);
+ spec.emplace_back("int16", INT16);
+ spec.emplace_back("int32", INT32);
+ spec.emplace_back("int64", INT64);
+ spec.emplace_back("float", FLOAT);
+ spec.emplace_back("double", DOUBLE);
+ spec.emplace_back("string", STRING);
+ spec.emplace_back("rank", RANK);
+ spec.emplace_back("docid", DOCID);
std::vector<std::string> strValues;
- strValues.push_back("applications");
- strValues.push_back("places");
- strValues.push_back("system");
- strValues.push_back("vespa search core");
+ strValues.emplace_back("applications");
+ strValues.emplace_back("places");
+ strValues.emplace_back("system");
+ strValues.emplace_back("vespa search core");
srand(12345);
sortAndCheck(spec, 5000, 4, strValues);
srand(time(nullptr));
sortAndCheck(spec, 5000, 4, strValues);
- strValues.push_back("multilevelsort");
- strValues.push_back("trondheim");
- strValues.push_back("ubuntu");
- strValues.push_back("fastserver4");
+ strValues.emplace_back("multilevelsort");
+ strValues.emplace_back("trondheim");
+ strValues.emplace_back("ubuntu");
+ strValues.emplace_back("fastserver4");
srand(56789);
sortAndCheck(spec, 5000, 8, strValues);
@@ -403,7 +386,7 @@ TEST("test that [docid] translates to [lid][paritionid]") {
vespalib::TestClock clock;
vespalib::Doom doom(clock.clock(), vespalib::steady_time::max());
search::uca::UcaConverterFactory ucaFactory;
- FastS_SortSpec asc(7, doom, ucaFactory);
+ FastS_SortSpec asc("no-metastore", 7, doom, ucaFactory);
RankedHit hits[2] = {RankedHit(91, 0.0), RankedHit(3, 2.0)};
search::AttributeManager mgr;
search::AttributeContext ac(mgr);
@@ -420,7 +403,7 @@ TEST("test that [docid] translates to [lid][paritionid]") {
EXPECT_EQUAL(6u, sr2.second);
EXPECT_EQUAL(0, memcmp(SECOND_ASC, sr2.first, 6));
- FastS_SortSpec desc(7, doom, ucaFactory);
+ FastS_SortSpec desc("no-metastore", 7, doom, ucaFactory);
desc.Init("-[docid]", ac);
desc.initWithoutSorting(hits, 2);
sr1 = desc.getSortRef(0);
@@ -431,4 +414,45 @@ TEST("test that [docid] translates to [lid][paritionid]") {
EXPECT_EQUAL(0, memcmp(SECOND_DESC, sr2.first, 6));
}
+TEST("test that [docid] uses attribute when one exists") {
+ vespalib::TestClock clock;
+ vespalib::Doom doom(clock.clock(), vespalib::steady_time::max());
+ search::uca::UcaConverterFactory ucaFactory;
+ FastS_SortSpec asc("metastore", 7, doom, ucaFactory);
+ RankedHit hits[2] = {RankedHit(91, 0.0), RankedHit(3, 2.0)};
+ Config cfg(BasicType::INT64, CollectionType::SINGLE);
+ auto metastore = AttributeFactory::createAttribute("metastore", cfg);
+ ASSERT_TRUE(metastore->addDocs(100));
+ auto * iattr = dynamic_cast<IntegerAttribute *>(metastore.get());
+ for (uint32_t lid(0); lid < 100; lid++) {
+ iattr->update(lid, lid);
+ }
+ metastore->commit();
+ search::AttributeManager mgr;
+ mgr.add(metastore);
+ search::AttributeContext ac(mgr);
+ EXPECT_TRUE(asc.Init("+[docid]", ac));
+ asc.initWithoutSorting(hits, 2);
+ constexpr uint8_t FIRST_ASC[8] = {0x80,0,0,0,0,0,0,91};
+ constexpr uint8_t SECOND_ASC[8] = {0x80,0,0,0,0,0,0,3};
+ constexpr uint8_t FIRST_DESC[8] = {0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff - 91};
+ constexpr uint8_t SECOND_DESC[8] = {0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff - 3};
+ auto sr1 = asc.getSortRef(0);
+ EXPECT_EQUAL(8u, sr1.second);
+ EXPECT_EQUAL(0, memcmp(FIRST_ASC, sr1.first, 8));
+ auto sr2 = asc.getSortRef(1);
+ EXPECT_EQUAL(8u, sr2.second);
+ EXPECT_EQUAL(0, memcmp(SECOND_ASC, sr2.first, 8));
+
+ FastS_SortSpec desc("metastore", 7, doom, ucaFactory);
+ desc.Init("-[docid]", ac);
+ desc.initWithoutSorting(hits, 2);
+ sr1 = desc.getSortRef(0);
+ EXPECT_EQUAL(8u, sr1.second);
+ EXPECT_EQUAL(0, memcmp(FIRST_DESC, sr1.first, 8));
+ sr2 = desc.getSortRef(1);
+ EXPECT_EQUAL(8u, sr2.second);
+ EXPECT_EQUAL(0, memcmp(SECOND_DESC, sr2.first, 8));
+}
+
TEST_MAIN() { TEST_RUN_ALL(); }
diff --git a/searchlib/src/vespa/searchlib/common/sortresults.cpp b/searchlib/src/vespa/searchlib/common/sortresults.cpp
index 911e447715b..4eed49defc5 100644
--- a/searchlib/src/vespa/searchlib/common/sortresults.cpp
+++ b/searchlib/src/vespa/searchlib/common/sortresults.cpp
@@ -3,9 +3,9 @@
#include "sortresults.h"
#include "sort.h"
#include <vespa/searchcommon/attribute/iattributecontext.h>
-#include <vespa/vespalib/util/array.hpp>
-
+#include <vespa/vespalib/util/array.h>
#include <vespa/vespalib/util/issue.h>
+
using vespalib::Issue;
#include <vespa/log/log.h>
@@ -174,6 +174,7 @@ FastS_SortSpec::Add(IAttributeContext & vecMan, const SortInfo & sInfo)
type = (sInfo._ascending) ? ASC_RANK : DESC_RANK;
} else if ((sInfo._field.size() == 7) && (sInfo._field == "[docid]")) {
type = (sInfo._ascending) ? ASC_DOCID : DESC_DOCID;
+ vector = vecMan.getAttribute(_documentmetastore);
} else {
type = (sInfo._ascending) ? ASC_VECTOR : DESC_VECTOR;
vector = vecMan.getAttribute(sInfo._field);
@@ -217,7 +218,9 @@ FastS_SortSpec::initSortData(const RankedHit *hits, uint32_t n)
size_t variableWidth = 0;
for (const auto & vec : _vectors) {
if (vec._type >= ASC_DOCID) { // doc id
- fixedWidth += sizeof(uint32_t) + sizeof(uint16_t);
+ fixedWidth = (vec._vector != nullptr)
+ ? vec._vector->getFixedWidth()
+ : sizeof(uint32_t) + sizeof(uint16_t);
} else if (vec._type >= ASC_RANK) { // rank value
fixedWidth += sizeof(search::HitRank);
} else {
@@ -239,21 +242,29 @@ FastS_SortSpec::initSortData(const RankedHit *hits, uint32_t n)
for (uint32_t i(0), idx(0); (i < n) && !_doom.hard_doom(); ++i) {
uint32_t len = 0;
for (const auto & vec : _vectors) {
- int written(0);
+ long written(0);
if (available < std::max(sizeof(hits->_docId) + sizeof(_partitionId), sizeof(hits->_rankValue))) {
mySortData = realloc(n, variableWidth, available, dataSize, mySortData);
}
do {
switch (vec._type) {
case ASC_DOCID:
- serializeForSort<convertForSort<uint32_t, true> >(hits[i].getDocId(), mySortData);
- serializeForSort<convertForSort<uint16_t, true> >(_partitionId, mySortData + sizeof(hits->_docId));
- written = sizeof(hits->_docId) + sizeof(_partitionId);
+ if (vec._vector != nullptr) {
+ written = vec._vector->serializeForAscendingSort(hits[i].getDocId(), mySortData, available, vec._converter);
+ } else {
+ serializeForSort<convertForSort<uint32_t, true> >(hits[i].getDocId(), mySortData);
+ serializeForSort<convertForSort<uint16_t, true> >(_partitionId, mySortData + sizeof(hits->_docId));
+ written = sizeof(hits->_docId) + sizeof(_partitionId);
+ }
break;
case DESC_DOCID:
- serializeForSort<convertForSort<uint32_t, false> >(hits[i].getDocId(), mySortData);
- serializeForSort<convertForSort<uint16_t, false> >(_partitionId, mySortData + sizeof(hits->_docId));
- written = sizeof(hits->_docId) + sizeof(_partitionId);
+ if (vec._vector != nullptr) {
+ written = vec._vector->serializeForDescendingSort(hits[i].getDocId(), mySortData, available, vec._converter);
+ } else {
+ serializeForSort<convertForSort<uint32_t, false> >(hits[i].getDocId(), mySortData);
+ serializeForSort<convertForSort<uint16_t, false> >(_partitionId, mySortData + sizeof(hits->_docId));
+ written = sizeof(hits->_docId) + sizeof(_partitionId);
+ }
break;
case ASC_RANK:
serializeForSort<convertForSort<search::HitRank, true> >(hits[i].getRank(), mySortData);
@@ -288,12 +299,13 @@ FastS_SortSpec::initSortData(const RankedHit *hits, uint32_t n)
}
}
-FastS_SortSpec::FastS_SortSpec(uint32_t partitionId, const Doom & doom, const ConverterFactory & ucaFactory) :
- _partitionId(partitionId),
- _doom(doom),
- _ucaFactory(ucaFactory),
- _sortSpec(),
- _vectors()
+FastS_SortSpec::FastS_SortSpec(vespalib::stringref documentmetastore, uint32_t partitionId, const Doom & doom, const ConverterFactory & ucaFactory)
+ : _documentmetastore(documentmetastore),
+ _partitionId(partitionId),
+ _doom(doom),
+ _ucaFactory(ucaFactory),
+ _sortSpec(),
+ _vectors()
{ }
diff --git a/searchlib/src/vespa/searchlib/common/sortresults.h b/searchlib/src/vespa/searchlib/common/sortresults.h
index 9ea7d4f14ba..337863601d5 100644
--- a/searchlib/src/vespa/searchlib/common/sortresults.h
+++ b/searchlib/src/vespa/searchlib/common/sortresults.h
@@ -4,7 +4,7 @@
#include "rankedhit.h"
#include "sortspec.h"
-#include <vespa/vespalib/util/array.h>
+#include <vespa/vespalib/stllike/allocator.h>
#include <vespa/vespalib/util/doom.h>
#define INSERT_SORT_LEVEL 80
@@ -72,7 +72,7 @@ public:
struct VectorRef
{
- VectorRef(uint32_t type, const search::attribute::IAttributeVector * vector, const search::common::BlobConverter *converter)
+ VectorRef(uint32_t type, const search::attribute::IAttributeVector * vector, const search::common::BlobConverter *converter) noexcept
: _type(type),
_vector(vector),
_converter(converter)
@@ -84,17 +84,18 @@ public:
struct SortData : public search::RankedHit
{
- SortData() : RankedHit(), _idx(0u), _len(0u), _pos(0u) {}
+ SortData() noexcept : RankedHit(), _idx(0u), _len(0u), _pos(0u) {}
uint32_t _idx;
uint32_t _len;
uint32_t _pos;
};
private:
- typedef std::vector<VectorRef> VectorRefList;
- typedef vespalib::Array<uint8_t> BinarySortData;
- typedef vespalib::Array<SortData> SortDataArray;
+ using VectorRefList = std::vector<VectorRef>;
+ using BinarySortData = std::vector<uint8_t, vespalib::allocator_large<uint8_t>>;
+ using SortDataArray = std::vector<SortData, vespalib::allocator_large<SortData>>;
using ConverterFactory = search::common::ConverterFactory;
+ vespalib::string _documentmetastore;
uint16_t _partitionId;
vespalib::Doom _doom;
const ConverterFactory & _ucaFactory;
@@ -110,7 +111,7 @@ private:
public:
FastS_SortSpec(const FastS_SortSpec &) = delete;
FastS_SortSpec & operator = (const FastS_SortSpec &) = delete;
- FastS_SortSpec(uint32_t partitionId, const vespalib::Doom & doom, const ConverterFactory & ucaFactory);
+ FastS_SortSpec(vespalib::stringref documentmetastore, uint32_t partitionId, const vespalib::Doom & doom, const ConverterFactory & ucaFactory);
~FastS_SortSpec() override;
std::pair<const char *, size_t> getSortRef(size_t i) const {
diff --git a/searchlib/src/vespa/searchlib/common/sortspec.cpp b/searchlib/src/vespa/searchlib/common/sortspec.cpp
index e12f758e2d2..16f0c884535 100644
--- a/searchlib/src/vespa/searchlib/common/sortspec.cpp
+++ b/searchlib/src/vespa/searchlib/common/sortspec.cpp
@@ -36,7 +36,7 @@ LowercaseConverter::onConvert(const ConstBufferRef & src) const
return {_buffer.begin(), _buffer.size()};
}
-SortInfo::SortInfo(const vespalib::string & field, bool ascending, BlobConverter::SP converter)
+SortInfo::SortInfo(vespalib::stringref field, bool ascending, BlobConverter::SP converter) noexcept
: _field(field), _ascending(ascending), _converter(std::move(converter))
{ }
SortInfo::~SortInfo() = default;
@@ -72,13 +72,13 @@ SortSpec::SortSpec(const vespalib::string & spec, const ConverterFactory & ucaFa
for(; (p < e) && (*p != ')'); p++);
if (*p == ')') {
vespalib::string strength(strengthName, p - strengthName);
- push_back(SortInfo(attr, ascending, ucaFactory.create(locale, strength)));
+ emplace_back(attr, ascending, ucaFactory.create(locale, strength));
} else {
throw std::runtime_error(make_string("Missing ')' at %s attr=%s locale=%s strength=%s", p, attr.c_str(), localeName, strengthName));
}
} else if (*p == ')') {
vespalib::string locale(localeName, p-localeName);
- push_back(SortInfo(attr, ascending, ucaFactory.create(locale, "")));
+ emplace_back(attr, ascending, ucaFactory.create(locale, ""));
} else {
throw std::runtime_error(make_string("Missing ')' or ',' at %s attr=%s locale=%s", p, attr.c_str(), localeName));
}
@@ -91,7 +91,7 @@ SortSpec::SortSpec(const vespalib::string & spec, const ConverterFactory & ucaFa
for(; (p < e) && (*p != ')'); p++);
if (*p == ')') {
vespalib::string attr(attrName, p-attrName);
- push_back(SortInfo(attr, ascending, std::make_shared<LowercaseConverter>()));
+ emplace_back(attr, ascending, std::make_shared<LowercaseConverter>());
} else {
throw std::runtime_error("Missing ')'");
}
@@ -99,7 +99,7 @@ SortSpec::SortSpec(const vespalib::string & spec, const ConverterFactory & ucaFa
throw std::runtime_error("Unknown func " + vespalib::string(func, p-func));
}
} else {
- push_back(SortInfo(funcSpec, ascending, {}));
+ emplace_back(funcSpec, ascending, std::shared_ptr<search::common::BlobConverter>());
}
}
}
diff --git a/searchlib/src/vespa/searchlib/common/sortspec.h b/searchlib/src/vespa/searchlib/common/sortspec.h
index 7a5b6fb7f90..682612afd43 100644
--- a/searchlib/src/vespa/searchlib/common/sortspec.h
+++ b/searchlib/src/vespa/searchlib/common/sortspec.h
@@ -11,7 +11,7 @@
namespace search::common {
struct SortInfo {
- SortInfo(const vespalib::string & field, bool ascending, BlobConverter::SP converter);
+ SortInfo(vespalib::stringref field, bool ascending, BlobConverter::SP converter) noexcept;
~SortInfo();
vespalib::string _field;
bool _ascending;