aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorHenning Baldersheim <balder@oath.com>2018-07-19 14:00:27 +0200
committerHenning Baldersheim <balder@oath.com>2018-07-19 14:00:27 +0200
commit81914f5a56ceb33001179c172f22278398c86a51 (patch)
tree1d8e7a1e137eee94e8275e72085ead1a144cd644 /searchlib
parent9df684ab0857b573443c00ac7cf1007822d17dfc (diff)
Add control of cache update policy when an item changes value.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp53
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_header.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attribute_header.h6
-rw-r--r--searchlib/src/vespa/searchlib/attribute/attributefilewriter.cpp37
-rw-r--r--searchlib/src/vespa/searchlib/docstore/documentstore.cpp104
-rw-r--r--searchlib/src/vespa/searchlib/docstore/documentstore.h18
-rw-r--r--searchlib/src/vespa/searchlib/docstore/logdocumentstore.cpp2
7 files changed, 115 insertions, 109 deletions
diff --git a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
index a22c44e843c..80471235d1b 100644
--- a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
+++ b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
@@ -282,13 +282,13 @@ TEST("testTruncatedIdxFile"){
{
// Files comes from the 'growing test'.
LogDataStore datastore(executor, TEST_PATH("bug-7257706"), config, GrowStrategy(),
- TuneFileSummary(), fileHeaderContext, tlSyncer, NULL);
+ TuneFileSummary(), fileHeaderContext, tlSyncer, nullptr);
EXPECT_EQUAL(354ul, datastore.lastSyncToken());
}
const char * magic = "mumbo jumbo";
{
LogDataStore datastore(executor, "bug-7257706-truncated", config, GrowStrategy(),
- TuneFileSummary(), fileHeaderContext, tlSyncer, NULL);
+ TuneFileSummary(), fileHeaderContext, tlSyncer, nullptr);
EXPECT_EQUAL(331ul, datastore.lastSyncToken());
datastore.write(332, 7, magic, strlen(magic));
datastore.write(333, 8, magic, strlen(magic));
@@ -296,7 +296,7 @@ TEST("testTruncatedIdxFile"){
}
{
LogDataStore datastore(executor, "bug-7257706-truncated", config, GrowStrategy(),
- TuneFileSummary(), fileHeaderContext, tlSyncer, NULL);
+ TuneFileSummary(), fileHeaderContext, tlSyncer, nullptr);
EXPECT_EQUAL(334ul, datastore.lastSyncToken());
}
}
@@ -308,7 +308,7 @@ TEST("testThatEmptyIdxFilesAndDanglingDatFilesAreRemoved") {
MyTlSyncer tlSyncer;
LogDataStore datastore(executor, "dangling-test", config,
GrowStrategy(), TuneFileSummary(),
- fileHeaderContext, tlSyncer, NULL);
+ fileHeaderContext, tlSyncer, nullptr);
EXPECT_EQUAL(354ul, datastore.lastSyncToken());
EXPECT_EQUAL(4096u + 480u, datastore.getDiskHeaderFootprint());
EXPECT_EQUAL(datastore.getDiskHeaderFootprint() + 94016u, datastore.getDiskFootprint());
@@ -321,7 +321,7 @@ TEST("testThatIncompleteCompactedFilesAreRemoved") {
MyTlSyncer tlSyncer;
LogDataStore datastore(executor, "incompletecompact-test", config,
GrowStrategy(), TuneFileSummary(),
- fileHeaderContext, tlSyncer, NULL);
+ fileHeaderContext, tlSyncer, nullptr);
EXPECT_EQUAL(354ul, datastore.lastSyncToken());
EXPECT_EQUAL(3*(4096u + 480u), datastore.getDiskHeaderFootprint());
LogDataStore::NameIdSet files = datastore.getAllActiveFiles();
@@ -340,7 +340,7 @@ public:
_executor(1, 128*1024),
_tlSyncer(),
_datastore(_executor, _myDir.getDir(), _config, GrowStrategy(),
- TuneFileSummary(), _fileHeaderContext, _tlSyncer, NULL)
+ TuneFileSummary(), _fileHeaderContext, _tlSyncer, nullptr)
{ }
~VisitStore();
IDataStore & getStore() { return _datastore; }
@@ -524,7 +524,7 @@ VisitCacheStore::VisitCacheStore() :
_inserted(),
_serial(1)
{ }
-VisitCacheStore::~VisitCacheStore() {}
+VisitCacheStore::~VisitCacheStore() = default;
void
verifyCacheStats(CacheStats cs, size_t hits, size_t misses, size_t elements, size_t memory_used) {
@@ -546,41 +546,42 @@ TEST("test that the integrated visit cache works.") {
for (size_t i(1); i <= 100; i++) {
vcs.verifyRead(i);
}
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 0, 100, 100, 20574));
+ constexpr size_t BASE_SZ = 21374;
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 0, 100, 100, BASE_SZ));
for (size_t i(1); i <= 100; i++) {
vcs.verifyRead(i);
}
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 100, 100, 100, 20574)); // From the individual cache.
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 100, 100, 100, BASE_SZ)); // From the individual cache.
vcs.verifyVisit({7,9,17,19,67,88}, false);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 100, 100, 100, 20574));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 100, 100, 100, BASE_SZ));
vcs.verifyVisit({7,9,17,19,67,88}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 100, 101, 101, 21135));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 100, 101, 101, BASE_SZ+557));
vcs.verifyVisit({7,9,17,19,67,88}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 101, 101, 21135));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 101, 101, BASE_SZ+557));
vcs.rewrite(8);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 101, 100, 20922)); // From the individual cache.
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 101, 100, BASE_SZ+328)); // From the individual cache.
vcs.rewrite(7);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 101, 98, 20148)); // From the both caches.
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 101, 98, BASE_SZ-442)); // From the both caches.
vcs.verifyVisit({7,9,17,19,67,88}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 102, 99, 20732));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 102, 99, BASE_SZ+130));
vcs.verifyVisit({7,9,17,19,67,88,89}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 103, 99, 20783));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 103, 99, BASE_SZ+201));
vcs.rewrite(17);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 103, 97, 19943));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 103, 97, BASE_SZ-657));
vcs.verifyVisit({7,9,17,19,67,88,89}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 104, 98, 20587));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 104, 98, BASE_SZ-3));
vcs.remove(17);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 104, 97, 19943));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 104, 97, BASE_SZ-657));
vcs.verifyVisit({7,9,17,19,67,88,89}, {7,9,19,67,88,89}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 105, 98, 20526));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 105, 98, BASE_SZ-64));
vcs.verifyVisit({41, 42}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 106, 99, 20820));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 106, 99, BASE_SZ+238));
vcs.verifyVisit({43, 44}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 107, 100, 21124));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 107, 100, BASE_SZ+540));
vcs.verifyVisit({41, 42, 43, 44}, true);
- TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 108, 99, 20944));
+ TEST_DO(verifyCacheStats(ds.getCacheStats(), 101, 108, 99, BASE_SZ+362));
}
TEST("testWriteRead") {
@@ -595,7 +596,7 @@ TEST("testWriteRead") {
vespalib::ThreadStackExecutor executor(1, 128*1024);
MyTlSyncer tlSyncer;
LogDataStore datastore(executor, "empty", config, GrowStrategy(),
- TuneFileSummary(), fileHeaderContext, tlSyncer, NULL);
+ TuneFileSummary(), fileHeaderContext, tlSyncer, nullptr);
ASSERT_TRUE(datastore.lastSyncToken() == 0);
size_t headerFootprint = datastore.getDiskHeaderFootprint();
EXPECT_LESS(0u, headerFootprint);
@@ -606,7 +607,7 @@ TEST("testWriteRead") {
fetchAndTest(datastore, 0, a[0].c_str(), a[0].size());
datastore.write(2, 0, a[1].c_str(), a[1].size());
fetchAndTest(datastore, 0, a[1].c_str(), a[1].size());
- fetchAndTest(datastore, 1, NULL, 0);
+ fetchAndTest(datastore, 1, nullptr, 0);
datastore.remove(3, 0);
fetchAndTest(datastore, 0, "", 0);
@@ -632,7 +633,7 @@ TEST("testWriteRead") {
MyTlSyncer tlSyncer;
LogDataStore datastore(executor, "empty", config,
GrowStrategy(), TuneFileSummary(),
- fileHeaderContext, tlSyncer, NULL);
+ fileHeaderContext, tlSyncer, nullptr);
size_t headerFootprint = datastore.getDiskHeaderFootprint();
EXPECT_LESS(0u, headerFootprint);
EXPECT_EQUAL(4944ul + headerFootprint, datastore.getDiskFootprint());
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_header.cpp b/searchlib/src/vespa/searchlib/attribute/attribute_header.cpp
index 4a69e0a827d..828c7c19962 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_header.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_header.cpp
@@ -68,9 +68,7 @@ AttributeHeader::AttributeHeader(const vespalib::string &fileName,
{
}
-AttributeHeader::~AttributeHeader()
-{
-}
+AttributeHeader::~AttributeHeader() = default;
void
AttributeHeader::internalExtractTags(const vespalib::GenericHeader &header)
diff --git a/searchlib/src/vespa/searchlib/attribute/attribute_header.h b/searchlib/src/vespa/searchlib/attribute/attribute_header.h
index 3d00396e171..4a0b1e0bee0 100644
--- a/searchlib/src/vespa/searchlib/attribute/attribute_header.h
+++ b/searchlib/src/vespa/searchlib/attribute/attribute_header.h
@@ -10,8 +10,7 @@
namespace vespalib { class GenericHeader; }
-namespace search {
-namespace attribute {
+namespace search::attribute {
/**
* Attribute header class used by attribute savers and attribute initializer
@@ -71,5 +70,4 @@ public:
void addTags(vespalib::GenericHeader &header) const;
};
-} // namespace search::attribute
-} // namespace search
+}
diff --git a/searchlib/src/vespa/searchlib/attribute/attributefilewriter.cpp b/searchlib/src/vespa/searchlib/attribute/attributefilewriter.cpp
index b1268aacc4f..415c00cb8fd 100644
--- a/searchlib/src/vespa/searchlib/attribute/attributefilewriter.cpp
+++ b/searchlib/src/vespa/searchlib/attribute/attributefilewriter.cpp
@@ -2,10 +2,10 @@
#include "attributefilewriter.h"
#include "attributefilebufferwriter.h"
+#include "attribute_header.h"
#include <vespa/vespalib/data/fileheader.h>
#include <vespa/searchlib/common/fileheadercontext.h>
#include <vespa/searchlib/common/tunefileinfo.h>
-#include "attribute_header.h"
#include <vespa/fastos/file.h>
#include <vespa/log/log.h>
@@ -14,7 +14,6 @@ LOG_SETUP(".searchlib.attribute.attributefilewriter");
using search::common::FileHeaderContext;
using vespalib::getLastErrorString;
-
namespace search {
namespace {
@@ -23,8 +22,7 @@ const uint32_t headerAlign = 4096;
const uint32_t MIN_ALIGNMENT = 4096;
void
-writeDirectIOAligned(FastOS_FileInterface &file, const void *buf,
- size_t length)
+writeDirectIOAligned(FastOS_FileInterface &file, const void *buf, size_t length)
{
const char * data(static_cast<const char *>(buf));
size_t remaining(length);
@@ -38,7 +36,6 @@ writeDirectIOAligned(FastOS_FileInterface &file, const void *buf,
}
}
-
void
updateHeader(const vespalib::string &name, uint64_t fileBitSize)
{
@@ -63,29 +60,22 @@ class FileBackedBufferWriter : public AttributeFileBufferWriter
{
public:
FileBackedBufferWriter(AttributeFileWriter &fileWriter);
+ ~FileBackedBufferWriter() override;
- virtual ~FileBackedBufferWriter();
-
- virtual void onFlush(size_t nowLen) override;
+ void onFlush(size_t nowLen) override;
};
FileBackedBufferWriter::FileBackedBufferWriter(AttributeFileWriter &fileWriter)
: AttributeFileBufferWriter(fileWriter)
-{
-}
-
-
-FileBackedBufferWriter::~FileBackedBufferWriter()
-{
-}
+{ }
+FileBackedBufferWriter::~FileBackedBufferWriter() = default;
void
FileBackedBufferWriter::onFlush(size_t nowLen) {
// Note: Must use const ptr to indicate that buffer is pre-filled.
- Buffer buf(std::make_unique<BufferBuf>
- ((const char *) _buf->getFree(), nowLen));
+ auto buf(std::make_unique<BufferBuf>(static_cast<const void *>(_buf->getFree()), nowLen));
assert(buf->getDataLen() == nowLen);
assert(buf->getData() == _buf->getFree());
_fileWriter.writeBuf(std::move(buf));
@@ -93,7 +83,6 @@ FileBackedBufferWriter::onFlush(size_t nowLen) {
}
-
AttributeFileWriter::
AttributeFileWriter(const TuneFileAttributes &tuneFileAttributes,
const FileHeaderContext &fileHeaderContext,
@@ -107,9 +96,7 @@ AttributeFileWriter(const TuneFileAttributes &tuneFileAttributes,
_fileBitSize(0)
{ }
-
-AttributeFileWriter::~AttributeFileWriter() { }
-
+AttributeFileWriter::~AttributeFileWriter() = default;
bool
AttributeFileWriter::open(const vespalib::string &fileName)
@@ -130,7 +117,6 @@ AttributeFileWriter::open(const vespalib::string &fileName)
return true;
}
-
void
AttributeFileWriter::writeHeader()
{
@@ -142,7 +128,6 @@ AttributeFileWriter::writeHeader()
_fileBitSize = headerLen * 8;
}
-
void
AttributeFileWriter::addTags(vespalib::GenericHeader &header)
{
@@ -151,14 +136,12 @@ AttributeFileWriter::addTags(vespalib::GenericHeader &header)
header.putTag(Tag("desc", _desc));
}
-
AttributeFileWriter::Buffer
AttributeFileWriter::allocBuf(size_t size)
{
return std::make_unique<BufferBuf>(size, MIN_ALIGNMENT);
}
-
void
AttributeFileWriter::writeBuf(Buffer buf)
{
@@ -168,7 +151,6 @@ AttributeFileWriter::writeBuf(Buffer buf)
_fileBitSize += bufLen * 8;
}
-
void
AttributeFileWriter::close()
{
@@ -179,13 +161,10 @@ AttributeFileWriter::close()
}
}
-
std::unique_ptr<BufferWriter>
AttributeFileWriter::allocBufferWriter()
{
return std::make_unique<FileBackedBufferWriter>(*this);
}
-
-
} // namespace search
diff --git a/searchlib/src/vespa/searchlib/docstore/documentstore.cpp b/searchlib/src/vespa/searchlib/docstore/documentstore.cpp
index 59e92b112fa..a6c5f567454 100644
--- a/searchlib/src/vespa/searchlib/docstore/documentstore.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/documentstore.cpp
@@ -35,8 +35,7 @@ void
DocumentVisitorAdapter::visit(uint32_t lid, vespalib::ConstBufferRef buf) {
if (buf.size() > 0) {
vespalib::nbostream is(buf.c_str(), buf.size());
- document::Document::UP doc(new document::Document(_repo, is));
- _visitor.visit(lid, std::move(doc));
+ _visitor.visit(lid, std::make_unique<document::Document>(_repo, is));
}
}
@@ -51,34 +50,38 @@ public:
using Alloc = vespalib::alloc::Alloc;
typedef std::unique_ptr<Value> UP;
- Value() : _compressedSize(0), _uncompressedSize(0), _compression(CompressionConfig::NONE) {}
-
- Value(Value &&rhs) :
- _compressedSize(rhs._compressedSize),
- _uncompressedSize(rhs._uncompressedSize),
- _compression(rhs._compression),
- _buf(std::move(rhs._buf)) {}
-
- Value(const Value &rhs) :
- _compressedSize(rhs._compressedSize),
- _uncompressedSize(rhs._uncompressedSize),
- _compression(rhs._compression),
- _buf(Alloc::alloc(rhs.size())) {
+ Value()
+ : _syncToken(0),
+ _compressedSize(0),
+ _uncompressedSize(0),
+ _compression(CompressionConfig::NONE)
+ {}
+
+ Value(uint64_t syncToken)
+ : _syncToken(syncToken),
+ _compressedSize(0),
+ _uncompressedSize(0),
+ _compression(CompressionConfig::NONE)
+ {}
+
+ Value(Value &&rhs) = default;
+ Value &operator=(Value &&rhs) = default;
+
+ Value(const Value &rhs)
+ : _syncToken(rhs._syncToken),
+ _compressedSize(rhs._compressedSize),
+ _uncompressedSize(rhs._uncompressedSize),
+ _compression(rhs._compression),
+ _buf(Alloc::alloc(rhs.size()))
+ {
memcpy(get(), rhs.get(), size());
}
- Value &operator=(Value &&rhs) {
- _buf = std::move(rhs._buf);
- _compressedSize = rhs._compressedSize;
- _uncompressedSize = rhs._uncompressedSize;
- _compression = rhs._compression;
- return *this;
- }
-
void setCompression(CompressionConfig::Type comp, size_t uncompressedSize) {
_compression = comp;
_uncompressedSize = uncompressedSize;
}
+ uint64_t getSyncToken() const { return _syncToken; }
CompressionConfig::Type getCompression() const { return _compression; }
@@ -96,7 +99,8 @@ public:
* Decompress value into temporary buffer and deserialize document from
* the temporary buffer.
*/
- document::Document::UP deserializeDocument(const DocumentTypeRepo &repo);
+ document::Document::UP deserializeDocument(const DocumentTypeRepo &repo) const;
+ vespalib::DataBuffer decompressed() const;
size_t size() const { return _compressedSize; }
bool empty() const { return size() == 0; }
@@ -104,6 +108,7 @@ public:
const void *get() const { return _buf.get(); }
void *get() { return _buf.get(); }
private:
+ uint64_t _syncToken;
size_t _compressedSize;
size_t _uncompressedSize;
CompressionConfig::Type _compression;
@@ -119,7 +124,7 @@ public:
bool read(DocumentIdT key, Value &value) const;
void visit(const IDocumentStore::LidVector &lids, const DocumentTypeRepo &repo, IDocumentVisitor &visitor) const;
- void write(DocumentIdT, const Value &) {}
+ void write(DocumentIdT, const Value &);
void erase(DocumentIdT) {}
const CompressionConfig &getCompression() const { return _compression; }
void reconfigure(const CompressionConfig &compression);
@@ -138,8 +143,7 @@ void
Value::set(vespalib::DataBuffer &&buf, ssize_t len, const CompressionConfig &compression) {
//Underlying buffer must be identical to allow swap.
vespalib::DataBuffer compressed(buf.getData(), 0u);
- CompressionConfig::Type type = compress(compression, vespalib::ConstBufferRef(buf.getData(), len),
- compressed, true);
+ CompressionConfig::Type type = compress(compression, vespalib::ConstBufferRef(buf.getData(), len), compressed, true);
_compressedSize = compressed.getDataLen();
if (buf.getData() == compressed.getData()) {
// Uncompressed so we can just steal the underlying buffer.
@@ -154,16 +158,20 @@ Value::set(vespalib::DataBuffer &&buf, ssize_t len, const CompressionConfig &com
setCompression(type, len);
}
+vespalib::DataBuffer
+Value::decompressed() const {
+ vespalib::DataBuffer uncompressed(_buf.get(), (size_t) 0);
+ decompress(getCompression(), getUncompressedSize(), vespalib::ConstBufferRef(*this, size()), uncompressed, true);
+ return uncompressed;
+}
document::Document::UP
-Value::deserializeDocument(const DocumentTypeRepo &repo) {
- vespalib::DataBuffer uncompressed((char *) _buf.get(), (size_t) 0);
- decompress(getCompression(), getUncompressedSize(), vespalib::ConstBufferRef(*this, size()), uncompressed, true);
+Value::deserializeDocument(const DocumentTypeRepo &repo) const {
+ vespalib::DataBuffer uncompressed(decompressed());
vespalib::nbostream is(uncompressed.getData(), uncompressed.getDataLen());
- return document::Document::UP(new document::Document(repo, is));
+ return std::make_unique<document::Document>(repo, is);
}
-
void
BackingStore::visit(const IDocumentStore::LidVector &lids, const DocumentTypeRepo &repo,
IDocumentVisitor &visitor) const {
@@ -184,6 +192,14 @@ BackingStore::read(DocumentIdT key, Value &value) const {
}
void
+BackingStore::write(DocumentIdT lid, const Value & value)
+{
+ assert(value.getCompression() == _compression.type);
+ vespalib::DataBuffer buf = value.decompressed();
+ _backingStore.write(value.getSyncToken(), lid, buf.getData(), buf.getDataLen());
+}
+
+void
BackingStore::reconfigure(const CompressionConfig &compression) {
_compression = compression;
}
@@ -194,8 +210,7 @@ using CacheParams = vespalib::CacheParam<
vespalib::LruParam<DocumentIdT, docstore::Value>,
docstore::BackingStore,
vespalib::zero<DocumentIdT>,
- vespalib::size<docstore::Value>
->;
+ vespalib::size<docstore::Value> >;
class Cache : public vespalib::cache<CacheParams> {
public:
@@ -210,6 +225,7 @@ DocumentStore::Config::operator == (const Config &rhs) const {
return (_maxCacheBytes == rhs._maxCacheBytes) &&
(_allowVisitCaching == rhs._allowVisitCaching) &&
(_initialCacheEntries == rhs._initialCacheEntries) &&
+ (_updateStrategy == rhs._updateStrategy) &&
(_compression == rhs._compression);
}
@@ -226,7 +242,7 @@ DocumentStore::DocumentStore(const Config & config, IDataStore & store)
_cache->reserveElements(config.getInitialCacheEntries());
}
-DocumentStore::~DocumentStore() {}
+DocumentStore::~DocumentStore() = default;
void
DocumentStore::reconfigure(const Config & config) {
@@ -282,10 +298,22 @@ DocumentStore::write(uint64_t syncToken, DocumentIdT lid, const document::Docume
void
DocumentStore::write(uint64_t syncToken, DocumentIdT lid, const vespalib::nbostream & stream) {
- _backingStore.write(syncToken, lid, stream.peek(), stream.size());
if (useCache()) {
- _cache->invalidate(lid);
- _visitCache->invalidate(lid);
+ switch (_config.updateStrategy()) {
+ case Config::UpdateStrategy::INVALIDATE:
+ _backingStore.write(syncToken, lid, stream.peek(), stream.size());
+ _cache->invalidate(lid);
+ break;
+ case Config::UpdateStrategy::UPDATE: {
+ Value value(syncToken);
+ value.set(vespalib::DataBuffer(), stream.size(), _store->getCompression());
+ _cache->write(lid, std::move(value));
+ break;
+ }
+ }
+ _visitCache->invalidate(lid); // The cost and complexity of this updating this is not worth it.
+ } else {
+ _backingStore.write(syncToken, lid, stream.peek(), stream.size());
}
}
diff --git a/searchlib/src/vespa/searchlib/docstore/documentstore.h b/searchlib/src/vespa/searchlib/docstore/documentstore.h
index 08b042d99c5..7bc3ab1c21d 100644
--- a/searchlib/src/vespa/searchlib/docstore/documentstore.h
+++ b/searchlib/src/vespa/searchlib/docstore/documentstore.h
@@ -27,17 +27,20 @@ class DocumentStore : public IDocumentStore
public:
class Config {
public:
+ enum UpdateStrategy {INVALIDATE, UPDATE };
using CompressionConfig = vespalib::compression::CompressionConfig;
Config() :
_compression(CompressionConfig::LZ4, 9, 70),
_maxCacheBytes(1000000000),
_initialCacheEntries(0),
+ _updateStrategy(INVALIDATE),
_allowVisitCaching(false)
{ }
Config(const CompressionConfig & compression, size_t maxCacheBytes, size_t initialCacheEntries) :
_compression((maxCacheBytes != 0) ? compression : CompressionConfig::NONE),
_maxCacheBytes(maxCacheBytes),
_initialCacheEntries(initialCacheEntries),
+ _updateStrategy(INVALIDATE),
_allowVisitCaching(false)
{ }
const CompressionConfig & getCompression() const { return _compression; }
@@ -45,11 +48,14 @@ public:
size_t getInitialCacheEntries() const { return _initialCacheEntries; }
bool allowVisitCaching() const { return _allowVisitCaching; }
Config & allowVisitCaching(bool allow) { _allowVisitCaching = allow; return *this; }
+ Config & updateStrategy(UpdateStrategy strategy) { _updateStrategy = strategy; return *this; }
+ UpdateStrategy updateStrategy() const { return _updateStrategy; }
bool operator == (const Config &) const;
private:
CompressionConfig _compression;
size_t _maxCacheBytes;
size_t _initialCacheEntries;
+ UpdateStrategy _updateStrategy;
bool _allowVisitCaching;
};
@@ -82,14 +88,10 @@ public:
CacheStats getCacheStats() const override;
size_t memoryMeta() const override { return _backingStore.memoryMeta(); }
const vespalib::string & getBaseDir() const override { return _backingStore.getBaseDir(); }
- void
- accept(IDocumentStoreReadVisitor &visitor,
- IDocumentStoreVisitorProgress &visitorProgress,
- const document::DocumentTypeRepo &repo) override;
- void
- accept(IDocumentStoreRewriteVisitor &visitor,
- IDocumentStoreVisitorProgress &visitorProgress,
- const document::DocumentTypeRepo &repo) override;
+ void accept(IDocumentStoreReadVisitor &visitor, IDocumentStoreVisitorProgress &visitorProgress,
+ const document::DocumentTypeRepo &repo) override;
+ void accept(IDocumentStoreRewriteVisitor &visitor, IDocumentStoreVisitorProgress &visitorProgress,
+ const document::DocumentTypeRepo &repo) override;
double getVisitCost() const override;
DataStoreStorageStats getStorageStats() const override;
MemoryUsage getMemoryUsage() const override;
diff --git a/searchlib/src/vespa/searchlib/docstore/logdocumentstore.cpp b/searchlib/src/vespa/searchlib/docstore/logdocumentstore.cpp
index e2b29f6bdd6..c285d4323c2 100644
--- a/searchlib/src/vespa/searchlib/docstore/logdocumentstore.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/logdocumentstore.cpp
@@ -26,7 +26,7 @@ LogDocumentStore::LogDocumentStore(vespalib::ThreadExecutor & executor,
tuneFileSummary, fileHeaderContext, tlSyncer, bucketizer)
{}
-LogDocumentStore::~LogDocumentStore() {}
+LogDocumentStore::~LogDocumentStore() = default;
void
LogDocumentStore::reconfigure(const Config & config) {