summaryrefslogtreecommitdiff
path: root/src/mongo/db/index
diff options
context:
space:
mode:
authorIan Boros <ian.boros@mongodb.com>2022-04-20 16:34:18 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-28 02:39:29 +0000
commit260dc8099245ba5732fc3633012b05df29e61b34 (patch)
tree2dbfff2669d7be176234f61e370283180eca1509 /src/mongo/db/index
parentdb67c16a6445e66ff85a5f4d800b6b9393e82cdd (diff)
downloadmongo-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/SConscript1
-rw-r--r--src/mongo/db/index/columns_access_method.cpp220
-rw-r--r--src/mongo/db/index/columns_access_method.h114
-rw-r--r--src/mongo/db/index/index_access_method.h9
-rw-r--r--src/mongo/db/index/index_access_method_factory_impl.cpp33
-rw-r--r--src/mongo/db/index/index_access_method_factory_impl.h9
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