diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2020-10-06 11:10:24 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@broadpark.no> | 2020-10-06 11:10:24 +0200 |
commit | 43cf58d24470e3c0cc85ec43a3bf8f314cd29c99 (patch) | |
tree | e618d3e2238aaaf88dbc049b6d0e4c12dc2b547f /searchcore/src | |
parent | 5c4a0dab894a17b2a20a4e1b51b51d274c5c5265 (diff) |
Reuse document meta store state from prepare step instead of doing
a new lookup in btree mapping from gid to lid during live feed.
Diffstat (limited to 'searchcore/src')
22 files changed, 170 insertions, 144 deletions
diff --git a/searchcore/src/tests/proton/docsummary/docsummary.cpp b/searchcore/src/tests/proton/docsummary/docsummary.cpp index 7e4e05f6948..07f023982c9 100644 --- a/searchcore/src/tests/proton/docsummary/docsummary.cpp +++ b/searchcore/src/tests/proton/docsummary/docsummary.cpp @@ -245,7 +245,7 @@ public: IDocumentMetaStore &dms = _ddb->getReadySubDB()->getDocumentMetaStoreContext().get(); uint32_t docSize = 1; PutRes putRes(dms.put(docId.getGlobalId(), BucketFactory::getBucketId(docId), - Timestamp(0u), docSize, lid)); + Timestamp(0u), docSize, lid, 0u)); LOG_ASSERT(putRes.ok()); uint64_t serialNum = _ddb->getFeedHandler().incSerialNum(); _aw->put(serialNum, doc, lid, true, std::shared_ptr<IDestructorCallback>()); diff --git a/searchcore/src/tests/proton/documentdb/buckethandler/buckethandler_test.cpp b/searchcore/src/tests/proton/documentdb/buckethandler/buckethandler_test.cpp index b16bf6620c2..3adb153863c 100644 --- a/searchcore/src/tests/proton/documentdb/buckethandler/buckethandler_test.cpp +++ b/searchcore/src/tests/proton/documentdb/buckethandler/buckethandler_test.cpp @@ -47,7 +47,7 @@ struct MySubDb for (size_t i = 0; i < bucketDocs.getDocs().size(); ++i) { const test::Document &testDoc = bucketDocs.getDocs()[i]; _metaStore.put(testDoc.getGid(), testDoc.getBucket(), - testDoc.getTimestamp(), testDoc.getDocSize(), testDoc.getLid()); + testDoc.getTimestamp(), testDoc.getDocSize(), testDoc.getLid(), 0u); } } } diff --git a/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp index fc2a4326ccc..74f3c8e7591 100644 --- a/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/combiningfeedview/combiningfeedview_test.cpp @@ -106,7 +106,7 @@ struct MySubDb for (size_t i = 0; i < docs.getDocs().size(); ++i) { const test::Document &testDoc = docs.getDocs()[i]; _view->_metaStore.put(testDoc.getGid(), testDoc.getBucket(), - testDoc.getTimestamp(), testDoc.getDocSize(), testDoc.getLid()); + testDoc.getTimestamp(), testDoc.getDocSize(), testDoc.getLid(), 0u); } } }; diff --git a/searchcore/src/tests/proton/documentdb/document_scan_iterator/document_scan_iterator_test.cpp b/searchcore/src/tests/proton/documentdb/document_scan_iterator/document_scan_iterator_test.cpp index ec82ca0637f..73fac7d9439 100644 --- a/searchcore/src/tests/proton/documentdb/document_scan_iterator/document_scan_iterator_test.cpp +++ b/searchcore/src/tests/proton/documentdb/document_scan_iterator/document_scan_iterator_test.cpp @@ -36,10 +36,10 @@ struct Fixture Fixture &add(uint32_t lid) { DocumentId docId(make_string("id:test:test:n=%u:%u", 1, lid)); const GlobalId &gid = docId.getGlobalId(); - DMSResult res = _metaStore.inspect(gid); + DMSResult res = _metaStore.inspect(gid, 0u); ASSERT_EQUAL(lid, res._lid); uint32_t docSize = 1; - _metaStore.put(gid, gid.convertToBucketId(), Timestamp(lid), docSize, lid); + _metaStore.put(gid, gid.convertToBucketId(), Timestamp(lid), docSize, lid, 0u); return *this; } LidSet scan(uint32_t count, uint32_t compactLidLimit, uint32_t maxDocsToScan = 10) { diff --git a/searchcore/src/tests/proton/documentdb/documentbucketmover/documentbucketmover_test.cpp b/searchcore/src/tests/proton/documentdb/documentbucketmover/documentbucketmover_test.cpp index bdeb4a09685..7126cb04892 100644 --- a/searchcore/src/tests/proton/documentdb/documentbucketmover/documentbucketmover_test.cpp +++ b/searchcore/src/tests/proton/documentdb/documentbucketmover/documentbucketmover_test.cpp @@ -142,7 +142,7 @@ struct MySubDb for (size_t i = 0; i < bucketDocs.getDocs().size(); ++i) { const test::Document &testDoc = bucketDocs.getDocs()[i]; _metaStore.put(testDoc.getGid(), testDoc.getBucket(), - testDoc.getTimestamp(), testDoc.getDocSize(), testDoc.getLid()); + testDoc.getTimestamp(), testDoc.getDocSize(), testDoc.getLid(), 0u); _realRetriever->_docs.push_back(testDoc.getDoc()); ASSERT_EQUAL(testDoc.getLid() + 1, _realRetriever->_docs.size()); @@ -166,7 +166,7 @@ struct MySubDb void removeBucket(uint32_t userId) { const test::DocumentVector &userDocs = _docs.getDocs(userId); for (size_t i = 0; i < userDocs.size(); ++i) { - _metaStore.remove(userDocs[i].getLid()); + _metaStore.remove(userDocs[i].getLid(), 0u); if (_metaStore.getFreeListActive()) { _metaStore.removeComplete(userDocs[i].getLid()); } diff --git a/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp b/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp index f033dfd50a8..70b2100521f 100644 --- a/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp +++ b/searchcore/src/tests/proton/documentdb/maintenancecontroller/maintenancecontroller_test.cpp @@ -539,7 +539,7 @@ MyDocumentSubDB::handlePut(PutOperation &op) op.getBucketId(), op.getTimestamp(), op.getSerializedDocSize(), - op.getLid())); + op.getLid(), 0u)); assert(putRes.ok()); assert(op.getLid() == putRes._lid); _docs[op.getLid()] = doc; @@ -552,7 +552,7 @@ MyDocumentSubDB::handlePut(PutOperation &op) assert(meta.getGid() == gid); (void) meta; - bool remres = _metaStore.remove(op.getPrevLid()); + bool remres = _metaStore.remove(op.getPrevLid(), 0u); assert(remres); (void) remres; _metaStore.removeComplete(op.getPrevLid()); @@ -581,7 +581,7 @@ MyDocumentSubDB::handleRemove(RemoveOperationWithDocId &op) op.getBucketId(), op.getTimestamp(), op.getSerializedDocSize(), - op.getLid())); + op.getLid(), 0u)); assert(putRes.ok()); assert(op.getLid() == putRes._lid); const document::DocumentType *docType = @@ -598,7 +598,7 @@ MyDocumentSubDB::handleRemove(RemoveOperationWithDocId &op) assert(meta.getGid() == gid); (void) meta; - bool remres = _metaStore.remove(op.getPrevLid()); + bool remres = _metaStore.remove(op.getPrevLid(), 0u); assert(remres); (void) remres; @@ -617,7 +617,7 @@ MyDocumentSubDB::prepareMove(MoveOperation &op) { const DocumentId &docId = op.getDocument()->getId(); const document::GlobalId &gid = docId.getGlobalId(); - DocumentMetaStore::Result inspectResult = _metaStore.inspect(gid); + DocumentMetaStore::Result inspectResult = _metaStore.inspect(gid, 0u); assert(!inspectResult._found); op.setDbDocumentId(DbDocumentId(_subDBId, inspectResult._lid)); } @@ -639,7 +639,7 @@ MyDocumentSubDB::handleMove(const MoveOperation &op) op.getBucketId(), op.getTimestamp(), op.getSerializedDocSize(), - op.getLid())); + op.getLid(), 0u)); assert(putRes.ok()); assert(op.getLid() == putRes._lid); _docs[op.getLid()] = doc; @@ -652,7 +652,7 @@ MyDocumentSubDB::handleMove(const MoveOperation &op) assert(meta.getGid() == gid); (void) meta; - bool remres = _metaStore.remove(op.getPrevLid()); + bool remres = _metaStore.remove(op.getPrevLid(), 0u); assert(remres); (void) remres; diff --git a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp index 7a2fadeaa2d..8d1276497bd 100644 --- a/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp +++ b/searchcore/src/tests/proton/documentdb/storeonlyfeedview/storeonlyfeedview_test.cpp @@ -223,12 +223,12 @@ struct FixtureBase { void addSingleDocToMetaStore(uint32_t expected_lid) { using Result = DocumentMetaStore::Result; DocumentId id(make_string("id:test:foo:g=foo:%d", expected_lid)); - Result inspect = metaStore->inspect(id.getGlobalId()); + Result inspect = metaStore->inspect(id.getGlobalId(), 0u); uint32_t docSize = 1; EXPECT_EQUAL(expected_lid, metaStore->put(id.getGlobalId(), id.getGlobalId().convertToBucketId(), - Timestamp(10), docSize, inspect.getLid()).getLid()); + Timestamp(10), docSize, inspect.getLid(), 0u).getLid()); } void addDocsToMetaStore(int count) { @@ -331,11 +331,11 @@ TEST_F("require that handleMove() handles move within same subdb and propagates uint32_t docSize = 1; f.runInMaster([&] () { f.metaStore->put(doc1id.getGlobalId(), doc1id.getGlobalId().convertToBucketId(), - Timestamp(9), docSize, 1); }); + Timestamp(9), docSize, 1, 0u); }); f.runInMaster([&] () { f.metaStore->put(doc->getId().getGlobalId(), doc->getId().getGlobalId().convertToBucketId(), - Timestamp(10), docSize, 2); }); - f.runInMaster([&] () { f.metaStore->remove(1); }); + Timestamp(10), docSize, 2, 0u); }); + f.runInMaster([&] () { f.metaStore->remove(1, 0u); }); f.metaStore->removeComplete(1); MoveOperation::UP op = makeMoveOp(doc, DbDocumentId(subdb_id, 2), subdb_id); op->setTargetLid(1); diff --git a/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp b/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp index 49b84c09040..9ca22bafe9a 100644 --- a/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp +++ b/searchcore/src/tests/proton/documentmetastore/documentmetastore_test.cpp @@ -118,9 +118,9 @@ assertPut(const BucketId &bucketId, const GlobalId &gid, DocumentMetaStore &dms) { - Result inspect = dms.inspect(gid); + Result inspect = dms.inspect(gid, 0u); uint32_t docSize = 1; - PutRes putRes = dms.put(gid, bucketId, timestamp, docSize, inspect.getLid()); + PutRes putRes = dms.put(gid, bucketId, timestamp, docSize, inspect.getLid(), 0u); EXPECT_TRUE(putRes.ok()); EXPECT_EQ(lid, putRes.getLid()); } @@ -258,9 +258,9 @@ uint32_t docSize5 = 1; uint32_t addGid(DocumentMetaStore &dms, const GlobalId &gid, const BucketId &bid, Timestamp timestamp, uint32_t docSize = 1) { - Result inspect = dms.inspect(gid); + Result inspect = dms.inspect(gid, 0u); PutRes putRes; - EXPECT_TRUE((putRes = dms.put(gid, bid, timestamp, docSize, inspect.getLid())).ok()); + EXPECT_TRUE((putRes = dms.put(gid, bid, timestamp, docSize, inspect.getLid(), 0u)).ok()); return putRes.getLid(); } @@ -276,7 +276,7 @@ putGid(DocumentMetaStore &dms, const GlobalId &gid, uint32_t lid, Timestamp time { BucketId bid(minNumBits, gid.convertToBucketId().getRawId()); uint32_t docSize = 1; - EXPECT_TRUE(dms.put(gid, bid, timestamp, docSize, lid).ok()); + EXPECT_TRUE(dms.put(gid, bid, timestamp, docSize, lid, 0u).ok()); } TEST(DocumentMetaStoreTest, removed_documents_are_bucketized_to_bucket_0) @@ -292,7 +292,7 @@ TEST(DocumentMetaStoreTest, removed_documents_are_bucketized_to_bucket_0) EXPECT_EQ(bucketId1, dms.getBucketOf(guard, 1)); assertPut(bucketId2, time2, 2, gid2, dms); EXPECT_EQ(bucketId2, dms.getBucketOf(guard, 2)); - EXPECT_TRUE(dms.remove(1)); + EXPECT_TRUE(dms.remove(1, 0u)); EXPECT_EQ(BucketId(), dms.getBucketOf(guard, 1)); EXPECT_EQ(bucketId2, dms.getBucketOf(guard, 2)); } @@ -339,7 +339,7 @@ TEST(DocumentMetaStore, gids_can_be_cleared) assertGid(gid1, 1, dms); assertLid(1, gid1, dms); EXPECT_EQ(1u, dms.getNumUsedLids()); - EXPECT_TRUE(dms.remove(1)); + EXPECT_TRUE(dms.remove(1, 0u)); dms.removeComplete(1); EXPECT_EQ(0u, dms.getNumUsedLids()); EXPECT_TRUE(!dms.getGid(1, gid)); @@ -349,13 +349,13 @@ TEST(DocumentMetaStore, gids_can_be_cleared) assertGid(gid2, 1, dms); assertLid(1, gid2, dms); EXPECT_EQ(1u, dms.getNumUsedLids()); - EXPECT_TRUE(dms.remove(1)); + EXPECT_TRUE(dms.remove(1, 0u)); dms.removeComplete(1); EXPECT_EQ(0u, dms.getNumUsedLids()); EXPECT_TRUE(!dms.getGid(1, gid)); EXPECT_TRUE(!dms.getLid(gid2, lid)); - EXPECT_TRUE(!dms.remove(1)); // not used - EXPECT_TRUE(!dms.remove(2)); // outside range + EXPECT_TRUE(!dms.remove(1, 0u)); // not used + EXPECT_TRUE(!dms.remove(2, 0u)); // outside range } TEST(DocumentMetaStore, generation_handling_is_working) @@ -378,7 +378,7 @@ TEST(DocumentMetaStore, generation_handling_is_working) EXPECT_EQ(1u, gh.getGenerationRefCount()); } EXPECT_EQ(0u, gh.getGenerationRefCount()); - dms->remove(1); + dms->remove(1, 0u); dms->removeComplete(1); EXPECT_EQ(4u, gh.getCurrentGeneration()); } @@ -513,7 +513,7 @@ TEST(DocumentMetaStoreTest, lid_and_gid_space_is_reused) assertPut(bucketId2, time2, 2, gid2, *dms); // -> gen 2 EXPECT_EQ(3u, dms->getNumDocs()); EXPECT_EQ(2u, dms->getNumUsedLids()); - dms->remove(2); // -> gen 3 + dms->remove(2, 0u); // -> gen 3 dms->removeComplete(2); // -> gen 4 EXPECT_EQ(3u, dms->getNumDocs()); EXPECT_EQ(1u, dms->getNumUsedLids()); @@ -524,7 +524,7 @@ TEST(DocumentMetaStoreTest, lid_and_gid_space_is_reused) assertGid(gid3, 2, *dms); { AttributeGuard g1(av); // guard on gen 5 - dms->remove(2); + dms->remove(2, 0u); dms->removeComplete(2); EXPECT_EQ(3u, dms->getNumDocs()); EXPECT_EQ(1u, dms->getNumUsedLids()); // lid 2 free but guarded @@ -598,7 +598,7 @@ TEST(DocumentMetaStoreTest, gids_can_be_saved_and_loaded) EXPECT_EQ(lid, addLid); } for (size_t i = 0; i < removeLids.size(); ++i) { - dms1.remove(removeLids[i]); + dms1.remove(removeLids[i], 0u); dms1.removeComplete(removeLids[i]); } uint64_t expSaveBytesSize = DocumentMetaStore::minHeaderLen + @@ -686,28 +686,28 @@ TEST(DocumentMetaStore, stats_are_updated) TEST(DocumentMetaStoreTest, can_put_and_remove_before_free_list_construct) { DocumentMetaStore dms(createBucketDB()); - EXPECT_TRUE(dms.put(gid4, bucketId4, time4, docSize4, 4).ok()); + EXPECT_TRUE(dms.put(gid4, bucketId4, time4, docSize4, 4, 0u).ok()); assertLid(4, gid4, dms); assertGid(gid4, 4, dms); EXPECT_EQ(1u, dms.getNumUsedLids()); EXPECT_EQ(5u, dms.getNumDocs()); - EXPECT_TRUE(dms.put(gid1, bucketId1, time1, docSize1, 1).ok()); + EXPECT_TRUE(dms.put(gid1, bucketId1, time1, docSize1, 1, 0u).ok()); // already there, nothing changes - EXPECT_TRUE(dms.put(gid1, bucketId1, time1, docSize1, 1).ok()); + EXPECT_TRUE(dms.put(gid1, bucketId1, time1, docSize1, 1, 0u).ok()); assertLid(1, gid1, dms); assertGid(gid1, 1, dms); EXPECT_EQ(2u, dms.getNumUsedLids()); EXPECT_EQ(5u, dms.getNumDocs()); // gid1 already there with lid 1 - EXPECT_THROW(dms.put(gid1, bucketId1, time1, docSize1, 2).ok(), + EXPECT_THROW(dms.put(gid1, bucketId1, time1, docSize1, 2, 0u).ok(), vespalib::IllegalStateException); - EXPECT_THROW(dms.put(gid5, bucketId5, time5, docSize5, 1).ok(), + EXPECT_THROW(dms.put(gid5, bucketId5, time5, docSize5, 1, 0u).ok(), vespalib::IllegalStateException); assertLid(1, gid1, dms); assertGid(gid1, 1, dms); EXPECT_EQ(2u, dms.getNumUsedLids()); EXPECT_EQ(5u, dms.getNumDocs()); - EXPECT_TRUE(dms.remove(4)); // -> goes to free list. cleared and re-applied in constructFreeList(). + EXPECT_TRUE(dms.remove(4, 0u)); // -> goes to free list. cleared and re-applied in constructFreeList(). uint32_t lid; GlobalId gid; EXPECT_TRUE(!dms.getLid(gid4, lid)); @@ -793,7 +793,7 @@ requireThatBasicBucketInfoWorks() GlobalId gid = createGid(lid); BucketId bucketId(minNumBits, gid.convertToBucketId().getRawId()); - EXPECT_TRUE(dms.remove(lid)); + EXPECT_TRUE(dms.remove(lid, 0u)); dms.removeComplete(lid); m.erase(std::make_pair(bucketId, gid)); } @@ -873,7 +873,7 @@ TEST(DocumentMetaStoreTest, can_retrieve_list_of_lids_from_bucket_id) const BucketId &bucketId = itr->first; const LidVector &expLids = itr->second; for (size_t i = 0; i < expLids.size(); ++i) { - EXPECT_TRUE(dms.remove(expLids[i])); + EXPECT_TRUE(dms.remove(expLids[i], 0u)); dms.removeComplete(expLids[i]); } LOG(info, "Verify that bucket id '%s' has 0 lids", bucketId.toString().c_str()); @@ -1033,14 +1033,14 @@ TEST(DocumentMetaStoreTest, removed_lids_are_cleared_as_active) f.dms.setBucketState(f.bid1, true); assertActiveLids(BoolVector().T().T(), f.dms.getActiveLids()); EXPECT_EQ(2u, f.dms.getNumActiveLids()); - f.dms.remove(2); + f.dms.remove(2, 0u); f.dms.removeComplete(2); assertActiveLids(BoolVector().T().F(), f.dms.getActiveLids()); EXPECT_EQ(1u, f.dms.getNumActiveLids()); f.addGlobalId(f.gids[2], 2); // from bid2 assertActiveLids(BoolVector().T().F(), f.dms.getActiveLids()); EXPECT_EQ(1u, f.dms.getNumActiveLids()); - f.dms.remove(2); + f.dms.remove(2, 0u); f.dms.removeComplete(2); f.addGlobalId(f.gids[3], 2); // from bid1 assertActiveLids(BoolVector().T().T(), f.dms.getActiveLids()); @@ -1075,7 +1075,7 @@ TEST(DocumentMetaStoreTest, document_and_meta_entry_count_is_updated) EXPECT_EQ(4u, f.dms.getBucketDB().takeGuard()->get(f.bid1).getEntryCount()); EXPECT_EQ(3u, f.dms.getBucketDB().takeGuard()->get(f.bid2).getDocumentCount()); EXPECT_EQ(3u, f.dms.getBucketDB().takeGuard()->get(f.bid2).getEntryCount()); - f.dms.remove(3); // from bid2 + f.dms.remove(3, 0u); // from bid2 f.dms.removeComplete(3); EXPECT_EQ(4u, f.dms.getBucketDB().takeGuard()->get(f.bid1).getDocumentCount()); EXPECT_EQ(4u, f.dms.getBucketDB().takeGuard()->get(f.bid1).getEntryCount()); @@ -1092,18 +1092,18 @@ TEST(DocumentMetaStoreTest, empty_buckets_are_removed) f.addGlobalIds(3); EXPECT_TRUE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid1)); EXPECT_TRUE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid2)); - f.dms.remove(3); // from bid2 + f.dms.remove(3, 0u); // from bid2 f.dms.removeComplete(3); EXPECT_TRUE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid1)); EXPECT_TRUE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid2)); EXPECT_EQ(0u, f.dms.getBucketDB().takeGuard()->get(f.bid2).getEntryCount()); f._bucketDBHandler.handleDeleteBucket(f.bid2); EXPECT_FALSE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid2)); - f.dms.remove(1); // from bid1 + f.dms.remove(1, 0u); // from bid1 f.dms.removeComplete(1); EXPECT_TRUE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid1)); EXPECT_FALSE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid2)); - f.dms.remove(2); // from bid1 + f.dms.remove(2, 0u); // from bid1 f.dms.removeComplete(2); EXPECT_TRUE(f.dms.getBucketDB().takeGuard()->hasBucket(f.bid1)); EXPECT_EQ(0u, f.dms.getBucketDB().takeGuard()->get(f.bid1).getEntryCount()); @@ -1214,7 +1214,7 @@ struct SplitAndJoinFixture : public SplitAndJoinEmptyFixture { for (size_t i = 0; i < gids.size(); ++i) { EXPECT_TRUE(dms.put(gids[i].gid, gids[i].bid1, Timestamp(0), docSize, - gids[i].lid).ok()); + gids[i].lid, 0u).ok()); } } void insertGids2() { @@ -1222,7 +1222,7 @@ struct SplitAndJoinFixture : public SplitAndJoinEmptyFixture { for (size_t i = 0; i < gids.size(); ++i) { EXPECT_TRUE(dms.put(gids[i].gid, gids[i].bid2, Timestamp(0), docSize, - gids[i].lid).ok()); + gids[i].lid, 0u).ok()); } } @@ -1233,7 +1233,7 @@ struct SplitAndJoinFixture : public SplitAndJoinEmptyFixture { for (size_t i = 0; i < gids.size(); ++i) { const GlobalIdEntry &g(gids[i]); BucketId b(g.bid3 == alt ? g.bid2 : g.bid1); - EXPECT_TRUE(dms.put(g.gid, b, Timestamp(0), docSize, g.lid).ok()); + EXPECT_TRUE(dms.put(g.gid, b, Timestamp(0), docSize, g.lid, 0u).ok()); } } @@ -1244,7 +1244,7 @@ struct SplitAndJoinFixture : public SplitAndJoinEmptyFixture { for (size_t i = 0; i < gids.size(); ++i) { const GlobalIdEntry &g(gids[i]); BucketId b(g.bid3 == alt ? g.bid1 : g.bid2); - EXPECT_TRUE(dms.put(g.gid, b, Timestamp(0), docSize, g.lid).ok()); + EXPECT_TRUE(dms.put(g.gid, b, Timestamp(0), docSize, g.lid, 0u).ok()); } } }; @@ -1712,7 +1712,7 @@ TEST(DocumentMetaStoreTest, remove_changed_bucket_works) EXPECT_EQ(1u, addLid1); uint32_t addLid2 = addGid(f.dms, g.gid, g.bid2, Timestamp(0)); EXPECT_TRUE(1u == addLid2); - EXPECT_TRUE(f.dms.remove(1u)); + EXPECT_TRUE(f.dms.remove(1u, 0u)); f.dms.removeComplete(1u); } @@ -1752,7 +1752,7 @@ TEST(DocumentMetaStoreTest, get_lid_usage_stats_works) EXPECT_EQ(4u, s.getLowestFreeLid()); EXPECT_EQ(3u, s.getHighestUsedLid()); - dms.remove(1); + dms.remove(1, 0u); dms.removeComplete(1); s = dms.getLidUsageStats(); @@ -1761,7 +1761,7 @@ TEST(DocumentMetaStoreTest, get_lid_usage_stats_works) EXPECT_EQ(1u, s.getLowestFreeLid()); EXPECT_EQ(3u, s.getHighestUsedLid()); - dms.remove(3); + dms.remove(3, 0u); dms.removeComplete(3); s = dms.getLidUsageStats(); @@ -1770,7 +1770,7 @@ TEST(DocumentMetaStoreTest, get_lid_usage_stats_works) EXPECT_EQ(1u, s.getLowestFreeLid()); EXPECT_EQ(2u, s.getHighestUsedLid()); - dms.remove(2); + dms.remove(2, 0u); dms.removeComplete(2); s = dms.getLidUsageStats(); @@ -1813,7 +1813,7 @@ TEST(DocumentMetaStoreTest, move_works) EXPECT_TRUE(dms.getLid(gid2, lid)); EXPECT_EQ(gid1, gid); EXPECT_EQ(2u, lid); - EXPECT_TRUE(dms.remove(1)); + EXPECT_TRUE(dms.remove(1, 0u)); EXPECT_FALSE(dms.getGid(1u, gid)); EXPECT_FALSE(dms.getGidEvenIfMoved(1u, gid)); EXPECT_TRUE(dms.getGid(2u, gid)); @@ -1822,7 +1822,7 @@ TEST(DocumentMetaStoreTest, move_works) EXPECT_FALSE(dms.getGidEvenIfMoved(1u, gid)); EXPECT_TRUE(dms.getGid(2u, gid)); EXPECT_EQ(1u, dms.getNumUsedLids()); - dms.move(2u, 1u); + dms.move(2u, 1u, 0u); EXPECT_TRUE(dms.getGid(1u, gid)); EXPECT_FALSE(dms.getGid(2u, gid)); EXPECT_TRUE(dms.getGidEvenIfMoved(2u, gid)); @@ -1864,7 +1864,7 @@ void remove(uint32_t startLid, uint32_t shrinkTarget, DocumentMetaStore &dms) { for (uint32_t lid = startLid; lid >= shrinkTarget; --lid) { - dms.remove(lid); + dms.remove(lid, 0u); dms.removeComplete(lid); } } @@ -1962,7 +1962,7 @@ assertSize(DocumentMetaStore &dms, uint32_t lid, uint32_t expSize) void removeLid(DocumentMetaStore &dms, uint32_t lid) { - dms.remove(lid); + dms.remove(lid, 0u); dms.removeComplete(lid); } @@ -2119,7 +2119,7 @@ TEST(DocumentMetaStoreTest, call_to_remove_is_notified) dms.constructFreeList(); addLid(dms, 1); - dms.remove(1); + dms.remove(1, 0u); EXPECT_EQ(1, listener->remove_cnt); } diff --git a/searchcore/src/tests/proton/documentmetastore/lidreusedelayer/lidreusedelayer_test.cpp b/searchcore/src/tests/proton/documentmetastore/lidreusedelayer/lidreusedelayer_test.cpp index 32cc9d989d8..453f7eb638e 100644 --- a/searchcore/src/tests/proton/documentmetastore/lidreusedelayer/lidreusedelayer_test.cpp +++ b/searchcore/src/tests/proton/documentmetastore/lidreusedelayer/lidreusedelayer_test.cpp @@ -58,15 +58,15 @@ public: ~MyMetaStore() override = default; - Result inspectExisting(const GlobalId &) const override { + Result inspectExisting(const GlobalId &, uint64_t) override { return Result(); } - Result inspect(const GlobalId &) override { + Result inspect(const GlobalId &, uint64_t) override { return Result(); } - Result put(const GlobalId &, const BucketId &, const Timestamp &, uint32_t, DocId) override { + Result put(const GlobalId &, const BucketId &, const Timestamp &, uint32_t, DocId, uint64_t) override { return Result(); } @@ -74,7 +74,7 @@ public: return true; } - bool remove(DocId) override { + bool remove(DocId, uint64_t) override { return true; } @@ -83,7 +83,7 @@ public: ++_removeCompleteLids; } - void move(DocId, DocId) override { + void move(DocId, DocId, uint64_t) override { } bool validLid(DocId) const override { diff --git a/searchcore/src/tests/proton/matching/matching_test.cpp b/searchcore/src/tests/proton/matching/matching_test.cpp index 0ea63bce859..22dc19167f6 100644 --- a/searchcore/src/tests/proton/matching/matching_test.cpp +++ b/searchcore/src/tests/proton/matching/matching_test.cpp @@ -198,7 +198,7 @@ struct MyWorld { const document::GlobalId &gid = docId.getGlobalId(); document::BucketId bucketId(BucketFactory::getBucketId(docId)); uint32_t docSize = 1; - metaStore.put(gid, bucketId, Timestamp(0u), docSize, i); + metaStore.put(gid, bucketId, Timestamp(0u), docSize, i, 0u); metaStore.setBucketState(bucketId, true); } } diff --git a/searchcore/src/tests/proton/reference/gid_to_lid_mapper/gid_to_lid_mapper_test.cpp b/searchcore/src/tests/proton/reference/gid_to_lid_mapper/gid_to_lid_mapper_test.cpp index a209dcd1f5d..30e3c86cb34 100644 --- a/searchcore/src/tests/proton/reference/gid_to_lid_mapper/gid_to_lid_mapper_test.cpp +++ b/searchcore/src/tests/proton/reference/gid_to_lid_mapper/gid_to_lid_mapper_test.cpp @@ -97,19 +97,19 @@ struct Fixture bumpTimeStamp(); const GlobalId gid(toGid(docId)); uint32_t docSize = 1; - _dms->put(gid, toBucketId(gid), _timestamp, docSize, lid); + _dms->put(gid, toBucketId(gid), _timestamp, docSize, lid, 0u); _dms->commit(); } uint32_t put(vespalib::stringref docId) { - auto inspectRes = _dms->inspect(toGid(docId)); + auto inspectRes = _dms->inspect(toGid(docId), 0u); uint32_t lid = inspectRes.getLid(); put(docId, lid); return lid; } void remove(uint32_t lid) { - if (_dms->remove(lid)) { + if (_dms->remove(lid, 0u)) { _dms->removeComplete(lid); } _dms->commit(); diff --git a/searchcore/src/tests/proton/server/documentretriever_test.cpp b/searchcore/src/tests/proton/server/documentretriever_test.cpp index a934254aca3..90d76e4540b 100644 --- a/searchcore/src/tests/proton/server/documentretriever_test.cpp +++ b/searchcore/src/tests/proton/server/documentretriever_test.cpp @@ -339,9 +339,9 @@ struct Fixture { { typedef DocumentMetaStore::Result Result; meta_store.constructFreeList(); - Result inspect = meta_store.get().inspect(gid); + Result inspect = meta_store.get().inspect(gid, 0u); uint32_t docSize = 1; - Result putRes(meta_store.get().put(gid, bucket_id, timestamp, docSize, inspect.getLid())); + Result putRes(meta_store.get().put(gid, bucket_id, timestamp, docSize, inspect.getLid(), 0u)); lid = putRes.getLid(); ASSERT_TRUE(putRes.ok()); schema::CollectionType ct = schema::CollectionType::SINGLE; diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp index c6a2564cea2..f0a44744feb 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.cpp @@ -173,15 +173,12 @@ DocumentMetaStore::ensureSpace(DocId lid) _lidAlloc.ensureSpace(newSize, newCapacity); } -bool +void DocumentMetaStore::insert(DocId lid, const RawDocumentMetaData &metaData) { ensureSpace(lid); _metaDataStore[lid] = metaData; - KeyComp comp(metaData, _metaDataStore, *_gidCompare); - if (!_gidToLidMap.insert(lid, BTreeNoLeafData(), comp)) { - return false; - } + _gidToLidMap.insert(_gid_to_lid_map_write_itr, lid, BTreeNoLeafData()); // flush writes to meta store rcu vector before new entry is visible // from frozen root or lid based scan std::atomic_thread_fence(std::memory_order_release); @@ -196,7 +193,6 @@ DocumentMetaStore::insert(DocId lid, const RawDocumentMetaData &metaData) _subDbType); _lidAlloc.updateActiveLids(lid, state.isActive()); updateCommittedDocIdLimit(); - return true; } void @@ -392,6 +388,8 @@ DocumentMetaStore::DocumentMetaStore(BucketDBOwner::SP bucketDB, grow.getDocsGrowDelta(), getGenerationHolder()), _gidToLidMap(), + _gid_to_lid_map_write_itr(vespalib::datastore::EntryRef(), _gidToLidMap.getAllocator()), + _gid_to_lid_map_write_itr_prepare_serial_num(0u), _lidAlloc(_metaDataStore.size(), _metaDataStore.capacity(), getGenerationHolder()), @@ -420,13 +418,14 @@ DocumentMetaStore::~DocumentMetaStore() } DocumentMetaStore::Result -DocumentMetaStore::inspectExisting(const GlobalId &gid) const +DocumentMetaStore::inspectExisting(const GlobalId &gid, uint64_t prepare_serial_num) { assert(_lidAlloc.isFreeListConstructed()); Result res; KeyComp comp(gid, _metaDataStore, *_gidCompare); - TreeType::Iterator itr = _gidToLidMap.lowerBound(KeyComp::FIND_DOC_ID, - comp); + auto& itr = _gid_to_lid_map_write_itr; + itr.lower_bound(_gidToLidMap.getRoot(), KeyComp::FIND_DOC_ID, comp); + _gid_to_lid_map_write_itr_prepare_serial_num = prepare_serial_num; bool found = itr.valid() && !comp(KeyComp::FIND_DOC_ID, itr.getKey()); if (found) { res.setLid(itr.getKey()); @@ -437,13 +436,14 @@ DocumentMetaStore::inspectExisting(const GlobalId &gid) const } DocumentMetaStore::Result -DocumentMetaStore::inspect(const GlobalId &gid) +DocumentMetaStore::inspect(const GlobalId &gid, uint64_t prepare_serial_num) { assert(_lidAlloc.isFreeListConstructed()); Result res; KeyComp comp(gid, _metaDataStore, *_gidCompare); - TreeType::Iterator itr = _gidToLidMap.lowerBound(KeyComp::FIND_DOC_ID, - comp); + auto& itr = _gid_to_lid_map_write_itr; + itr.lower_bound(_gidToLidMap.getRoot(), KeyComp::FIND_DOC_ID, comp); + _gid_to_lid_map_write_itr_prepare_serial_num = prepare_serial_num; bool found = itr.valid() && !comp(KeyComp::FIND_DOC_ID, itr.getKey()); if (!found) { DocId myLid = peekFreeLid(); @@ -462,20 +462,23 @@ DocumentMetaStore::put(const GlobalId &gid, const BucketId &bucketId, const Timestamp ×tamp, uint32_t docSize, - DocId lid) + DocId lid, + uint64_t prepare_serial_num) { Result res; RawDocumentMetaData metaData(gid, bucketId, timestamp, docSize); KeyComp comp(metaData, _metaDataStore, *_gidCompare); - TreeType::Iterator itr = _gidToLidMap.lowerBound(KeyComp::FIND_DOC_ID, - comp); + auto& itr = _gid_to_lid_map_write_itr; + if (prepare_serial_num == 0u || _gid_to_lid_map_write_itr_prepare_serial_num != prepare_serial_num) { + itr.lower_bound(_gidToLidMap.getRoot(), KeyComp::FIND_DOC_ID, comp); + } bool found = itr.valid() && !comp(KeyComp::FIND_DOC_ID, itr.getKey()); if (!found) { if (validLid(lid)) { throw IllegalStateException( make_string( "document meta data store" - " or transaction log is corrupted," + " or transaction log is corrupt," " cannot put" " document with lid '%u' and gid '%s'," " gid not found, but lid is used" @@ -489,15 +492,14 @@ DocumentMetaStore::put(const GlobalId &gid, assert(freeLid == lid); (void) freeLid; } - if (insert(lid, metaData)) { - res.setLid(lid); - res.markSuccess(); - } + insert(lid, metaData); + res.setLid(lid); + res.markSuccess(); } else if (lid != itr.getKey()) { throw IllegalStateException( make_string( "document meta data store" - " or transaction log is corrupted," + " or transaction log is corrupt," " cannot put" " document with lid '%u' and gid '%s'," " gid found, but using another lid '%u'", @@ -536,40 +538,44 @@ DocumentMetaStore::updateMetaData(DocId lid, return true; } -bool -DocumentMetaStore::remove(DocId lid, BucketDBOwner::Guard &bucketGuard) +void +DocumentMetaStore::remove(DocId lid, uint64_t prepare_serial_num, BucketDBOwner::Guard &bucketGuard) { - if (!validLid(lid)) { - return false; - } const GlobalId & gid = getRawGid(lid); KeyComp comp(gid, _metaDataStore, *_gidCompare); - if (!_gidToLidMap.remove(lid, comp)) { + auto& itr = _gid_to_lid_map_write_itr; + if (prepare_serial_num == 0u || _gid_to_lid_map_write_itr_prepare_serial_num != prepare_serial_num) { + itr.lower_bound(_gidToLidMap.getRoot(), lid, comp); + } + if (!itr.valid() || comp(lid, itr.getKey())) { throw IllegalStateException(make_string( "document meta data store corrupted," " cannot remove" " document with lid '%u' and gid '%s'", lid, gid.toString().c_str())); } + _gidToLidMap.remove(itr); _lidAlloc.unregisterLid(lid); RawDocumentMetaData &oldMetaData = _metaDataStore[lid]; bucketGuard->remove(oldMetaData.getGid(), oldMetaData.getBucketId().stripUnused(), oldMetaData.getTimestamp(), oldMetaData.getDocSize(), _subDbType); - return true; } bool -DocumentMetaStore::remove(DocId lid) +DocumentMetaStore::remove(DocId lid, uint64_t prepare_serial_num) { BucketDBOwner::Guard bucketGuard = _bucketDB->takeGuard(); - bool result = remove(lid, bucketGuard); + if (!validLid(lid)) { + return false; + } + remove(lid, prepare_serial_num, bucketGuard); incGeneration(); - if (result && _op_listener) { + if (_op_listener) { _op_listener->notify_remove(); } - return result; + return true; } void @@ -582,7 +588,7 @@ DocumentMetaStore::removeComplete(DocId lid) } void -DocumentMetaStore::move(DocId fromLid, DocId toLid) +DocumentMetaStore::move(DocId fromLid, DocId toLid, uint64_t prepare_serial_num) { assert(fromLid != 0); assert(toLid != 0); @@ -594,11 +600,14 @@ DocumentMetaStore::move(DocId fromLid, DocId toLid) _metaDataStore[toLid] = _metaDataStore[fromLid]; const GlobalId & gid = getRawGid(fromLid); KeyComp comp(gid, _metaDataStore, *_gidCompare); - TreeType::Iterator it(_gidToLidMap.lowerBound(fromLid, comp)); - assert(it.valid()); - assert(it.getKey() == fromLid); - _gidToLidMap.thaw(it); - it.writeKey(toLid); + auto& itr = _gid_to_lid_map_write_itr; + if (prepare_serial_num == 0u || _gid_to_lid_map_write_itr_prepare_serial_num != prepare_serial_num) { + itr.lower_bound(_gidToLidMap.getRoot(), fromLid, comp); + } + assert(itr.valid()); + assert(itr.getKey() == fromLid); + _gidToLidMap.thaw(itr); + itr.writeKey(toLid); _lidAlloc.moveLidEnd(fromLid, toLid); incGeneration(); } @@ -611,9 +620,8 @@ DocumentMetaStore::removeBatch(const std::vector<DocId> &lidsToRemove, const uin assert(lid > 0 && lid < docIdLimit); (void) docIdLimit; - bool removed = remove(lid, bucketGuard); - assert(removed); - (void) removed; + assert(validLid(lid)); + remove(lid, 0u, bucketGuard); } incGeneration(); if (_op_listener) { diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.h b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.h index 4274c49f5b5..53a6ed5cc68 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.h +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/documentmetastore.h @@ -68,6 +68,8 @@ private: MetaDataStore _metaDataStore; TreeType _gidToLidMap; + Iterator _gid_to_lid_map_write_itr; // Iterator used for all updates of _gidToLidMap + SerialNum _gid_to_lid_map_write_itr_prepare_serial_num; documentmetastore::LidAllocator _lidAlloc; IGidCompare::SP _gidCompare; BucketDBOwner::SP _bucketDB; @@ -79,7 +81,7 @@ private: DocId getFreeLid(); DocId peekFreeLid(); VESPA_DLL_LOCAL void ensureSpace(DocId lid); - bool insert(DocId lid, const RawDocumentMetaData &metaData); + void insert(DocId lid, const RawDocumentMetaData &metaData); const GlobalId & getRawGid(DocId lid) const { return getRawMetaData(lid).getGid(); } @@ -126,7 +128,7 @@ private: VESPA_DLL_LOCAL DocId readNextDoc(documentmetastore::Reader & reader, TreeType::Builder & treeBuilder); - bool remove(DocId lid, BucketDBOwner::Guard &bucketGuard); + void remove(DocId lid, uint64_t cached_iterator_sequence_id, BucketDBOwner::Guard &bucketGuard); public: typedef TreeType::Iterator Iterator; @@ -147,8 +149,8 @@ public: /** * Implements documentmetastore::IStore. */ - Result inspectExisting(const GlobalId &gid) const override; - Result inspect(const GlobalId &gid) override; + Result inspectExisting(const GlobalId &gid, uint64_t prepare_serial_num) override; + Result inspect(const GlobalId &gid, uint64_t prepare_serial_num) override; /** * Puts the given <lid, meta data> pair to this store. * This function should only be called before constructFreeList() @@ -158,9 +160,9 @@ public: * was used to create the <lid, gid> pairs. **/ Result put(const GlobalId &gid, const BucketId &bucketId, - const Timestamp ×tamp, uint32_t docSize, DocId lid) override; + const Timestamp ×tamp, uint32_t docSize, DocId lid, uint64_t prepare_serial_num) override; bool updateMetaData(DocId lid, const BucketId &bucketId, const Timestamp ×tamp) override; - bool remove(DocId lid) override; + bool remove(DocId lid, uint64_t prepare_serial_num) override; BucketId getBucketOf(const vespalib::GenerationHandler::Guard & guard, uint32_t lid) const override; vespalib::GenerationHandler::Guard getGuard() const override; @@ -172,7 +174,7 @@ public: * document store). */ void removeComplete(DocId lid) override; - void move(DocId fromLid, DocId toLid) override; + void move(DocId fromLid, DocId toLid, uint64_t prepare_serial_num) override; bool validButMaybeUnusedLid(DocId lid) const { return _lidAlloc.validButMaybeUnusedLid(lid); } bool validLidFast(DocId lid) const { return _lidAlloc.validLid(lid); } bool validLid(DocId lid) const override { return validLidFast(lid); } diff --git a/searchcore/src/vespa/searchcore/proton/documentmetastore/i_store.h b/searchcore/src/vespa/searchcore/proton/documentmetastore/i_store.h index 9e3988c76f0..56da7850142 100644 --- a/searchcore/src/vespa/searchcore/proton/documentmetastore/i_store.h +++ b/searchcore/src/vespa/searchcore/proton/documentmetastore/i_store.h @@ -6,6 +6,7 @@ #include <vespa/document/base/globalid.h> #include <vespa/document/bucket/bucketid.h> #include <persistence/spi/types.h> +#include <vespa/searchlib/common/serialnum.h> namespace proton::documentmetastore { @@ -55,14 +56,14 @@ struct IStore * Inspect the meta data associated with the given gid. * If the gid is not found the result is not valid. */ - virtual Result inspectExisting(const GlobalId &gid) const = 0; + virtual Result inspectExisting(const GlobalId &gid, uint64_t prepare_serial_num) = 0; /** * Inspect the meta data associated with the given gid. * If the gid is not found the next available lid is returned in the result. * This lid can be used if calling put() right afterwards. */ - virtual Result inspect(const GlobalId &gid) = 0; + virtual Result inspect(const GlobalId &gid, uint64_t prepare_serial_num) = 0; /** * Puts the given <lid, meta data> pair to this store. @@ -73,7 +74,8 @@ struct IStore const BucketId &bucketId, const Timestamp ×tamp, uint32_t docSize, - DocId lid) = 0; + DocId lid, + uint64_t prepare_serial_num) = 0; /* * Update the meta data associated with the given lid. @@ -90,7 +92,7 @@ struct IStore * found or could not be removed. * The caller must call removeComplete() after document removal is done. **/ - virtual bool remove(DocId lid) = 0; + virtual bool remove(DocId lid, uint64_t prepare_serial_num) = 0; /** * Signal that the removal of the document associated with this lid is complete. @@ -104,7 +106,7 @@ struct IStore * is updated atomically from fromLid to toLid. * The caller must call removeComplete() with fromLid after document move is done. */ - virtual void move(DocId fromLid, DocId toLid) = 0; + virtual void move(DocId fromLid, DocId toLid, uint64_t prepare_serial_num) = 0; /** * Check if the lid is valid. diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.cpp b/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.cpp index 1f19c99a2a4..266cce220ea 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.cpp +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.cpp @@ -21,7 +21,8 @@ DocumentOperation::DocumentOperation(Type type) noexcept _prevDbdId(), _prevMarkedAsRemoved(false), _prevTimestamp(), - _serializedDocSize(0) + _serializedDocSize(0), + _prepare_serial_num(0u) { } @@ -34,7 +35,8 @@ DocumentOperation::DocumentOperation(Type type, BucketId bucketId, Timestamp tim _prevDbdId(), _prevMarkedAsRemoved(false), _prevTimestamp(), - _serializedDocSize(0) + _serializedDocSize(0), + _prepare_serial_num(0u) { } diff --git a/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.h b/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.h index 764ba1886a9..ef88b1c73f3 100644 --- a/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.h +++ b/searchcore/src/vespa/searchcore/proton/feedoperation/documentoperation.h @@ -19,6 +19,7 @@ protected: bool _prevMarkedAsRemoved; storage::spi::Timestamp _prevTimestamp; mutable uint32_t _serializedDocSize; // Set by serialize()/deserialize() + uint64_t _prepare_serial_num; DocumentOperation(Type type) noexcept; @@ -83,6 +84,8 @@ public: void deserialize(vespalib::nbostream &is, const document::DocumentTypeRepo &repo) override; uint32_t getSerializedDocSize() const { return _serializedDocSize; } + void set_prepare_serial_num(uint64_t prepare_serial_num_in) { _prepare_serial_num = prepare_serial_num_in; } + uint64_t get_prepare_serial_num() const { return _prepare_serial_num; } // Provided as a hook for tests. void serializeDocumentOperationOnly(vespalib::nbostream &os) const; diff --git a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp index ea5d46f02ad..a5efb0a66e9 100644 --- a/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/combiningfeedview.cpp @@ -76,7 +76,7 @@ CombiningFeedView::findPrevDbdId(const document::GlobalId &gid, const documentmetastore::IStore *metaStore = _metaStores[subDbId]; if (metaStore == nullptr) continue; - documentmetastore::IStore::Result inspectRes(metaStore->inspectExisting(gid)); + documentmetastore::IStore::Result inspectRes(const_cast<documentmetastore::IStore *>(metaStore)->inspectExisting(gid, op.get_prepare_serial_num())); if (inspectRes._found) { op.setPrevDbDocumentId(DbDocumentId(subDbId, inspectRes._lid)); op.setPrevMarkedAsRemoved(subDbId == getRemFeedViewId()); diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp index 8b82478c1a4..174ba090842 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.cpp @@ -140,6 +140,7 @@ FeedHandler::doHandleOperation(FeedToken token, FeedOperation::UP op) void FeedHandler::performPut(FeedToken token, PutOperation &op) { op.assertValid(); + op.set_prepare_serial_num(inc_prepare_serial_num()); _activeFeedView->preparePut(op); if (ignoreOperation(op)) { LOG(debug, "performPut(): ignoreOperation: docId(%s), timestamp(%" PRIu64 "), prevTimestamp(%" PRIu64 ")", @@ -168,6 +169,7 @@ FeedHandler::performPut(FeedToken token, PutOperation &op) { void FeedHandler::performUpdate(FeedToken token, UpdateOperation &op) { + op.set_prepare_serial_num(inc_prepare_serial_num()); _activeFeedView->prepareUpdate(op); if (op.getPrevDbDocumentId().valid() && !op.getPrevMarkedAsRemoved()) { if (considerUpdateOperationForRejection(token, op)) { @@ -205,6 +207,7 @@ FeedHandler::createNonExistingDocument(FeedToken token, const UpdateOperation &o doc->setRepo(*_activeFeedView->getDocumentTypeRepo()); op.getUpdate()->applyTo(*doc); PutOperation putOp(op.getBucketId(), op.getTimestamp(), std::move(doc)); + putOp.set_prepare_serial_num(op.get_prepare_serial_num()); _activeFeedView->preparePut(putOp); appendOperation(putOp, token); if (token) { @@ -218,6 +221,7 @@ FeedHandler::createNonExistingDocument(FeedToken token, const UpdateOperation &o void FeedHandler::performRemove(FeedToken token, RemoveOperation &op) { + op.set_prepare_serial_num(inc_prepare_serial_num()); _activeFeedView->prepareRemove(op); if (ignoreOperation(op)) { LOG(debug, "performRemove(): ignoreOperation: remove(%s), timestamp(%" PRIu64 "), prevTimestamp(%" PRIu64 ")", @@ -402,6 +406,7 @@ FeedHandler::FeedHandler(IThreadingService &writeService, _tlsReplayProgress(), _serialNum(0), _prunedSerialNum(0), + _prepare_serial_num(0u), _numOperationsPendingCommit(0), _numOperationsCompleted(0), _numCommitsCompleted(0), @@ -702,6 +707,7 @@ void FeedHandler::handleMove(MoveOperation &op, std::shared_ptr<search::IDestructorCallback> moveDoneCtx) { assert(_writeService.master().isCurrentThread()); + op.set_prepare_serial_num(inc_prepare_serial_num()); _activeFeedView->prepareMove(op); assert(op.getValidDbdId()); assert(op.getValidPrevDbdId()); diff --git a/searchcore/src/vespa/searchcore/proton/server/feedhandler.h b/searchcore/src/vespa/searchcore/proton/server/feedhandler.h index c295b26a759..ec7ecbdd3ae 100644 --- a/searchcore/src/vespa/searchcore/proton/server/feedhandler.h +++ b/searchcore/src/vespa/searchcore/proton/server/feedhandler.h @@ -76,6 +76,7 @@ private: // the serial num of the last message in the transaction log SerialNum _serialNum; SerialNum _prunedSerialNum; + uint64_t _prepare_serial_num; size_t _numOperationsPendingCommit; size_t _numOperationsCompleted; size_t _numCommitsCompleted; @@ -210,6 +211,7 @@ public: SerialNum incSerialNum() { return ++_serialNum; } SerialNum getSerialNum() const override { return _serialNum; } SerialNum getPrunedSerialNum() const { return _prunedSerialNum; } + uint64_t inc_prepare_serial_num() { return ++_prepare_serial_num; } bool isDoingReplay() const; float getReplayProgress() const { diff --git a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp index 6654f31ac5d..4f143015ea6 100644 --- a/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp +++ b/searchcore/src/vespa/searchcore/proton/server/storeonlyfeedview.cpp @@ -169,7 +169,7 @@ void putMetaData(documentmetastore::IStore &meta_store, const DocumentId & doc_i { documentmetastore::IStore::Result putRes( meta_store.put(doc_id.getGlobalId(), - op.getBucketId(), op.getTimestamp(), op.getSerializedDocSize(), op.getLid())); + op.getBucketId(), op.getTimestamp(), op.getSerializedDocSize(), op.getLid(), op.get_prepare_serial_num())); if (!putRes.ok()) { throw IllegalStateException( make_string("Could not put <lid, gid> pair for %sdocument with id '%s' and gid '%s'", @@ -187,7 +187,7 @@ void removeMetaData(documentmetastore::IStore &meta_store, const GlobalId & gid, const RawDocumentMetaData &meta(meta_store.getRawMetaData(op.getPrevLid())); assert(meta.getGid() == gid); (void) meta; - if (!meta_store.remove(op.getPrevLid())) { + if (!meta_store.remove(op.getPrevLid(), op.get_prepare_serial_num())) { throw IllegalStateException( make_string("Could not remove <lid, gid> pair for %sdocument with id '%s' and gid '%s'", is_removed_doc ? "removed " : "", doc_id.toString().c_str(), @@ -206,7 +206,7 @@ moveMetaData(documentmetastore::IStore &meta_store, const DocumentId & doc_id, c (void) meta; assert(meta.getGid() == doc_id.getGlobalId()); assert(meta.getTimestamp() == op.getTimestamp()); - meta_store.move(op.getPrevLid(), op.getLid()); + meta_store.move(op.getPrevLid(), op.getLid(), op.get_prepare_serial_num()); } std::unique_ptr<PendingLidTrackerBase> @@ -292,7 +292,7 @@ StoreOnlyFeedView::preparePut(PutOperation &putOp) { const DocumentId &docId = putOp.getDocument()->getId(); const document::GlobalId &gid = docId.getGlobalId(); - documentmetastore::IStore::Result inspectResult = _metaStore.inspect(gid); + documentmetastore::IStore::Result inspectResult = _metaStore.inspect(gid, putOp.get_prepare_serial_num()); putOp.setDbDocumentId(DbDocumentId(_params._subDbId, inspectResult._lid)); assert(_params._subDbType != SubDbType::REMOVED); setPrev(putOp, inspectResult, _params._subDbId, false); @@ -386,7 +386,7 @@ StoreOnlyFeedView::prepareUpdate(UpdateOperation &updOp) { const DocumentId &docId = updOp.getUpdate()->getId(); const document::GlobalId &gid = docId.getGlobalId(); - documentmetastore::IStore::Result inspectResult = _metaStore.inspect(gid); + documentmetastore::IStore::Result inspectResult = _metaStore.inspect(gid, updOp.get_prepare_serial_num()); updOp.setDbDocumentId(DbDocumentId(_params._subDbId, inspectResult._lid)); assert(_params._subDbType != SubDbType::REMOVED); setPrev(updOp, inspectResult, _params._subDbId, false); @@ -578,7 +578,7 @@ StoreOnlyFeedView::removeIndexedFields(SerialNum, Lid, bool, OnRemoveDoneType) { void StoreOnlyFeedView::prepareRemove(RemoveOperation &rmOp) { - documentmetastore::IStore::Result inspectRes = _metaStore.inspect(rmOp.getGlobalId()); + documentmetastore::IStore::Result inspectRes = _metaStore.inspect(rmOp.getGlobalId(), rmOp.get_prepare_serial_num()); if ((_params._subDbType == SubDbType::REMOVED) && (rmOp.getType() == FeedOperation::REMOVE)) { rmOp.setDbDocumentId(DbDocumentId(_params._subDbId, inspectRes._lid)); } @@ -785,7 +785,7 @@ StoreOnlyFeedView::prepareMove(MoveOperation &moveOp) { const DocumentId &docId = moveOp.getDocument()->getId(); const document::GlobalId &gid = docId.getGlobalId(); - documentmetastore::IStore::Result inspectResult = _metaStore.inspect(gid); + documentmetastore::IStore::Result inspectResult = _metaStore.inspect(gid, moveOp.get_prepare_serial_num()); assert(!inspectResult._found); moveOp.setDbDocumentId(DbDocumentId(_params._subDbId, inspectResult._lid)); } diff --git a/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h b/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h index 8900e58ee18..66cc5ed0fea 100644 --- a/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h +++ b/searchcore/src/vespa/searchcore/proton/test/document_meta_store_observer.h @@ -57,34 +57,35 @@ struct DocumentMetaStoreObserver : public IDocumentMetaStore /** * Implements documentmetastore::IStore. */ - virtual Result inspectExisting(const GlobalId &gid) const override { - return _store.inspectExisting(gid); + virtual Result inspectExisting(const GlobalId &gid, uint64_t prepare_serial_num) override { + return _store.inspectExisting(gid, prepare_serial_num); } - virtual Result inspect(const GlobalId &gid) override { - return _store.inspect(gid); + virtual Result inspect(const GlobalId &gid, uint64_t prepare_serial_num) override { + return _store.inspect(gid, prepare_serial_num); } virtual Result put(const GlobalId &gid, const BucketId &bucketId, const Timestamp ×tamp, uint32_t docSize, - DocId lid) override { - return _store.put(gid, bucketId, timestamp, docSize, lid); + DocId lid, + uint64_t prepare_serial_num) override { + return _store.put(gid, bucketId, timestamp, docSize, lid, prepare_serial_num); } virtual bool updateMetaData(DocId lid, const BucketId &bucketId, const Timestamp ×tamp) override { return _store.updateMetaData(lid, bucketId, timestamp); } - virtual bool remove(DocId lid) override { - return _store.remove(lid); + virtual bool remove(DocId lid, uint64_t prepare_serial_num) override { + return _store.remove(lid, prepare_serial_num); } virtual void removeComplete(DocId lid) override { ++_removeCompleteCnt; _removeCompleteLid = lid; _store.removeComplete(lid); } - virtual void move(DocId fromLid, DocId toLid) override { - _store.move(fromLid, toLid); + virtual void move(DocId fromLid, DocId toLid, uint64_t prepare_serial_num) override { + _store.move(fromLid, toLid, prepare_serial_num); } virtual bool validLid(DocId lid) const override { return _store.validLid(lid); |