summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorTor Egge <tegge@oath.com>2017-08-15 19:18:28 +0000
committerTor Egge <tegge@oath.com>2017-08-15 19:18:28 +0000
commit06aa676b5c1560354479df27e387a1d4c3d3e9e5 (patch)
treead4adbaa58b36008ef842f74cd3f0a47566d7ab4 /searchlib
parentcde02a5457a5f5efccd346bc3c82a464158b3afc (diff)
Factor out ReferenceMappings from ReferenceAttribute.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp5
-rw-r--r--searchlib/src/vespa/searchlib/attribute/CMakeLists.txt1
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference.h42
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp60
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_attribute.h52
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.h2
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp82
-rw-r--r--searchlib/src/vespa/searchlib/attribute/reference_mappings.h74
8 files changed, 222 insertions, 96 deletions
diff --git a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp
index a638309576a..7e2e8904170 100644
--- a/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp
+++ b/searchlib/src/tests/attribute/reference_attribute/reference_attribute_test.cpp
@@ -15,6 +15,7 @@ LOG_SETUP("reference_attribute_test");
using search::MemoryUsage;
using vespalib::ArrayRef;
using generation_t = vespalib::GenerationHandler::generation_t;
+using search::attribute::Reference;
using search::attribute::ReferenceAttribute;
using search::attribute::Config;
using search::attribute::BasicType;
@@ -99,7 +100,7 @@ struct Fixture
}
const GlobalId *get(uint32_t doc) {
- const ReferenceAttribute::Reference *ref = _attr->getReference(doc);
+ const Reference *ref = _attr->getReference(doc);
if (ref != nullptr) {
return &ref->gid();
} else {
@@ -107,7 +108,7 @@ struct Fixture
}
}
- const ReferenceAttribute::Reference *getRef(uint32_t doc) {
+ const Reference *getRef(uint32_t doc) {
return _attr->getReference(doc);
}
diff --git a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
index 9308ae015b5..6838119ccd9 100644
--- a/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
+++ b/searchlib/src/vespa/searchlib/attribute/CMakeLists.txt
@@ -79,6 +79,7 @@ vespa_add_library(searchlib_attribute OBJECT
readerbase.cpp
reference_attribute.cpp
reference_attribute_saver.cpp
+ reference_mappings.cpp
singleenumattribute.cpp
singleenumattributesaver.cpp
singlenumericattribute.cpp
diff --git a/searchlib/src/vespa/searchlib/attribute/reference.h b/searchlib/src/vespa/searchlib/attribute/reference.h
new file mode 100644
index 00000000000..db8c94b4a11
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/reference.h
@@ -0,0 +1,42 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/document/base/globalid.h>
+#include <vespa/searchlib/datastore/entryref.h>
+
+namespace search::attribute {
+
+/*
+ * Class representing a single reference in a reference attribute.
+ */
+class Reference {
+ using EntryRef = search::datastore::EntryRef;
+ using GlobalId = document::GlobalId;
+ GlobalId _gid;
+ mutable uint32_t _lid; // referenced lid
+ mutable EntryRef _revMapIdx; // map from gid to lids referencing gid
+public:
+ Reference()
+ : _gid(),
+ _lid(0u),
+ _revMapIdx()
+ {
+ }
+ Reference(const GlobalId &gid_)
+ : _gid(gid_),
+ _lid(0u),
+ _revMapIdx()
+ {
+ }
+ bool operator<(const Reference &rhs) const {
+ return _gid < rhs._gid;
+ }
+ const GlobalId &gid() const { return _gid; }
+ uint32_t lid() const { return _lid; }
+ EntryRef revMapIdx() const { return _revMapIdx; }
+ void setLid(uint32_t referencedLid) const { _lid = referencedLid; }
+ void setRevMapIdx(EntryRef newRevMapIdx) const { _revMapIdx = newRevMapIdx; }
+};
+
+}
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp
index 2798127e981..ee911c9a8cc 100644
--- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.cpp
@@ -7,7 +7,6 @@
#include <vespa/searchlib/datastore/unique_store_builder.h>
#include <vespa/searchlib/datastore/datastore.hpp>
#include <vespa/searchlib/datastore/unique_store.hpp>
-#include <vespa/searchlib/btree/btreestore.hpp>
#include <vespa/searchlib/common/i_gid_to_lid_mapper_factory.h>
#include <vespa/searchlib/common/i_gid_to_lid_mapper.h>
#include <vespa/vespalib/data/fileheader.h>
@@ -37,8 +36,7 @@ ReferenceAttribute::ReferenceAttribute(const vespalib::stringref baseFileName,
_indices(getGenerationHolder()),
_cachedUniqueStoreMemoryUsage(),
_gidToLidMapperFactory(),
- _reverseMappingIndices(getGenerationHolder()),
- _reverseMapping()
+ _referenceMappings(getGenerationHolder())
{
setEnum(true);
enableEnumeratedSave(true);
@@ -46,16 +44,13 @@ ReferenceAttribute::ReferenceAttribute(const vespalib::stringref baseFileName,
ReferenceAttribute::~ReferenceAttribute()
{
- _reverseMapping.clearBuilder();
+ _referenceMappings.clearBuilder();
incGeneration(); // Force freeze
const auto &store = _store;
const auto saver = _store.getSaver();
saver.foreach_key([&store,this](EntryRef ref)
{ const Reference &entry = store.get(ref);
- EntryRef revMapIdx = entry.revMapIdx();
- if (revMapIdx.valid()) {
- _reverseMapping.clear(revMapIdx);
- }
+ _referenceMappings.clearMapping(entry);
});
incGeneration(); // Force freeze
}
@@ -83,46 +78,24 @@ ReferenceAttribute::addDoc(DocId &doc)
}
void
-ReferenceAttribute::syncReverseMappingIndices(const Reference &entry)
-{
- uint32_t referencedLid = entry.lid();
- if (referencedLid != 0u) {
- _reverseMappingIndices.ensure_size(referencedLid + 1);
- _reverseMappingIndices[referencedLid] = entry.revMapIdx();
- }
-}
-
-void
ReferenceAttribute::removeReverseMapping(EntryRef oldRef, uint32_t lid)
{
const auto &entry = _store.get(oldRef);
- EntryRef revMapIdx = entry.revMapIdx();
- _reverseMapping.apply(revMapIdx, nullptr, nullptr, &lid, &lid + 1);
- std::atomic_thread_fence(std::memory_order_release);
- entry.setRevMapIdx(revMapIdx);
- syncReverseMappingIndices(entry);
+ _referenceMappings.removeReverseMapping(entry, lid);
}
void
ReferenceAttribute::addReverseMapping(EntryRef newRef, uint32_t lid)
{
const auto &entry = _store.get(newRef);
- EntryRef revMapIdx = entry.revMapIdx();
- ReverseMapping::KeyDataType add(lid, btree::BTreeNoLeafData());
- _reverseMapping.apply(revMapIdx, &add, &add + 1, nullptr, nullptr);
- std::atomic_thread_fence(std::memory_order_release);
- entry.setRevMapIdx(revMapIdx);
- syncReverseMappingIndices(entry);
+ _referenceMappings.addReverseMapping(entry, lid);
}
void
ReferenceAttribute::buildReverseMapping(EntryRef newRef, const std::vector<ReverseMapping::KeyDataType> &adds)
{
const auto &entry = _store.get(newRef);
- EntryRef revMapIdx = entry.revMapIdx();
- assert(!revMapIdx.valid());
- _reverseMapping.apply(revMapIdx, &adds[0], &adds[adds.size()], nullptr, nullptr);
- entry.setRevMapIdx(revMapIdx);
+ _referenceMappings.buildReverseMapping(entry, adds);
}
void
@@ -174,7 +147,7 @@ ReferenceAttribute::clearDoc(DocId doc)
void
ReferenceAttribute::removeOldGenerations(generation_t firstUsed)
{
- _reverseMapping.trimHoldLists(firstUsed);
+ _referenceMappings.trimHoldLists(firstUsed);
_store.trimHoldLists(firstUsed);
getGenerationHolder().trimHoldLists(firstUsed);
}
@@ -182,9 +155,9 @@ ReferenceAttribute::removeOldGenerations(generation_t firstUsed)
void
ReferenceAttribute::onGenerationChange(generation_t generation)
{
- _reverseMapping.freeze();
+ _referenceMappings.freeze();
_store.freeze();
- _reverseMapping.transferHoldLists(generation - 1);
+ _referenceMappings.transferHoldLists(generation - 1);
_store.transferHoldLists(generation - 1);
getGenerationHolder().transferHoldLists(generation - 1);
}
@@ -287,7 +260,7 @@ ReferenceAttribute::update(DocId doc, const GlobalId &gid)
}
}
-const ReferenceAttribute::Reference *
+const Reference *
ReferenceAttribute::getReference(DocId doc)
{
assert(doc < _indices.size());
@@ -360,14 +333,7 @@ ReferenceAttribute::notifyGidToLidChange(const GlobalId &gid, DocId referencedLi
EntryRef ref = _store.find(gid);
if (ref.valid()) {
const auto &entry = _store.get(ref);
- uint32_t oldReferencedLid = entry.lid();
- if (oldReferencedLid != referencedLid) {
- if (oldReferencedLid != 0u && oldReferencedLid < _reverseMappingIndices.size()) {
- _reverseMappingIndices[oldReferencedLid] = EntryRef();
- }
- entry.setLid(referencedLid);
- }
- syncReverseMappingIndices(entry);
+ _referenceMappings.notifyGidToLidChange(entry, referencedLid);
commit();
}
}
@@ -383,7 +349,7 @@ ReferenceAttribute::populateReferencedLids()
saver.foreach_key([&store,&mapper,this](EntryRef ref)
{ const Reference &entry = store.get(ref);
entry.setLid(mapper.mapGidToLid(entry.gid()));
- syncReverseMappingIndices(entry); });
+ _referenceMappings.syncReverseMappingIndices(entry); });
}
commit();
}
@@ -419,7 +385,7 @@ IMPLEMENT_IDENTIFIABLE_ABSTRACT(ReferenceAttribute, AttributeVector);
namespace datastore {
-using Reference = attribute::ReferenceAttribute::Reference;
+using Reference = attribute::Reference;
template class UniqueStore<Reference, EntryRefT<22>>;
template class UniqueStoreBuilder<Reference, EntryRefT<22>>;
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h
index 5647acfd163..a751213dc9a 100644
--- a/searchlib/src/vespa/searchlib/attribute/reference_attribute.h
+++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute.h
@@ -3,10 +3,10 @@
#pragma once
#include "not_implemented_attribute.h"
-#include <vespa/document/base/globalid.h>
+#include "reference_mappings.h"
+#include "reference.h"
#include <vespa/searchlib/datastore/unique_store.h>
#include <vespa/searchlib/common/rcuvector.h>
-#include "postingstore.h"
namespace search {
@@ -28,32 +28,6 @@ class ReferenceAttribute : public NotImplementedAttribute
public:
using EntryRef = search::datastore::EntryRef;
using GlobalId = document::GlobalId;
- class Reference {
- GlobalId _gid;
- mutable uint32_t _lid; // referenced lid
- mutable EntryRef _revMapIdx; // map from gid to lids referencing gid
- public:
- Reference()
- : _gid(),
- _lid(0u),
- _revMapIdx()
- {
- }
- Reference(const GlobalId &gid_)
- : _gid(gid_),
- _lid(0u),
- _revMapIdx()
- {
- }
- bool operator<(const Reference &rhs) const {
- return _gid < rhs._gid;
- }
- const GlobalId &gid() const { return _gid; }
- uint32_t lid() const { return _lid; }
- EntryRef revMapIdx() const { return _revMapIdx; }
- void setLid(uint32_t referencedLid) const { _lid = referencedLid; }
- void setRevMapIdx(EntryRef newRevMapIdx) const { _revMapIdx = newRevMapIdx; }
- };
using ReferenceStore = datastore::UniqueStore<Reference>;
using ReferenceStoreIndices = RcuVectorBase<EntryRef>;
using IndicesCopyVector = vespalib::Array<EntryRef>;
@@ -68,12 +42,7 @@ private:
ReferenceStoreIndices _indices;
MemoryUsage _cachedUniqueStoreMemoryUsage;
std::shared_ptr<IGidToLidMapperFactory> _gidToLidMapperFactory;
- // Vector containing references to trees of lids referencing given
- // referenced lid.
- ReverseMappingIndices _reverseMappingIndices;
- // Store of B-Trees, used to map from gid or referenced lid to
- // referencing lids.
- ReverseMapping _reverseMapping;
+ ReferenceMappings _referenceMappings;
virtual void onAddDocs(DocId docIdLimit) override;
virtual void removeOldGenerations(generation_t firstUsed) override;
@@ -87,7 +56,6 @@ private:
bool considerCompact(const CompactionStrategy &compactionStrategy);
void compactWorst();
IndicesCopyVector getIndicesCopy(uint32_t size) const;
- void syncReverseMappingIndices(const Reference &entry);
void removeReverseMapping(EntryRef oldRef, uint32_t lid);
void addReverseMapping(EntryRef newRef, uint32_t lid);
void buildReverseMapping(EntryRef newRef, const std::vector<ReverseMapping::KeyDataType> &adds);
@@ -113,18 +81,10 @@ public:
template <typename FunctionType>
void
- foreach_lid(uint32_t referencedLid, FunctionType &&func) const;
-};
-
-template <typename FunctionType>
-void
-ReferenceAttribute::foreach_lid(uint32_t referencedLid, FunctionType &&func) const
-{
- if (referencedLid < _reverseMappingIndices.size()) {
- EntryRef revMapIdx = _reverseMappingIndices[referencedLid];
- _reverseMapping.foreach_frozen_key(revMapIdx, func);
+ foreach_lid(uint32_t referencedLid, FunctionType &&func) const {
+ _referenceMappings.foreach_lid(referencedLid, std::forward<FunctionType>(func));
}
-}
+};
}
}
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.h b/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.h
index d1ee5e0339a..7d85c60c3e6 100644
--- a/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.h
+++ b/searchlib/src/vespa/searchlib/attribute/reference_attribute_saver.h
@@ -8,6 +8,7 @@
#include <vespa/searchlib/datastore/unique_store_saver.h>
#include <vespa/searchlib/common/rcuvector.h>
#include "reference_attribute.h"
+#include "reference.h"
namespace search {
namespace attribute {
@@ -31,7 +32,6 @@ private:
using GlobalId = document::GlobalId;
using IndicesCopyVector = ReferenceAttribute::IndicesCopyVector;
using Store = ReferenceAttribute::ReferenceStore;
- using Reference = ReferenceAttribute::Reference;
using Saver = Store::Saver;
IndicesCopyVector _indices;
const Store &_store;
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp b/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp
new file mode 100644
index 00000000000..67f02c50d88
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/reference_mappings.cpp
@@ -0,0 +1,82 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#include "reference_mappings.h"
+#include "reference.h"
+#include <vespa/searchlib/datastore/datastore.hpp>
+#include <vespa/searchlib/btree/btreestore.hpp>
+
+namespace search::attribute {
+
+ReferenceMappings::ReferenceMappings(GenerationHolder &genHolder)
+ : _reverseMappingIndices(genHolder),
+ _reverseMapping()
+{
+}
+
+ReferenceMappings::~ReferenceMappings()
+{
+}
+
+void
+ReferenceMappings::clearMapping(const Reference &entry)
+{
+ EntryRef revMapIdx = entry.revMapIdx();
+ if (revMapIdx.valid()) {
+ _reverseMapping.clear(revMapIdx);
+ }
+}
+
+void
+ReferenceMappings::syncReverseMappingIndices(const Reference &entry)
+{
+ uint32_t referencedLid = entry.lid();
+ if (referencedLid != 0u) {
+ _reverseMappingIndices.ensure_size(referencedLid + 1);
+ _reverseMappingIndices[referencedLid] = entry.revMapIdx();
+ }
+}
+
+void
+ReferenceMappings::removeReverseMapping(const Reference &entry, uint32_t lid)
+{
+ EntryRef revMapIdx = entry.revMapIdx();
+ _reverseMapping.apply(revMapIdx, nullptr, nullptr, &lid, &lid + 1);
+ std::atomic_thread_fence(std::memory_order_release);
+ entry.setRevMapIdx(revMapIdx);
+ syncReverseMappingIndices(entry);
+}
+
+void
+ReferenceMappings::addReverseMapping(const Reference &entry, uint32_t lid)
+{
+ EntryRef revMapIdx = entry.revMapIdx();
+ ReverseMapping::KeyDataType add(lid, btree::BTreeNoLeafData());
+ _reverseMapping.apply(revMapIdx, &add, &add + 1, nullptr, nullptr);
+ std::atomic_thread_fence(std::memory_order_release);
+ entry.setRevMapIdx(revMapIdx);
+ syncReverseMappingIndices(entry);
+}
+
+void
+ReferenceMappings::buildReverseMapping(const Reference &entry, const std::vector<ReverseMapping::KeyDataType> &adds)
+{
+ EntryRef revMapIdx = entry.revMapIdx();
+ assert(!revMapIdx.valid());
+ _reverseMapping.apply(revMapIdx, &adds[0], &adds[adds.size()], nullptr, nullptr);
+ entry.setRevMapIdx(revMapIdx);
+}
+
+void
+ReferenceMappings::notifyGidToLidChange(const Reference &entry, uint32_t referencedLid)
+{
+ uint32_t oldReferencedLid = entry.lid();
+ if (oldReferencedLid != referencedLid) {
+ if (oldReferencedLid != 0u && oldReferencedLid < _reverseMappingIndices.size()) {
+ _reverseMappingIndices[oldReferencedLid] = EntryRef();
+ }
+ entry.setLid(referencedLid);
+ }
+ syncReverseMappingIndices(entry);
+}
+
+}
diff --git a/searchlib/src/vespa/searchlib/attribute/reference_mappings.h b/searchlib/src/vespa/searchlib/attribute/reference_mappings.h
new file mode 100644
index 00000000000..129ccbbea25
--- /dev/null
+++ b/searchlib/src/vespa/searchlib/attribute/reference_mappings.h
@@ -0,0 +1,74 @@
+// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+
+#pragma once
+
+#include <vespa/searchlib/btree/btreestore.h>
+#include <vespa/searchlib/common/rcuvector.h>
+
+namespace search::attribute {
+
+class Reference;
+
+/*
+ * Class representing mappings in a reference attribute.
+ */
+class ReferenceMappings
+{
+ using GenerationHolder = vespalib::GenerationHolder;
+ using EntryRef = search::datastore::EntryRef;
+ using ReverseMappingIndices = RcuVectorBase<EntryRef>;
+ using ReverseMapping = btree::BTreeStore<uint32_t, btree::BTreeNoLeafData,
+ btree::NoAggregated,
+ std::less<uint32_t>,
+ btree::BTreeDefaultTraits,
+ btree::NoAggrCalc>;
+ using generation_t = vespalib::GenerationHandler::generation_t;
+
+ // Vector containing references to trees of lids referencing given
+ // referenced lid.
+ ReverseMappingIndices _reverseMappingIndices;
+ // Store of B-Trees, used to map from gid or referenced lid to
+ // referencing lids.
+ ReverseMapping _reverseMapping;
+
+
+public:
+ ReferenceMappings(GenerationHolder &genHolder);
+
+ ~ReferenceMappings();
+
+ // Cleanup helpers, to free resources
+ void clearBuilder() { _reverseMapping.clearBuilder(); }
+ void clearMapping(const Reference &entry);
+
+ // Hold list management & freezing
+ void trimHoldLists(generation_t usedGen) { _reverseMapping.trimHoldLists(usedGen); }
+ void freeze() { _reverseMapping.freeze(); }
+ void transferHoldLists(generation_t generation) { _reverseMapping.transferHoldLists(generation); }
+
+ // Handle mapping changes
+ void notifyGidToLidChange(const Reference &entry, uint32_t referencedLid);
+ void syncReverseMappingIndices(const Reference &entry);
+ void removeReverseMapping(const Reference &entry, uint32_t lid);
+ void addReverseMapping(const Reference &entry, uint32_t lid);
+
+ // Setup mapping after load
+ void buildReverseMapping(const Reference &entry, const std::vector<ReverseMapping::KeyDataType> &adds);
+
+ // Reader API, reader must hold generation guard
+ template <typename FunctionType>
+ void
+ foreach_lid(uint32_t referencedLid, FunctionType &&func) const;
+};
+
+template <typename FunctionType>
+void
+ReferenceMappings::foreach_lid(uint32_t referencedLid, FunctionType &&func) const
+{
+ if (referencedLid < _reverseMappingIndices.size()) {
+ EntryRef revMapIdx = _reverseMappingIndices[referencedLid];
+ _reverseMapping.foreach_frozen_key(revMapIdx, std::forward<FunctionType>(func));
+ }
+}
+
+}