aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorGeir Storli <geirst@yahoo-inc.com>2017-05-12 11:17:32 +0000
committerGeir Storli <geirst@yahoo-inc.com>2017-05-12 14:01:25 +0000
commit90c765974b2d18b70e99a50c14244c5bc0df48d6 (patch)
treeeb61663a5b14920aca87774ab6860c17472604e0 /searchlib
parent473d687fa9c4e72bc8a804fdfcf45c8cc3c789f8 (diff)
Add support for shrinking lid space in LogDataStore.
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp50
-rw-r--r--searchlib/src/vespa/searchlib/common/rcuvector.h4
-rw-r--r--searchlib/src/vespa/searchlib/common/rcuvector.hpp7
-rw-r--r--searchlib/src/vespa/searchlib/docstore/logdatastore.cpp29
-rw-r--r--searchlib/src/vespa/searchlib/docstore/logdatastore.h2
5 files changed, 76 insertions, 16 deletions
diff --git a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
index 54218d5c73f..761d32224f5 100644
--- a/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
+++ b/searchlib/src/tests/docstore/logdatastore/logdatastore_test.cpp
@@ -765,7 +765,7 @@ struct Fixture {
return serialNum++;
}
- Fixture(const vespalib::string &dirName,
+ Fixture(const vespalib::string &dirName = "tmp",
bool dirCleanup = true,
size_t maxFileSize = 4096 * 2)
: executor(1, 0x10000),
@@ -803,6 +803,10 @@ struct Fixture {
}
}
}
+ void compactLidSpace(uint32_t wantedDocIdLimit) {
+ store.compactLidSpace(wantedDocIdLimit);
+ assertDocIdLimit(wantedDocIdLimit);
+ }
void assertDocIdLimit(uint32_t expDocIdLimit) {
EXPECT_EQUAL(expDocIdLimit, store.getDocIdLimit());
}
@@ -881,8 +885,7 @@ TEST("require that lid space can be compacted and entries from old files skipped
TEST_DO(f.assertContent({10,100,101,102,20,200,201,202,30}, 203));
f.assertDocIdLimit(203);
- f.store.compactLidSpace(100);
- f.assertDocIdLimit(100);
+ f.compactLidSpace(100);
TEST_DO(f.assertContent({10,20,30}, 203));
f.writeUntilNewChunk(31);
@@ -898,7 +901,7 @@ TEST("require that lid space can be compacted and entries from old files skipped
}
}
-TEST_F("require that getLid() is protected by docIdLimit", Fixture("tmp"))
+TEST_F("require that getLid() is protected by docIdLimit", Fixture)
{
f.write(1);
vespalib::GenerationHandler::Guard guard = f.store.getLidReadGuard();
@@ -906,6 +909,45 @@ TEST_F("require that getLid() is protected by docIdLimit", Fixture("tmp"))
EXPECT_FALSE(f.store.getLid(guard, 2).valid());
}
+TEST_F("require that lid space can be compacted and shrunk", Fixture)
+{
+ f.write(1).write(2);
+ EXPECT_FALSE(f.store.canShrinkLidSpace());
+
+ f.compactLidSpace(2);
+ MemoryUsage before = f.store.getMemoryUsage();
+ EXPECT_TRUE(f.store.canShrinkLidSpace());
+ f.store.shrinkLidSpace();
+
+ MemoryUsage after = f.store.getMemoryUsage();
+ EXPECT_LESS(after.usedBytes(), before.usedBytes());
+}
+
+TEST_F("require that lid space can be increased after being compacted and then shrunk", Fixture)
+{
+ f.write(1).write(3);
+ TEST_DO(f.compactLidSpace(2));
+ f.write(2);
+ TEST_DO(f.assertDocIdLimit(3));
+ f.store.shrinkLidSpace();
+ TEST_DO(f.assertDocIdLimit(3));
+ TEST_DO(f.assertContent({1,2}, 3));
+}
+
+TEST_F("require that lid space can be shrunk only after read guards are deleted", Fixture)
+{
+ f.write(1).write(2);
+ EXPECT_FALSE(f.store.canShrinkLidSpace());
+ {
+ vespalib::GenerationHandler::Guard guard = f.store.getLidReadGuard();
+ f.compactLidSpace(2);
+ f.write(1); // trigger remove of old generations
+ EXPECT_FALSE(f.store.canShrinkLidSpace());
+ }
+ f.write(1); // trigger remove of old generations
+ EXPECT_TRUE(f.store.canShrinkLidSpace());
+}
+
TEST_MAIN() {
DummyFileHeaderContext::setCreator("logdatastore_test");
TEST_RUN_ALL();
diff --git a/searchlib/src/vespa/searchlib/common/rcuvector.h b/searchlib/src/vespa/searchlib/common/rcuvector.h
index bde7fb2accb..aeaec9b1022 100644
--- a/searchlib/src/vespa/searchlib/common/rcuvector.h
+++ b/searchlib/src/vespa/searchlib/common/rcuvector.h
@@ -58,7 +58,7 @@ private:
}
void expand(size_t newCapacity);
void expandAndInsert(const T & v);
- virtual void onExpand();
+ virtual void onReallocation();
public:
using ValueType = T;
@@ -133,7 +133,7 @@ private:
generation_t _generation;
GenerationHolder _genHolderStore;
- void onExpand() override;
+ void onReallocation() override;
public:
RcuVector();
diff --git a/searchlib/src/vespa/searchlib/common/rcuvector.hpp b/searchlib/src/vespa/searchlib/common/rcuvector.hpp
index c68016dea81..9424331d014 100644
--- a/searchlib/src/vespa/searchlib/common/rcuvector.hpp
+++ b/searchlib/src/vespa/searchlib/common/rcuvector.hpp
@@ -60,7 +60,7 @@ RcuVectorBase<T>::expand(size_t newCapacity) {
size_t holdSize = tmpData->capacity() * sizeof(T);
vespalib::GenerationHeldBase::UP hold(new RcuVectorHeld<Array>(holdSize, std::move(tmpData)));
_genHolder.hold(std::move(hold));
- onExpand();
+ onReallocation();
}
template <typename T>
@@ -95,6 +95,7 @@ RcuVectorBase<T>::shrink(size_t newSize)
size_t holdSize = tmpData->capacity() * sizeof(T);
vespalib::GenerationHeldBase::UP hold(new RcuVectorHeld<Array>(holdSize, std::move(tmpData)));
_genHolder.hold(std::move(hold));
+ onReallocation();
}
}
@@ -144,11 +145,11 @@ RcuVectorBase<T>::getMemoryUsage() const
template <typename T>
void
-RcuVectorBase<T>::onExpand() { }
+RcuVectorBase<T>::onReallocation() { }
template <typename T>
void
-RcuVector<T>::onExpand() {
+RcuVector<T>::onReallocation() {
_genHolderStore.transferHoldLists(_generation);
}
diff --git a/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp b/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp
index 245f0ea912b..159c9882d31 100644
--- a/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp
+++ b/searchlib/src/vespa/searchlib/docstore/logdatastore.cpp
@@ -54,7 +54,8 @@ LogDataStore::LogDataStore(vespalib::ThreadExecutor &executor,
_initFlushSyncToken(0),
_tlSyncer(tlSyncer),
_bucketizer(bucketizer),
- _currentlyCompacting()
+ _currentlyCompacting(),
+ _compactLidSpaceGeneration()
{
// Reserve space for 1TB summary in order to avoid locking.
_fileChunks.reserve(LidInfo::getFileIdLimit());
@@ -886,15 +887,21 @@ LogDataStore::setLid(const LockGuard &guard, uint32_t lid, const LidInfo &meta)
}
} else {
_lidInfo.ensure_size(lid+1, LidInfo());
- _lidInfo.setGeneration(_genHandler.getNextGeneration());
- _genHandler.incGeneration();
- _genHandler.updateFirstUsedGeneration();
- _lidInfo.removeOldGenerations(_genHandler.getFirstUsedGeneration());
- updateDocIdLimit(_lidInfo.size());
+ incGeneration();
}
+ updateDocIdLimit(lid + 1);
_lidInfo[lid] = meta;
}
+void
+LogDataStore::incGeneration()
+{
+ _lidInfo.setGeneration(_genHandler.getNextGeneration());
+ _genHandler.incGeneration();
+ _genHandler.updateFirstUsedGeneration();
+ _lidInfo.removeOldGenerations(_genHandler.getFirstUsedGeneration());
+}
+
size_t
LogDataStore::computeNumberOfSignificantBucketIdBits(const IBucketizer & bucketizer, FileId fileId) const
{
@@ -1119,21 +1126,29 @@ void
LogDataStore::compactLidSpace(uint32_t wantedDocLidLimit)
{
LockGuard guard(_updateLock);
+ assert(wantedDocLidLimit <= getDocIdLimit());
for (size_t i = wantedDocLidLimit; i < _lidInfo.size(); ++i) {
_lidInfo[i] = LidInfo();
}
setDocIdLimit(wantedDocLidLimit);
+ _compactLidSpaceGeneration = _genHandler.getCurrentGeneration();
+ incGeneration();
}
bool
LogDataStore::canShrinkLidSpace() const
{
- return false;
+ return getDocIdLimit() < _lidInfo.size() &&
+ _compactLidSpaceGeneration < _genHandler.getFirstUsedGeneration();
}
void
LogDataStore::shrinkLidSpace()
{
+ assert(canShrinkLidSpace());
+ LockGuard guard(_updateLock);
+ _lidInfo.shrink(getDocIdLimit());
+ incGeneration();
}
} // namespace search
diff --git a/searchlib/src/vespa/searchlib/docstore/logdatastore.h b/searchlib/src/vespa/searchlib/docstore/logdatastore.h
index 037cac58fae..c426d9bb46c 100644
--- a/searchlib/src/vespa/searchlib/docstore/logdatastore.h
+++ b/searchlib/src/vespa/searchlib/docstore/logdatastore.h
@@ -304,6 +304,7 @@ private:
}
bool shouldCompactToActiveFile(size_t compactedSize) const;
std::pair<bool, FileId> findNextToCompact();
+ void incGeneration();
typedef std::vector<FileId> FileIdxVector;
Config _config;
@@ -322,6 +323,7 @@ private:
transactionlog::SyncProxy &_tlSyncer;
IBucketizer::SP _bucketizer;
NameIdSet _currentlyCompacting;
+ uint64_t _compactLidSpaceGeneration;
};
} // namespace search