diff options
author | Ian Boros <ian.boros@mongodb.com> | 2022-04-20 16:34:18 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-04-28 02:39:29 +0000 |
commit | 260dc8099245ba5732fc3633012b05df29e61b34 (patch) | |
tree | 2dbfff2669d7be176234f61e370283180eca1509 /src/mongo/db/index | |
parent | db67c16a6445e66ff85a5f4d800b6b9393e82cdd (diff) | |
download | mongo-260dc8099245ba5732fc3633012b05df29e61b34.tar.gz |
SERVER-65487 Add skeleton column index access method
Diffstat (limited to 'src/mongo/db/index')
-rw-r--r-- | src/mongo/db/index/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/index/columns_access_method.cpp | 220 | ||||
-rw-r--r-- | src/mongo/db/index/columns_access_method.h | 114 | ||||
-rw-r--r-- | src/mongo/db/index/index_access_method.h | 9 | ||||
-rw-r--r-- | src/mongo/db/index/index_access_method_factory_impl.cpp | 33 | ||||
-rw-r--r-- | src/mongo/db/index/index_access_method_factory_impl.h | 9 |
6 files changed, 374 insertions, 12 deletions
diff --git a/src/mongo/db/index/SConscript b/src/mongo/db/index/SConscript index 48ab6f723cc..c6a75052cba 100644 --- a/src/mongo/db/index/SConscript +++ b/src/mongo/db/index/SConscript @@ -126,6 +126,7 @@ env.Library( target="index_access_methods", source=[ "2d_access_method.cpp", + "columns_access_method.cpp", "btree_access_method.cpp", "fts_access_method.cpp", "hash_access_method.cpp", diff --git a/src/mongo/db/index/columns_access_method.cpp b/src/mongo/db/index/columns_access_method.cpp new file mode 100644 index 00000000000..140578dae67 --- /dev/null +++ b/src/mongo/db/index/columns_access_method.cpp @@ -0,0 +1,220 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#define MONGO_LOGV2_DEFAULT_COMPONENT ::mongo::logv2::LogComponent::kIndex + +#include "mongo/db/index/columns_access_method.h" + +#include <vector> + +#include "mongo/base/status.h" +#include "mongo/base/status_with.h" +#include "mongo/db/curop.h" +#include "mongo/db/index/column_key_generator.h" +#include "mongo/logv2/log.h" +#include "mongo/util/progress_meter.h" + +namespace mongo { +ColumnStoreAccessMethod::ColumnStoreAccessMethod(IndexCatalogEntry* ice, + std::unique_ptr<ColumnStore> store) + : _store(std::move(store)), _indexCatalogEntry(ice), _descriptor(ice->descriptor()) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod()"); +} + +class ColumnStoreAccessMethod::BulkBuilder final : public IndexAccessMethod::BulkBuilder { +public: + BulkBuilder(ColumnStoreAccessMethod* index, size_t maxMemoryUsageBytes, StringData dbName); + + BulkBuilder(ColumnStoreAccessMethod* index, + size_t maxMemoryUsageBytes, + const IndexStateInfo& stateInfo, + StringData dbName); + + + // + // Generic APIs + // + + Status insert(OperationContext* opCtx, + const CollectionPtr& collection, + SharedBufferFragmentBuilder& pooledBuilder, + const BSONObj& obj, + const RecordId& loc, + const InsertDeleteOptions& options, + const std::function<void()>& saveCursorBeforeWrite, + const std::function<void()>& restoreCursorAfterWrite) final; + + const MultikeyPaths& getMultikeyPaths() const final; + + bool isMultikey() const final; + + int64_t getKeysInserted() const; + + mongo::IndexStateInfo persistDataForShutdown() final; + + Status commit(OperationContext* opCtx, + const CollectionPtr& collection, + bool dupsAllowed, + int32_t yieldIterations, + const KeyHandlerFn& onDuplicateKeyInserted, + const RecordIdHandlerFn& onDuplicateRecord) final; + +private: + ColumnStoreAccessMethod* const _iam; + int64_t _keysInserted = 0; +}; + +ColumnStoreAccessMethod::BulkBuilder::BulkBuilder(ColumnStoreAccessMethod* index, + size_t maxMemoryUsageBytes, + StringData dbName) + : _iam(index) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::BulkBuilder()"); +} + +ColumnStoreAccessMethod::BulkBuilder::BulkBuilder(ColumnStoreAccessMethod* index, + size_t maxMemoryUsageBytes, + const IndexStateInfo& stateInfo, + StringData dbName) + : _iam(index) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::BulkBuilder()"); +} + +Status ColumnStoreAccessMethod::BulkBuilder::insert( + OperationContext* opCtx, + const CollectionPtr& collection, + SharedBufferFragmentBuilder& pooledBuilder, + const BSONObj& obj, + const RecordId& loc, + const InsertDeleteOptions& options, + const std::function<void()>& saveCursorBeforeWrite, + const std::function<void()>& restoreCursorAfterWrite) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::BulkBuilder::insert()"); +} +const MultikeyPaths& ColumnStoreAccessMethod::BulkBuilder::getMultikeyPaths() const { + const static MultikeyPaths empty; + return empty; +} + +bool ColumnStoreAccessMethod::BulkBuilder::isMultikey() const { + return false; +} + +int64_t ColumnStoreAccessMethod::BulkBuilder::getKeysInserted() const { + return _keysInserted; +} + +mongo::IndexStateInfo ColumnStoreAccessMethod::BulkBuilder::persistDataForShutdown() { + uasserted(ErrorCodes::NotImplemented, + "ColumnStoreAccessMethod::BulkBuilder::persistDataForShutdown()"); +} + +Status ColumnStoreAccessMethod::BulkBuilder::commit(OperationContext* opCtx, + const CollectionPtr& collection, + bool dupsAllowed, + int32_t yieldIterations, + const KeyHandlerFn& onDuplicateKeyInserted, + const RecordIdHandlerFn& onDuplicateRecord) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::BulkBuilder::commit()"); +} + + +Status ColumnStoreAccessMethod::insert(OperationContext* opCtx, + SharedBufferFragmentBuilder& pooledBufferBuilder, + const CollectionPtr& coll, + const std::vector<BsonRecord>& bsonRecords, + const InsertDeleteOptions& options, + int64_t* numInserted) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::insert()"); +} + +void ColumnStoreAccessMethod::remove(OperationContext* opCtx, + SharedBufferFragmentBuilder& pooledBufferBuilder, + const CollectionPtr& coll, + const BSONObj& obj, + const RecordId& loc, + bool logIfError, + const InsertDeleteOptions& options, + int64_t* numDeleted, + CheckRecordId checkRecordId) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::remove()"); +} + +Status ColumnStoreAccessMethod::update(OperationContext* opCtx, + SharedBufferFragmentBuilder& pooledBufferBuilder, + const BSONObj& oldDoc, + const BSONObj& newDoc, + const RecordId& loc, + const CollectionPtr& coll, + const InsertDeleteOptions& options, + int64_t* numInserted, + int64_t* numDeleted) { + uasserted(ErrorCodes::NotImplemented, "ColumnStoreAccessMethod::update()"); +} + +Status ColumnStoreAccessMethod::initializeAsEmpty(OperationContext* opCtx) { + return Status::OK(); +} + +void ColumnStoreAccessMethod::validate(OperationContext* opCtx, + int64_t* numKeys, + IndexValidateResults* fullResults) const { + _store->fullValidate(opCtx, numKeys, fullResults); +} + +bool ColumnStoreAccessMethod::appendCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const { + return _store->appendCustomStats(opCtx, result, scale); +} + +long long ColumnStoreAccessMethod::getSpaceUsedBytes(OperationContext* opCtx) const { + return _store->getSpaceUsedBytes(opCtx); +} + +long long ColumnStoreAccessMethod::getFreeStorageBytes(OperationContext* opCtx) const { + return _store->getFreeStorageBytes(opCtx); +} + +Status ColumnStoreAccessMethod::compact(OperationContext* opCtx) { + return _store->compact(opCtx); +} + + +std::unique_ptr<IndexAccessMethod::BulkBuilder> ColumnStoreAccessMethod::initiateBulk( + size_t maxMemoryUsageBytes, + const boost::optional<IndexStateInfo>& stateInfo, + StringData dbName) { + invariant(!stateInfo); + return std::make_unique<BulkBuilder>(this, maxMemoryUsageBytes, dbName); +} + +Ident* ColumnStoreAccessMethod::getIdentPtr() const { + return _store.get(); +} +} // namespace mongo diff --git a/src/mongo/db/index/columns_access_method.h b/src/mongo/db/index/columns_access_method.h new file mode 100644 index 00000000000..b3b85bc4ea2 --- /dev/null +++ b/src/mongo/db/index/columns_access_method.h @@ -0,0 +1,114 @@ +/** + * Copyright (C) 2022-present MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * <http://www.mongodb.com/licensing/server-side-public-license>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the Server Side Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include "mongo/db/index/index_access_method.h" +#include "mongo/db/storage/column_store.h" + +namespace mongo { + +class ColumnStoreAccessMethod : public IndexAccessMethod { + ColumnStoreAccessMethod(const ColumnStoreAccessMethod&) = delete; + ColumnStoreAccessMethod& operator=(const ColumnStoreAccessMethod&) = delete; + +public: + // + // Column-specific APIs + // + + + ColumnStoreAccessMethod(IndexCatalogEntry* ice, std::unique_ptr<ColumnStore>); + + + // + // Generic IndexAccessMethod APIs + // + + Status insert(OperationContext* opCtx, + SharedBufferFragmentBuilder& pooledBufferBuilder, + const CollectionPtr& coll, + const std::vector<BsonRecord>& bsonRecords, + const InsertDeleteOptions& options, + int64_t* numInserted) final; + + void remove(OperationContext* opCtx, + SharedBufferFragmentBuilder& pooledBufferBuilder, + const CollectionPtr& coll, + const BSONObj& obj, + const RecordId& loc, + bool logIfError, + const InsertDeleteOptions& options, + int64_t* numDeleted, + CheckRecordId checkRecordId) final; + Status update(OperationContext* opCtx, + SharedBufferFragmentBuilder& pooledBufferBuilder, + const BSONObj& oldDoc, + const BSONObj& newDoc, + const RecordId& loc, + const CollectionPtr& coll, + const InsertDeleteOptions& options, + int64_t* numInserted, + int64_t* numDeleted) final; + + Status initializeAsEmpty(OperationContext* opCtx) final; + + void validate(OperationContext* opCtx, + int64_t* numKeys, + IndexValidateResults* fullResults) const final; + + bool appendCustomStats(OperationContext* opCtx, + BSONObjBuilder* result, + double scale) const final; + + long long getSpaceUsedBytes(OperationContext* opCtx) const final; + + long long getFreeStorageBytes(OperationContext* opCtx) const final; + + Status compact(OperationContext* opCtx) final; + + std::unique_ptr<IndexAccessMethod::BulkBuilder> initiateBulk( + size_t maxMemoryUsageBytes, + const boost::optional<IndexStateInfo>& stateInfo, + StringData dbName) final; + + Ident* getIdentPtr() const final; + + const ColumnStore* storage() const { + return _store.get(); + } + + class BulkBuilder; + +private: + const std::unique_ptr<ColumnStore> _store; + IndexCatalogEntry* const _indexCatalogEntry; // owned by IndexCatalog + const IndexDescriptor* const _descriptor; +}; +} // namespace mongo diff --git a/src/mongo/db/index/index_access_method.h b/src/mongo/db/index/index_access_method.h index c9e85ff5d43..7bd9fbbf328 100644 --- a/src/mongo/db/index/index_access_method.h +++ b/src/mongo/db/index/index_access_method.h @@ -51,6 +51,7 @@ class MatchExpression; struct UpdateTicket; struct InsertDeleteOptions; class SortedDataIndexAccessMethod; +struct CollectionOptions; /** * An IndexAccessMethod is the interface through which all the mutation, lookup, and @@ -253,8 +254,12 @@ public: static void set(ServiceContext* service, std::unique_ptr<IndexAccessMethodFactory> collectionFactory); - virtual std::unique_ptr<IndexAccessMethod> make( - IndexCatalogEntry* entry, std::unique_ptr<SortedDataInterface> sortedDataInterface) = 0; + + virtual std::unique_ptr<IndexAccessMethod> make(OperationContext* opCtx, + const NamespaceString& nss, + const CollectionOptions& collectionOptions, + IndexCatalogEntry* entry, + StringData ident) = 0; }; /** diff --git a/src/mongo/db/index/index_access_method_factory_impl.cpp b/src/mongo/db/index/index_access_method_factory_impl.cpp index 2f1610deee6..31c313379fc 100644 --- a/src/mongo/db/index/index_access_method_factory_impl.cpp +++ b/src/mongo/db/index/index_access_method_factory_impl.cpp @@ -35,33 +35,50 @@ #include "mongo/db/index/2d_access_method.h" #include "mongo/db/index/btree_access_method.h" +#include "mongo/db/index/columns_access_method.h" #include "mongo/db/index/fts_access_method.h" #include "mongo/db/index/hash_access_method.h" #include "mongo/db/index/s2_access_method.h" #include "mongo/db/index/s2_bucket_access_method.h" #include "mongo/db/index/wildcard_access_method.h" +#include "mongo/db/storage/kv/kv_engine.h" #include "mongo/logv2/log.h" namespace mongo { std::unique_ptr<IndexAccessMethod> IndexAccessMethodFactoryImpl::make( - IndexCatalogEntry* entry, std::unique_ptr<SortedDataInterface> sortedDataInterface) { + OperationContext* opCtx, + const NamespaceString& nss, + const CollectionOptions& collectionOptions, + IndexCatalogEntry* entry, + StringData ident) { + + auto engine = opCtx->getServiceContext()->getStorageEngine()->getEngine(); auto desc = entry->descriptor(); + auto makeSDI = [&] { + return engine->getSortedDataInterface(opCtx, nss, collectionOptions, ident, desc); + }; + auto makeCS = [&] { + return engine->getColumnStore(opCtx, nss, collectionOptions, ident, desc); + }; const std::string& type = desc->getAccessMethodName(); + if ("" == type) - return std::make_unique<BtreeAccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<BtreeAccessMethod>(entry, makeSDI()); else if (IndexNames::HASHED == type) - return std::make_unique<HashAccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<HashAccessMethod>(entry, makeSDI()); else if (IndexNames::GEO_2DSPHERE == type) - return std::make_unique<S2AccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<S2AccessMethod>(entry, makeSDI()); else if (IndexNames::GEO_2DSPHERE_BUCKET == type) - return std::make_unique<S2BucketAccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<S2BucketAccessMethod>(entry, makeSDI()); else if (IndexNames::TEXT == type) - return std::make_unique<FTSAccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<FTSAccessMethod>(entry, makeSDI()); else if (IndexNames::GEO_2D == type) - return std::make_unique<TwoDAccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<TwoDAccessMethod>(entry, makeSDI()); else if (IndexNames::WILDCARD == type) - return std::make_unique<WildcardAccessMethod>(entry, std::move(sortedDataInterface)); + return std::make_unique<WildcardAccessMethod>(entry, makeSDI()); + else if (IndexNames::COLUMN == type) + return std::make_unique<ColumnStoreAccessMethod>(entry, makeCS()); LOGV2(20688, "Can't find index for keyPattern {keyPattern}", "Can't find index for keyPattern", diff --git a/src/mongo/db/index/index_access_method_factory_impl.h b/src/mongo/db/index/index_access_method_factory_impl.h index dae1a2204ac..639ee1c320d 100644 --- a/src/mongo/db/index/index_access_method_factory_impl.h +++ b/src/mongo/db/index/index_access_method_factory_impl.h @@ -33,13 +33,18 @@ namespace mongo { +struct CollectionOptions; + class IndexAccessMethodFactoryImpl : public IndexAccessMethodFactory { public: IndexAccessMethodFactoryImpl() = default; ~IndexAccessMethodFactoryImpl() = default; - std::unique_ptr<IndexAccessMethod> make( - IndexCatalogEntry* entry, std::unique_ptr<SortedDataInterface> SortedDataInterface) final; + std::unique_ptr<IndexAccessMethod> make(OperationContext* opCtx, + const NamespaceString& nss, + const CollectionOptions& collectionOptions, + IndexCatalogEntry* entry, + StringData ident) final; }; } // namespace mongo |