From 356172042cbc96375be8d663a945879b9f10dd41 Mon Sep 17 00:00:00 2001 From: Henning Baldersheim Date: Wed, 7 Oct 2020 20:29:40 +0000 Subject: - GC unused code. - vespalib::Lock -> std::mutex --- .../src/vespa/config/retriever/configretriever.cpp | 4 +- .../src/vespa/config/retriever/configretriever.h | 3 +- document/src/vespa/document/bucket/CMakeLists.txt | 1 - .../vespa/document/bucket/bucketdistribution.cpp | 115 --- .../src/vespa/document/bucket/bucketdistribution.h | 136 ---- .../vespa/document/datatype/positiondatatype.cpp | 5 +- .../src/vespa/document/datatype/positiondatatype.h | 2 - .../src/vespa/document/datatype/urldatatype.cpp | 10 +- document/src/vespa/document/datatype/urldatatype.h | 2 - document/src/vespa/document/select/valuenodes.cpp | 1 - .../document_subdbs/document_subdbs_test.cpp | 1 - searchcorespi/CMakeLists.txt | 4 - searchcorespi/src/tests/plugin/.gitignore | 5 - searchcorespi/src/tests/plugin/CMakeLists.txt | 32 - searchcorespi/src/tests/plugin/empty.cpp | 1 - .../src/tests/plugin/factoryregistry_test.cpp | 59 -- searchcorespi/src/tests/plugin/plugin.cpp | 78 -- searchcorespi/src/tests/plugin/plugin_test.cpp | 37 - .../src/vespa/searchcorespi/CMakeLists.txt | 1 - .../src/vespa/searchcorespi/plugin/.gitignore | 2 - .../src/vespa/searchcorespi/plugin/CMakeLists.txt | 7 - .../vespa/searchcorespi/plugin/factoryloader.cpp | 32 - .../src/vespa/searchcorespi/plugin/factoryloader.h | 26 - .../vespa/searchcorespi/plugin/factoryregistry.cpp | 54 -- .../vespa/searchcorespi/plugin/factoryregistry.h | 50 -- .../searchcorespi/plugin/iindexmanagerfactory.h | 76 -- searchlib/src/vespa/searchlib/docstore/compacter.h | 2 +- .../src/vespa/searchlib/docstore/randreaders.cpp | 2 +- .../src/vespa/searchlib/docstore/randreaders.h | 2 +- .../vespa/searchlib/memoryindex/memory_index.cpp | 5 +- .../src/vespa/searchlib/memoryindex/memory_index.h | 14 +- slobrok/src/vespa/slobrok/sblist.cpp | 4 +- slobrok/src/vespa/slobrok/sblist.h | 3 +- .../src/vespa/vespalib/stllike/cache.h | 1 - .../src/vespa/vespalib/stllike/cache.hpp | 8 +- .../src/vespa/vespalib/util/varholder.h | 8 +- .../filestorage/filestorhandlerimpl.cpp | 14 +- .../persistence/filestorage/filestorhandlerimpl.h | 2 +- vdslib/CMakeLists.txt | 1 - vdslib/src/tests/CMakeLists.txt | 1 - vdslib/src/tests/bucketdistribution/.gitignore | 3 - vdslib/src/tests/bucketdistribution/CMakeLists.txt | 8 - .../bucketdistribution/bucketdistributiontest.cpp | 92 --- vdslib/src/vespa/vdslib/CMakeLists.txt | 1 - vdslib/src/vespa/vdslib/bucketdistribution.cpp | 115 --- vdslib/src/vespa/vdslib/bucketdistribution.h | 119 --- vespalib/CMakeLists.txt | 2 - vespalib/src/tests/delegatelist/.cvsignore | 3 - vespalib/src/tests/delegatelist/.gitignore | 4 - vespalib/src/tests/delegatelist/CMakeLists.txt | 8 - vespalib/src/tests/delegatelist/delegatelist.cpp | 824 --------------------- vespalib/src/tests/rwlock/.gitignore | 4 - vespalib/src/tests/rwlock/CMakeLists.txt | 8 - vespalib/src/tests/rwlock/rwlock_test.cpp | 78 -- vespalib/src/tests/sync/sync_test.cpp | 131 +--- .../src/vespa/vespalib/data/memorydatastore.cpp | 3 +- vespalib/src/vespa/vespalib/data/memorydatastore.h | 6 +- .../src/vespa/vespalib/testkit/test_master.cpp | 34 +- vespalib/src/vespa/vespalib/testkit/test_master.h | 19 +- .../src/vespa/vespalib/testkit/test_master.hpp | 2 +- vespalib/src/vespa/vespalib/util/CMakeLists.txt | 1 - vespalib/src/vespa/vespalib/util/alloc.cpp | 8 +- vespalib/src/vespa/vespalib/util/delegatelist.hpp | 309 -------- vespalib/src/vespa/vespalib/util/ptrholder.h | 14 +- vespalib/src/vespa/vespalib/util/rwlock.cpp | 59 -- vespalib/src/vespa/vespalib/util/rwlock.h | 240 ------ .../vespa/vespalib/util/simple_thread_bundle.cpp | 4 +- .../src/vespa/vespalib/util/simple_thread_bundle.h | 5 +- vespalib/src/vespa/vespalib/util/sync.cpp | 47 -- vespalib/src/vespa/vespalib/util/sync.h | 104 --- vsm/src/vespa/vsm/vsm/vsm-adapter.cpp | 4 +- vsm/src/vespa/vsm/vsm/vsm-adapter.h | 2 +- 72 files changed, 132 insertions(+), 2940 deletions(-) delete mode 100644 document/src/vespa/document/bucket/bucketdistribution.cpp delete mode 100644 document/src/vespa/document/bucket/bucketdistribution.h delete mode 100644 searchcorespi/src/tests/plugin/.gitignore delete mode 100644 searchcorespi/src/tests/plugin/CMakeLists.txt delete mode 100644 searchcorespi/src/tests/plugin/empty.cpp delete mode 100644 searchcorespi/src/tests/plugin/factoryregistry_test.cpp delete mode 100644 searchcorespi/src/tests/plugin/plugin.cpp delete mode 100644 searchcorespi/src/tests/plugin/plugin_test.cpp delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/.gitignore delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h delete mode 100644 searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h delete mode 100644 vdslib/src/tests/bucketdistribution/.gitignore delete mode 100644 vdslib/src/tests/bucketdistribution/CMakeLists.txt delete mode 100644 vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp delete mode 100644 vdslib/src/vespa/vdslib/bucketdistribution.cpp delete mode 100644 vdslib/src/vespa/vdslib/bucketdistribution.h delete mode 100644 vespalib/src/tests/delegatelist/.cvsignore delete mode 100644 vespalib/src/tests/delegatelist/.gitignore delete mode 100644 vespalib/src/tests/delegatelist/CMakeLists.txt delete mode 100644 vespalib/src/tests/delegatelist/delegatelist.cpp delete mode 100644 vespalib/src/tests/rwlock/.gitignore delete mode 100644 vespalib/src/tests/rwlock/CMakeLists.txt delete mode 100644 vespalib/src/tests/rwlock/rwlock_test.cpp delete mode 100644 vespalib/src/vespa/vespalib/util/delegatelist.hpp delete mode 100644 vespalib/src/vespa/vespalib/util/rwlock.cpp delete mode 100644 vespalib/src/vespa/vespalib/util/rwlock.h diff --git a/config/src/vespa/config/retriever/configretriever.cpp b/config/src/vespa/config/retriever/configretriever.cpp index f144cf9aa99..f34ee6f70af 100644 --- a/config/src/vespa/config/retriever/configretriever.cpp +++ b/config/src/vespa/config/retriever/configretriever.cpp @@ -52,7 +52,7 @@ ConfigRetriever::getConfigs(const ConfigKeySet & keySet, milliseconds timeoutInM if (keySet != _lastKeySet) { _lastKeySet = keySet; { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_lock); if (_closed) return ConfigSnapshot(); _configSubscriber = std::make_unique(_context); @@ -83,7 +83,7 @@ ConfigRetriever::getConfigs(const ConfigKeySet & keySet, milliseconds timeoutInM void ConfigRetriever::close() { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_lock); _closed = true; _bootstrapSubscriber.close(); if (_configSubscriber) diff --git a/config/src/vespa/config/retriever/configretriever.h b/config/src/vespa/config/retriever/configretriever.h index 14e3171fc62..9ef67edd7b8 100644 --- a/config/src/vespa/config/retriever/configretriever.h +++ b/config/src/vespa/config/retriever/configretriever.h @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #pragma once -#include "configkeyset.h" #include "configsnapshot.h" #include "genericconfigsubscriber.h" #include "fixedconfigsubscriber.h" @@ -94,7 +93,7 @@ public: private: FixedConfigSubscriber _bootstrapSubscriber; std::unique_ptr _configSubscriber; - vespalib::Lock _lock; + std::mutex _lock; std::vector _subscriptionList; ConfigKeySet _lastKeySet; IConfigContext::SP _context; diff --git a/document/src/vespa/document/bucket/CMakeLists.txt b/document/src/vespa/document/bucket/CMakeLists.txt index 7704fe94bd0..fbbfe8b8466 100644 --- a/document/src/vespa/document/bucket/CMakeLists.txt +++ b/document/src/vespa/document/bucket/CMakeLists.txt @@ -2,7 +2,6 @@ vespa_add_library(document_bucket OBJECT SOURCES bucket.cpp - bucketdistribution.cpp bucketid.cpp bucketidfactory.cpp bucketidlist.cpp diff --git a/document/src/vespa/document/bucket/bucketdistribution.cpp b/document/src/vespa/document/bucket/bucketdistribution.cpp deleted file mode 100644 index 34ce9a9eccf..00000000000 --- a/document/src/vespa/document/bucket/bucketdistribution.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "bucketdistribution.h" -#include - -LOG_SETUP(".bucketdistribution"); - -namespace document { - -BucketDistribution::BucketDistribution(uint32_t numColumns, uint32_t numBucketBits) : - _numColumns(0), - _numBucketBits(numBucketBits), - _bucketToColumn(), - _lock() -{ - _bucketToColumn.resize(getNumBuckets()); - reset(); - setNumColumns(numColumns); -} - -void -BucketDistribution::getBucketCount(uint32_t numColumns, uint32_t numBucketBits, std::vector &ret) -{ - ret.resize(numColumns); - uint32_t cnt = getNumBuckets(numBucketBits) / numColumns; - uint32_t rst = getNumBuckets(numBucketBits) % numColumns; - for (uint32_t i = 0; i < numColumns; ++i) { - ret[i] = cnt + (i < rst ? 1 : 0); - } -} - -void -BucketDistribution::getBucketMigrateCount(uint32_t numColumns, uint32_t numBucketBits, std::vector &ret) -{ - getBucketCount(numColumns++, numBucketBits, ret); - uint32_t cnt = getNumBuckets(numBucketBits) / numColumns; - uint32_t rst = getNumBuckets(numBucketBits) % numColumns; - for (uint32_t i = 0; i < numColumns - 1; ++i) { - ret[i] -= cnt + (i < rst ? 1 : 0); - } -} - -void -BucketDistribution::reset() -{ - for (std::vector::iterator it = _bucketToColumn.begin(); - it != _bucketToColumn.end(); ++it) { - *it = 0; - } - _numColumns = 1; -} - -void -BucketDistribution::addColumn() -{ - uint32_t newColumns = _numColumns + 1; - std::vector migrate; - getBucketMigrateCount(_numColumns, _numBucketBits, migrate); - uint32_t numBuckets = getNumBuckets(_numBucketBits); - for (uint32_t i = 0; i < numBuckets; ++i) { - uint32_t old = _bucketToColumn[i]; - if (migrate[old] > 0) { - _bucketToColumn[i] = _numColumns; // move this bucket to the new column - migrate[old]--; - } - } - _numColumns = newColumns; -} - -void -BucketDistribution::setNumColumns(uint32_t numColumns) -{ - vespalib::LockGuard guard(_lock); - if (numColumns < _numColumns) { - reset(); - } - if (numColumns == _numColumns) { - return; - } - for (int i = numColumns - _numColumns; --i >= 0; ) { - addColumn(); - } -} - -void -BucketDistribution::setNumBucketBits(uint32_t numBucketBits) -{ - uint32_t numColumns; - { - vespalib::LockGuard guard(_lock); - if (numBucketBits == _numBucketBits) { - return; - } - _numBucketBits = numBucketBits; - _bucketToColumn.resize(getNumBuckets(numBucketBits)); - numColumns = _numColumns; - reset(); - } - setNumColumns(numColumns); -} - -uint32_t -BucketDistribution::getColumn(const document::BucketId &bucketId) const -{ - uint32_t ret = (uint32_t)(bucketId.getId() & (getNumBuckets(_numBucketBits) - 1)); - if (ret >= _bucketToColumn.size()) { - LOG(error, - "The bucket distribution map is not in sync with the number of bucket bits. " - "This should never happen! Distribution is broken!!"); - return 0; - } - return _bucketToColumn[ret]; -} - -} diff --git a/document/src/vespa/document/bucket/bucketdistribution.h b/document/src/vespa/document/bucket/bucketdistribution.h deleted file mode 100644 index c451ed9b9a7..00000000000 --- a/document/src/vespa/document/bucket/bucketdistribution.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -/** - * \class document::BucketDistribution - * \ingroup bucket - * - * Stable algorithmic hash distribution; this class assigns hash buckets to - * targets. The number of hash buckets should be large compared to the number - * of targets. The mapping from hash value to hash bucket is performed outside - * this class. - * - * This is used to determine which search column a bucket should go to. - */ -#pragma once - -#include "bucketid.h" -#include -#include - -namespace document { - -class BucketDistribution { -public: - /** - * Constructs a new bucket distribution object with a given number of - * columns and buckets. - * - * @param numColumns The number of columns to distribute to. - * @param numBucketBits The number of bits to use for bucket id. - */ - BucketDistribution(uint32_t numColumns, uint32_t numBucketBits); - - /** - * Returns the number of buckets that the given number of bucket bits will - * allow. - * - * @param numBucketBits The number of bits to use for bucket id. - * @return The number of buckets allowed. - */ - static uint32_t getNumBuckets(uint32_t numBucketBits) { return 1 << numBucketBits; } - - /** - * This method returns a list that contains the distributions of the given - * number of buckets over the given number of columns. - * - * @param numColumns The number of columns to distribute to. - * @param numBucketBits The number of bits to use for bucket id. - * @param ret List to fill with the bucket distribution. - */ - static void getBucketCount(uint32_t numColumns, uint32_t numBucketBits, - std::vector &ret); - - /** - * This method returns a list similar to getBucketCount(int,int), except - * that the returned list contains the number of buckets that will have to - * be migrated from each column if an additional column was added. - * - * @param numColumns The original number of columns. - * @param numBucketBits The number of bits to use for bucket id. - * @param ret List to fill with the number of buckets to migrate, - * one value per column. - */ - static void getBucketMigrateCount(uint32_t numColumns, - uint32_t numBucketBits, std::vector &ret); - - /** - * Sets the number of columns to distribute to to 1, and resets the content - * of the internal bucket-to-column map so that it all buckets point to - * that single column. - */ - void reset(); - - /** - * Sets the number of columns to use for this document distribution object. - * This will reset and setup this object from scratch. The original number - * of buckets is maintained. - * - * @param numColumns The new number of columns to distribute to. - */ - void setNumColumns(uint32_t numColumns); - - /** - * Returns the number of columns to distribute to. - * - * @return The number of columns. - */ - uint32_t getNumColumns() const { return _numColumns; } - - /** - * Sets the number of buckets to use for this document distribution object. - * This will reset and setup this object from scratch. The original number - * of columns is maintained. - * - * @param numBucketBits The new number of bits to use for bucket id. - */ - void setNumBucketBits(uint32_t numBucketBits); - - /** - * Returns the number of bits used for bucket identifiers. - * - * @return The number of bits. - */ - uint32_t getNumBucketBits() const { return _numBucketBits; } - - /** - * Returns the number of buckets available using the configured number of - * bucket bits. - * - * @return The number of buckets. - */ - uint32_t getNumBuckets() const { return getNumBuckets(_numBucketBits); } - - /** - * This method maps the given bucket id to its corresponding column. - * - * @param bucketId The bucket whose column to lookup. - * @return The column to distribute the bucket to. - */ - uint32_t getColumn(const document::BucketId &bucketId) const; - -private: - /** - * Adds a single column to this bucket distribution object. This will - * modify the internal bucket-to-column map so that it takes into account - * the new column. - */ - void addColumn(); - -private: - uint32_t _numColumns; // The number of columns to distribute to. - uint32_t _numBucketBits; // The number of bits to use for bucket identification. - std::vector _bucketToColumn; // A map from bucket id to column index. - vespalib::Lock _lock; -}; - -} // document - diff --git a/document/src/vespa/document/datatype/positiondatatype.cpp b/document/src/vespa/document/datatype/positiondatatype.cpp index a8e9c81c895..8b323d20fb5 100644 --- a/document/src/vespa/document/datatype/positiondatatype.cpp +++ b/document/src/vespa/document/datatype/positiondatatype.cpp @@ -1,17 +1,18 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "positiondatatype.h" +#include namespace document { namespace { const vespalib::string ZCURVE("_zcurve"); +std::mutex _G_lock; } StructDataType::UP PositionDataType::_instance; -vespalib::Lock PositionDataType::_lock; const vespalib::string PositionDataType::STRUCT_NAME("position"); const vespalib::string PositionDataType::FIELD_X("x"); @@ -30,7 +31,7 @@ const StructDataType & PositionDataType::getInstance() { if ( ! _instance) { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_G_lock); if ( ! _instance) { _instance = createInstance(); } diff --git a/document/src/vespa/document/datatype/positiondatatype.h b/document/src/vespa/document/datatype/positiondatatype.h index fa8e44ad847..c7cf1926159 100644 --- a/document/src/vespa/document/datatype/positiondatatype.h +++ b/document/src/vespa/document/datatype/positiondatatype.h @@ -2,14 +2,12 @@ #pragma once #include -#include namespace document { class PositionDataType { private: static StructDataType::UP _instance; - static vespalib::Lock _lock; PositionDataType(); static StructDataType::UP createInstance(); diff --git a/document/src/vespa/document/datatype/urldatatype.cpp b/document/src/vespa/document/datatype/urldatatype.cpp index 00ea31408af..bc8c2bee2c7 100644 --- a/document/src/vespa/document/datatype/urldatatype.cpp +++ b/document/src/vespa/document/datatype/urldatatype.cpp @@ -1,11 +1,17 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "urldatatype.h" +#include namespace document { +namespace { + +std::mutex _G_lock; + +} + StructDataType::UP UrlDataType::_instance; -vespalib::Lock UrlDataType::_lock; const vespalib::string UrlDataType::STRUCT_NAME("url"); const vespalib::string UrlDataType::FIELD_ALL("all"); @@ -34,7 +40,7 @@ const StructDataType & UrlDataType::getInstance() { if ( ! _instance ) { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_G_lock); if ( ! _instance ) { _instance = createInstance(); } diff --git a/document/src/vespa/document/datatype/urldatatype.h b/document/src/vespa/document/datatype/urldatatype.h index 902abd940e3..df28b9e56b9 100644 --- a/document/src/vespa/document/datatype/urldatatype.h +++ b/document/src/vespa/document/datatype/urldatatype.h @@ -2,14 +2,12 @@ #pragma once #include -#include namespace document { class UrlDataType { private: static StructDataType::UP _instance; - static vespalib::Lock _lock; UrlDataType() { /* hide */ } static StructDataType::UP createInstance(); diff --git a/document/src/vespa/document/select/valuenodes.cpp b/document/src/vespa/document/select/valuenodes.cpp index 73fc1c6486b..36cb92dfe33 100644 --- a/document/src/vespa/document/select/valuenodes.cpp +++ b/document/src/vespa/document/select/valuenodes.cpp @@ -2,7 +2,6 @@ #include "valuenodes.h" #include "visitor.h" #include "parser.h" -#include #include #include #include diff --git a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp index aebe5a61198..43f16e87986 100644 --- a/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp +++ b/searchcore/src/tests/proton/documentdb/document_subdbs/document_subdbs_test.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/searchcorespi/CMakeLists.txt b/searchcorespi/CMakeLists.txt index 32469886bf8..2faa2be3b82 100644 --- a/searchcorespi/CMakeLists.txt +++ b/searchcorespi/CMakeLists.txt @@ -18,8 +18,4 @@ vespa_define_module( src/vespa/searchcorespi src/vespa/searchcorespi/flush src/vespa/searchcorespi/index - src/vespa/searchcorespi/plugin - - TESTS - src/tests/plugin ) diff --git a/searchcorespi/src/tests/plugin/.gitignore b/searchcorespi/src/tests/plugin/.gitignore deleted file mode 100644 index e49000038ad..00000000000 --- a/searchcorespi/src/tests/plugin/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -Makefile -.depend -*_test -searchcorespi_factoryregistry_test_app -searchcorespi_plugin_test_app diff --git a/searchcorespi/src/tests/plugin/CMakeLists.txt b/searchcorespi/src/tests/plugin/CMakeLists.txt deleted file mode 100644 index da785b09b6a..00000000000 --- a/searchcorespi/src/tests/plugin/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_library(searchcorespi_tplugin - SOURCES - plugin.cpp - DEPENDS - searchcorespi -) -vespa_add_library(searchcorespi_illegal-plugin - SOURCES - empty.cpp - DEPENDS - searchcorespi -) -vespa_add_executable(searchcorespi_plugin_test_app TEST - SOURCES - plugin_test.cpp - DEPENDS - searchcorespi -) -vespa_add_test( - NAME searchcorespi_plugin_test_app - COMMAND searchcorespi_plugin_test_app - ENVIRONMENT "LD_LIBRARY_PATH=." - DEPENDS searchcorespi_tplugin searchcorespi_illegal-plugin -) -vespa_add_executable(searchcorespi_factoryregistry_test_app TEST - SOURCES - factoryregistry_test.cpp - DEPENDS - searchcorespi -) -vespa_add_test(NAME searchcorespi_factoryregistry_test_app COMMAND searchcorespi_factoryregistry_test_app) diff --git a/searchcorespi/src/tests/plugin/empty.cpp b/searchcorespi/src/tests/plugin/empty.cpp deleted file mode 100644 index c7c47fc98c5..00000000000 --- a/searchcorespi/src/tests/plugin/empty.cpp +++ /dev/null @@ -1 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. diff --git a/searchcorespi/src/tests/plugin/factoryregistry_test.cpp b/searchcorespi/src/tests/plugin/factoryregistry_test.cpp deleted file mode 100644 index 10a1c95f191..00000000000 --- a/searchcorespi/src/tests/plugin/factoryregistry_test.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include -#include -#include -#include -#include - -using vespalib::string; -using namespace searchcorespi; - -namespace { - -struct MyFactory : IIndexManagerFactory { - - virtual IIndexManager::UP createIndexManager(const IndexManagerConfig &, - const index::IndexMaintainerConfig &, - const index::IndexMaintainerContext &) override { - return IIndexManager::UP(); - } - virtual config::ConfigKeySet getConfigKeys( - const string &, - const search::index::Schema &, - const config::ConfigInstance &) override { - return config::ConfigKeySet(); - } -}; - -const string name = "factory"; - -TEST("require that factories can be added and removed") { - FactoryRegistry registry; - EXPECT_FALSE(registry.isRegistered(name)); - registry.add(name, IIndexManagerFactory::SP(new MyFactory)); - EXPECT_TRUE(registry.get(name).get()); - EXPECT_TRUE(registry.isRegistered(name)); - registry.remove(name); - EXPECT_EXCEPTION(registry.get(name), vespalib::IllegalArgumentException, - "No factory is registered with the name"); -} - -TEST("require that two factories with the same name cannot be added") { - FactoryRegistry registry; - registry.add(name, IIndexManagerFactory::SP(new MyFactory)); - EXPECT_EXCEPTION( - registry.add(name, IIndexManagerFactory::SP(new MyFactory)), - vespalib::IllegalArgumentException, - "A factory is already registered with the same name"); -} - -TEST("require that a non-existent factory cannot be removed") { - FactoryRegistry registry; - EXPECT_EXCEPTION(registry.remove(name), vespalib::IllegalArgumentException, - "No factory is registered with the name"); -} - -} // namespace - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchcorespi/src/tests/plugin/plugin.cpp b/searchcorespi/src/tests/plugin/plugin.cpp deleted file mode 100644 index d32b02f45fd..00000000000 --- a/searchcorespi/src/tests/plugin/plugin.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include - -using namespace search; -using namespace search::index; -using namespace vespalib; -using namespace config; - -namespace searchcorespi { -class IndexManager : public searchcorespi::IIndexManager -{ -public: - - typedef search::SerialNum SerialNum; - typedef search::index::Schema Schema; - typedef document::Document Document; - using OnWriteDoneType = - const std::shared_ptr &; - virtual void putDocument(uint32_t, const Document &, SerialNum) override { } - virtual void removeDocument(uint32_t, SerialNum) override { } - virtual void commit(SerialNum, OnWriteDoneType) override { } - virtual void heartBeat(SerialNum ) override {} - void compactLidSpace(uint32_t, SerialNum) override {} - virtual SerialNum getCurrentSerialNum() const override { return 0; } - virtual SerialNum getFlushedSerialNum() const override { return 0; } - virtual IndexSearchable::SP getSearchable() const override { - IndexSearchable::SP s; - return s; - } - virtual SearchableStats getSearchableStats() const override { - SearchableStats s; - return s; - } - virtual searchcorespi::IFlushTarget::List getFlushTargets() override { - searchcorespi::IFlushTarget::List l; - return l; - } - virtual void setSchema(const Schema &, SerialNum) override { } - virtual void setMaxFlushed(uint32_t) override { } -}; - -class IndexManagerFactory : public searchcorespi::IIndexManagerFactory -{ -public: - virtual IIndexManager::UP createIndexManager(const IndexManagerConfig &managerCfg, - const index::IndexMaintainerConfig &maintainerConfig, - const index::IndexMaintainerContext &maintainerContext) override; - - virtual ConfigKeySet getConfigKeys(const string &configId, - const Schema &schema, - const ConfigInstance &rootConfig) override; -}; - -IIndexManager::UP -IndexManagerFactory::createIndexManager(const IndexManagerConfig &, - const index::IndexMaintainerConfig &, - const index::IndexMaintainerContext &) -{ - return IIndexManager::UP(new IndexManager()); -} - -ConfigKeySet -IndexManagerFactory::getConfigKeys(const string &, - const Schema &, - const ConfigInstance &) -{ - ConfigKeySet keys; - return keys; -} - -} - -searchcorespi::IIndexManagerFactory * -createIndexManagerFactory() -{ - return new searchcorespi::IndexManagerFactory(); -} - diff --git a/searchcorespi/src/tests/plugin/plugin_test.cpp b/searchcorespi/src/tests/plugin/plugin_test.cpp deleted file mode 100644 index 733c2834c24..00000000000 --- a/searchcorespi/src/tests/plugin/plugin_test.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include -#include -#include - -using namespace searchcorespi; - -namespace { -TEST("require that plugins can be loaded.") { - FactoryLoader fl; - IIndexManagerFactory::UP f = fl.create("searchcorespi_tplugin"); - ASSERT_TRUE(f.get()); -} - -TEST("require that non-existent plugin causes failure") { - FactoryLoader fl; -#ifdef __APPLE__ - EXPECT_EXCEPTION(fl.create("no-such-plugin"), - vespalib::IllegalArgumentException, - "image not found"); -#else - EXPECT_EXCEPTION(fl.create("no-such-plugin"), - vespalib::IllegalArgumentException, - "cannot open shared object file"); -#endif -} - -TEST("require that missing factory function causes failure") { - FactoryLoader fl; - EXPECT_EXCEPTION(fl.create("searchcorespi_illegal-plugin"), - vespalib::IllegalArgumentException, - "Failed locating symbol 'createIndexManagerFactory'"); -} -} // namespace - -TEST_MAIN() { TEST_RUN_ALL(); } diff --git a/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt b/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt index 3cbe1265136..bee83a7f936 100644 --- a/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt +++ b/searchcorespi/src/vespa/searchcorespi/CMakeLists.txt @@ -3,7 +3,6 @@ vespa_add_library(searchcorespi SOURCES $ $ - $ INSTALL lib64 DEPENDS ) diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/.gitignore b/searchcorespi/src/vespa/searchcorespi/plugin/.gitignore deleted file mode 100644 index 7e7c0fe7fae..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/.depend -/Makefile diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt b/searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt deleted file mode 100644 index b564a593e4e..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_library(searchcorespi_plugin OBJECT - SOURCES - factoryregistry.cpp - factoryloader.cpp - DEPENDS -) diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp b/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp deleted file mode 100644 index ba2b0b962f6..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "factoryloader.h" -#include - -using vespalib::stringref; -using vespalib::make_string; -using vespalib::IllegalArgumentException; - -namespace searchcorespi { - -FactoryLoader::FactoryLoader() : - _libraries() -{ -} - -FactoryLoader::~FactoryLoader() = default; - -IIndexManagerFactory::UP -FactoryLoader::create(stringref factory) -{ - typedef IIndexManagerFactory* (*FuncT)(); - _libraries.loadLibrary(factory); - const FastOS_DynamicLibrary & lib = *_libraries.get(factory); - FuncT registrationMethod = reinterpret_cast(lib.GetSymbol("createIndexManagerFactory")); - if (registrationMethod == nullptr) { - throw IllegalArgumentException(make_string("Failed locating symbol 'createIndexManagerFactory' in library '%s' for factory '%s'.", - lib.GetLibName(), vespalib::string(factory).c_str())); - } - return IIndexManagerFactory::UP(registrationMethod()); -} - -} diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h b/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h deleted file mode 100644 index 3eda6557fa0..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryloader.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include -#include - -namespace searchcorespi { - -class FactoryLoader -{ -public: - FactoryLoader(); - ~FactoryLoader(); - /** - * Will load the library containing the factory. It will then locate the 'createIndexManagerFactory' - * symbol and run it to create the factory. - * @param the name of the library. Like 'vesparise'. - * @return the factory that is created. - */ - IIndexManagerFactory::UP create(vespalib::stringref factory); -private: - vespalib::LibraryPool _libraries; -}; - -} // namespace searchcorespi - diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp b/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp deleted file mode 100644 index bd1b914cf39..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include -#include - -using vespalib::LockGuard; -using vespalib::IllegalArgumentException; -using vespalib::stringref; -using vespalib::string; - -namespace searchcorespi { - -FactoryRegistry::FactoryRegistry() = default; - -FactoryRegistry::~FactoryRegistry() = default; - -void FactoryRegistry::add(stringref uniqueName, const IIndexManagerFactory::SP & factory) -{ - LockGuard guard(_lock); - if (_registry.find(uniqueName) == _registry.end()) { - _registry[uniqueName] = factory; - } else { - throw IllegalArgumentException("A factory is already registered with the same name as '" + uniqueName + "'.", VESPA_STRLOC); - } -} - -void FactoryRegistry::remove(stringref uniqueName) -{ - LockGuard guard(_lock); - if (_registry.find(uniqueName) == _registry.end()) { - throw IllegalArgumentException("No factory is registered with the name of '" + uniqueName + "'.", VESPA_STRLOC); - } - _registry.erase(uniqueName); -} - -const IIndexManagerFactory::SP & -FactoryRegistry::get(stringref uniqueName) const -{ - LockGuard guard(_lock); - Registry::const_iterator found = _registry.find(uniqueName); - if (found == _registry.end()) { - throw IllegalArgumentException("No factory is registered with the name of '" + uniqueName + "'.", VESPA_STRLOC); - } - return found->second; -} - -bool -FactoryRegistry::isRegistered(vespalib::stringref uniqueName) const -{ - LockGuard guard(_lock); - Registry::const_iterator found = _registry.find(uniqueName); - return found != _registry.end(); -} - -} diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h b/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h deleted file mode 100644 index feb27d62950..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/factoryregistry.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include - -namespace searchcorespi { - -/** - */ -class FactoryRegistry -{ -public: - FactoryRegistry(); - ~FactoryRegistry(); - /** - * This will register the plugged in factory under its official - * name. The plugin should call this method when it is loaded. E.g. - * by using either '__attribute__((constructor))' or using a - * global static object that will use its constructor to register - * the factory. - * @param uniqueName This is a name that is unique over all IndexManager factories. - * @param factory The factory instance for producing IndexManagers. - * @throws vespalib::IllegalArgument if factory is already registered. - */ - void add(vespalib::stringref uniqueName, const IIndexManagerFactory::SP & factory); - /** - * Will unregister a factory. Should be called when a sharedlibrary is being unloaded. - * @param uniqueName Unique name of factory to remove from registry. - * @throws vespalib::IllegalArgument if factory is already registered. - */ - void remove(vespalib::stringref uniqueName); - /** - * This method will fetch a factory given its unique name. - * @param name The name of the factory to return. - * @return The factory. - */ - const IIndexManagerFactory::SP & get(vespalib::stringref uniqueName) const; - /** - * Returns true if a factory with the given name has been registered. - */ - bool isRegistered(vespalib::stringref uniqueName) const; - -private: - typedef std::map Registry; - Registry _registry; - vespalib::Lock _lock; -}; - -} // namespace searchcorespi - diff --git a/searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h b/searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h deleted file mode 100644 index c2eddc15cde..00000000000 --- a/searchcorespi/src/vespa/searchcorespi/plugin/iindexmanagerfactory.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -namespace searchcorespi { - -/** - * Interface for an index manager factory. Every provider of an index manager is supposed to provide a - * factory for producing them. It is given the basedir, the schema and a collection of configs. - * The factory implementation must pick the config it needs and return an IIndexManager instance. - * The factory is registered by using the registerFactory() method. - */ -class IIndexManagerFactory -{ -public: - typedef std::shared_ptr SP; - typedef std::unique_ptr UP; - - virtual ~IIndexManagerFactory() {} - - /** - * This method will be called by a document db when it needs to create an index manager that - * uses an index maintainer (with source selector) in its implementation. - * The factory implementation must use RTTI to figure out what configs are what. - * It should receive all configs it needs, but wise to do sanity checking. - * - * @param managerConfig The config that will be used to construct an index manager. - * Note that if the factory used a different config id when populating the - * ConfigKeySet compared to the one in this config instance, it must - * also override the config id when fetching from the config snapshot. - * The root config received in the @ref getConfigKeys() call will also be - * part of the config snapshot in this config instance. - * @param maintainerConfig The config needed to construct an index maintainer. - * @param maintainerContext The context object used by an index maintainer during its lifetime. - * @return The index manager created or NULL if not, fx if configs are not as expected. - */ - virtual IIndexManager::UP createIndexManager(const IndexManagerConfig &managerConfig, - const index::IndexMaintainerConfig &maintainerConfig, - const index::IndexMaintainerContext &maintainerContext) = 0; - - /** - * The factory must return the set of config keys that it will require the config from. - * This will facilitate that the searchcore can fetch all configs needed in a pluggable way. - * - * @param configId The config id to use when generating the config keys. - * @param schema This is the initial index schema to be used. - * @param rootConfig This is an config instance that is the root config for the factory. - * Based on this config it must be able to tell if it needs any other config, - * and in that case provide the config keys. - * @return The set containing keys for all configs required. - */ - virtual config::ConfigKeySet getConfigKeys(const vespalib::string &configId, - const search::index::Schema &schema, - const config::ConfigInstance &rootConfig) = 0; -}; - -} // namespace searchcorespi - -extern "C" { -/** - * This is a method that each shared library must have in order provide a factory. - * This will be called by the one loading the library. - * @return The created factory that the caller will take ownership of. - */ -searchcorespi::IIndexManagerFactory * createIndexManagerFactory(); - -} - - diff --git a/searchlib/src/vespa/searchlib/docstore/compacter.h b/searchlib/src/vespa/searchlib/docstore/compacter.h index cf059b6cb04..52691d2c415 100644 --- a/searchlib/src/vespa/searchlib/docstore/compacter.h +++ b/searchlib/src/vespa/searchlib/docstore/compacter.h @@ -51,7 +51,7 @@ private: uint64_t _writeCount; vespalib::duration _maxBucketGuardDuration; vespalib::steady_time _lastSample; - vespalib::Lock _lock; + std::mutex _lock; vespalib::MemoryDataStore _backingMemory; std::vector _tmpStore; GenerationHandler::Guard _lidGuard; diff --git a/searchlib/src/vespa/searchlib/docstore/randreaders.cpp b/searchlib/src/vespa/searchlib/docstore/randreaders.cpp index 2eb419cf8eb..cb670f513f7 100644 --- a/searchlib/src/vespa/searchlib/docstore/randreaders.cpp +++ b/searchlib/src/vespa/searchlib/docstore/randreaders.cpp @@ -107,7 +107,7 @@ MMapRandReadDynamic::MMapRandReadDynamic(const vespalib::string &fileName, int m void MMapRandReadDynamic::remap(size_t sz) { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_lock); if ((sz > 0) && _holder.hasValue() && contains(*_holder.get(), sz)) { return; } diff --git a/searchlib/src/vespa/searchlib/docstore/randreaders.h b/searchlib/src/vespa/searchlib/docstore/randreaders.h index 4503c3600d4..00dc371bddf 100644 --- a/searchlib/src/vespa/searchlib/docstore/randreaders.h +++ b/searchlib/src/vespa/searchlib/docstore/randreaders.h @@ -47,7 +47,7 @@ private: vespalib::PtrHolder _holder; int _mmapFlags; int _fadviseOptions; - vespalib::Lock _lock; + std::mutex _lock; }; class NormalRandRead : public FileRandRead diff --git a/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp b/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp index 34c5d65ab23..789b7fcf452 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp +++ b/searchlib/src/vespa/searchlib/memoryindex/memory_index.cpp @@ -18,7 +18,6 @@ LOG_SETUP(".searchlib.memoryindex.memory_index"); using document::ArrayFieldValue; using document::WeightedSetFieldValue; -using vespalib::LockGuard; namespace search { @@ -215,7 +214,7 @@ MemoryIndex::getNumWords() const { void MemoryIndex::pruneRemovedFields(const Schema &schema) { - LockGuard lock(_lock); + std::lock_guard lock(_lock); if (_prunedSchema.get() == nullptr) { auto newSchema = Schema::intersect(_schema, schema); if (_schema == *newSchema) { @@ -241,7 +240,7 @@ MemoryIndex::pruneRemovedFields(const Schema &schema) Schema::SP MemoryIndex::getPrunedSchema() const { - LockGuard lock(_lock); + std::lock_guard lock(_lock); return _prunedSchema; } diff --git a/searchlib/src/vespa/searchlib/memoryindex/memory_index.h b/searchlib/src/vespa/searchlib/memoryindex/memory_index.h index a9f153f7dd8..56eb4ad7a66 100644 --- a/searchlib/src/vespa/searchlib/memoryindex/memory_index.h +++ b/searchlib/src/vespa/searchlib/memoryindex/memory_index.h @@ -48,14 +48,14 @@ private: std::unique_ptr _inverter0; std::unique_ptr _inverter1; DocumentInverter *_inverter; - bool _frozen; - uint32_t _maxDocId; - uint32_t _numDocs; - vespalib::Lock _lock; - std::vector _hiddenFields; - index::Schema::SP _prunedSchema; + bool _frozen; + uint32_t _maxDocId; + uint32_t _numDocs; + mutable std::mutex _lock; + std::vector _hiddenFields; + index::Schema::SP _prunedSchema; vespalib::hash_set _indexedDocs; // documents in memory index - const uint64_t _staticMemoryFootprint; + const uint64_t _staticMemoryFootprint; MemoryIndex(const MemoryIndex &) = delete; MemoryIndex(MemoryIndex &&) = delete; diff --git a/slobrok/src/vespa/slobrok/sblist.cpp b/slobrok/src/vespa/slobrok/sblist.cpp index 9fc58aa2974..e7528fb6db2 100644 --- a/slobrok/src/vespa/slobrok/sblist.cpp +++ b/slobrok/src/vespa/slobrok/sblist.cpp @@ -5,7 +5,7 @@ #include LOG_SETUP(".slobrok.list"); -using vespalib::LockGuard; +using LockGuard = std::lock_guard; namespace slobrok::api { @@ -83,7 +83,7 @@ SlobrokList::setup(const std::vector &specList) _slobrokSpecs.push_back(specList[i]); } - vespalib::RandomGen randomizer(time(NULL)); + vespalib::RandomGen randomizer(time(nullptr)); // randomize order for (size_t i = 0; i + 1 < cfgSz; ++i) { size_t lim = cfgSz - i; diff --git a/slobrok/src/vespa/slobrok/sblist.h b/slobrok/src/vespa/slobrok/sblist.h index e5f31c23e5b..08328b99d1a 100644 --- a/slobrok/src/vespa/slobrok/sblist.h +++ b/slobrok/src/vespa/slobrok/sblist.h @@ -2,7 +2,6 @@ #pragma once #include "cfg.h" -#include namespace slobrok::api { @@ -42,7 +41,7 @@ public: /** check if the list contains a given spec */ bool contains(const std::string &spec); private: - vespalib::Lock _lock; + std::mutex _lock; std::vector _slobrokSpecs; size_t _nextSpec; size_t _currSpec; diff --git a/staging_vespalib/src/vespa/vespalib/stllike/cache.h b/staging_vespalib/src/vespa/vespalib/stllike/cache.h index 99b601f7c3c..2c7722724cf 100644 --- a/staging_vespalib/src/vespa/vespalib/stllike/cache.h +++ b/staging_vespalib/src/vespa/vespalib/stllike/cache.h @@ -123,7 +123,6 @@ protected: vespalib::LockGuard getGuard(); void invalidate(const vespalib::LockGuard & guard, const K & key); bool hasKey(const vespalib::LockGuard & guard, const K & key) const; - bool hasLock() const; private: /** * Called when an object is inserted, to see if the LRU should be removed. diff --git a/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp b/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp index 906621d623c..ebad3ef6a09 100644 --- a/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp +++ b/staging_vespalib/src/vespa/vespalib/stllike/cache.hpp @@ -42,13 +42,7 @@ cache

::hasKey(const K & key) const { } template< typename P > -bool -cache

::hasLock() const { - return TryLock(_hashLock).hasLock(); -} - -template< typename P > -cache

::~cache() { } +cache

::~cache() = default; template< typename P > cache

::cache(BackingStore & b, size_t maxBytes) : diff --git a/staging_vespalib/src/vespa/vespalib/util/varholder.h b/staging_vespalib/src/vespa/vespalib/util/varholder.h index fdcc15d1fb4..980d773adc4 100644 --- a/staging_vespalib/src/vespa/vespalib/util/varholder.h +++ b/staging_vespalib/src/vespa/vespalib/util/varholder.h @@ -2,7 +2,7 @@ #pragma once -#include +#include namespace vespalib { @@ -10,7 +10,7 @@ template class VarHolder { T _v; - Lock _lock; + std::mutex _lock; public: VarHolder() : _v(), _lock() {} explicit VarHolder(const T &v) : _v(v), _lock() {} @@ -21,7 +21,7 @@ public: void set(const T &v) { T old; { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_lock); old = _v; _v = v; } @@ -30,7 +30,7 @@ public: void clear() { set(T()); } T get() const { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_lock); return _v; } }; diff --git a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp index 6878c0d0e82..6efb282ecbf 100644 --- a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp +++ b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.cpp @@ -75,7 +75,7 @@ FileStorHandlerImpl::~FileStorHandlerImpl() = default; void FileStorHandlerImpl::addMergeStatus(const document::Bucket& bucket, MergeStatus::SP status) { - vespalib::LockGuard mlock(_mergeStatesLock); + std::lock_guard mlock(_mergeStatesLock); if (_mergeStates.find(bucket) != _mergeStates.end()) { LOG(warning, "A merge status already existed for %s. Overwriting it.", bucket.toString().c_str()); } @@ -85,7 +85,7 @@ FileStorHandlerImpl::addMergeStatus(const document::Bucket& bucket, MergeStatus: MergeStatus& FileStorHandlerImpl::editMergeStatus(const document::Bucket& bucket) { - vespalib::LockGuard mlock(_mergeStatesLock); + std::lock_guard mlock(_mergeStatesLock); MergeStatus::SP status = _mergeStates[bucket]; if (status.get() == 0) { throw vespalib::IllegalStateException("No merge state exist for " + bucket.toString(), VESPA_STRLOC); @@ -96,21 +96,21 @@ FileStorHandlerImpl::editMergeStatus(const document::Bucket& bucket) bool FileStorHandlerImpl::isMerging(const document::Bucket& bucket) const { - vespalib::LockGuard mlock(_mergeStatesLock); + std::lock_guard mlock(_mergeStatesLock); return (_mergeStates.find(bucket) != _mergeStates.end()); } uint32_t FileStorHandlerImpl::getNumActiveMerges() const { - vespalib::LockGuard mlock(_mergeStatesLock); + std::lock_guard mlock(_mergeStatesLock); return _mergeStates.size(); } void FileStorHandlerImpl::clearMergeStatus(const document::Bucket& bucket, const api::ReturnCode* code) { - vespalib::LockGuard mlock(_mergeStatesLock); + std::lock_guard mlock(_mergeStatesLock); auto it = _mergeStates.find(bucket); if (it == _mergeStates.end()) { if (code != 0) { @@ -301,7 +301,7 @@ void FileStorHandlerImpl::updateMetrics(const MetricLockGuard &) { for (Disk & disk : _diskInfo) { - vespalib::MonitorGuard lockGuard(_mergeStatesLock); + std::lock_guard lockGuard(_mergeStatesLock); disk.metrics->pendingMerges.addValue(_mergeStates.size()); disk.metrics->queueSize.addValue(disk.getQueueSize()); @@ -1310,7 +1310,7 @@ FileStorHandlerImpl::getStatus(std::ostream& out, const framework::HttpUrlPath& out << "\n"; } - vespalib::LockGuard mergeGuard(_mergeStatesLock); + std::lock_guard mergeGuard(_mergeStatesLock); out << "Active merge operations" << _mergeStates.size() << "\n"; if (verbose) { out << "

Active merges

\n"; diff --git a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h index 34cb7ba9266..02dcfea0654 100644 --- a/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h +++ b/storage/src/vespa/storage/persistence/filestorage/filestorhandlerimpl.h @@ -288,7 +288,7 @@ private: std::vector _diskInfo; MessageSender& _messageSender; const document::BucketIdFactory& _bucketIdFactory; - vespalib::Lock _mergeStatesLock; + mutable std::mutex _mergeStatesLock; std::map _mergeStates; uint32_t _getNextMessageTimeout; const uint32_t _max_active_merges_per_stripe; // Read concurrently by stripes. diff --git a/vdslib/CMakeLists.txt b/vdslib/CMakeLists.txt index b997bf5f983..3c1ee756e56 100644 --- a/vdslib/CMakeLists.txt +++ b/vdslib/CMakeLists.txt @@ -21,7 +21,6 @@ vespa_define_module( TESTS src/tests - src/tests/bucketdistribution src/tests/container src/tests/distribution src/tests/state diff --git a/vdslib/src/tests/CMakeLists.txt b/vdslib/src/tests/CMakeLists.txt index bc230a7157b..6cf1ba5e33f 100644 --- a/vdslib/src/tests/CMakeLists.txt +++ b/vdslib/src/tests/CMakeLists.txt @@ -6,7 +6,6 @@ vespa_add_executable(vdslib_gtest_runner_app TEST SOURCES gtest_runner.cpp DEPENDS - vdslib_bucketdistributiontest vdslib_containertest vdslib_testdistribution vdslib_teststate diff --git a/vdslib/src/tests/bucketdistribution/.gitignore b/vdslib/src/tests/bucketdistribution/.gitignore deleted file mode 100644 index 583460ae288..00000000000 --- a/vdslib/src/tests/bucketdistribution/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.So -.depend -Makefile diff --git a/vdslib/src/tests/bucketdistribution/CMakeLists.txt b/vdslib/src/tests/bucketdistribution/CMakeLists.txt deleted file mode 100644 index 79ca63b72f2..00000000000 --- a/vdslib/src/tests/bucketdistribution/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_library(vdslib_bucketdistributiontest - SOURCES - bucketdistributiontest.cpp - DEPENDS - vdslib - GTest::GTest -) diff --git a/vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp b/vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp deleted file mode 100644 index 7f2b012680c..00000000000 --- a/vdslib/src/tests/bucketdistribution/bucketdistributiontest.cpp +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include -#include - -using namespace vdslib; - -void -assertDistribution(uint32_t numColumns, uint32_t numBucketBits, const uint32_t expected[]) -{ - BucketDistribution bd(numColumns, numBucketBits); - EXPECT_EQ(numColumns, bd.getNumColumns()); - EXPECT_EQ((uint32_t)(1 << numBucketBits), bd.getNumBuckets()); - for (uint32_t i = 0; i < bd.getNumBuckets(); ++i) { - EXPECT_EQ(expected[i], bd.getColumn(document::BucketId(16, i))); - } -} - -TEST(BucketDistributionTest, testDistribution) -{ - const uint32_t expected4[] = { - 10, 11, 9, 6, 4, 8, 14, 1, 13, 2, 12, 3, 5, 7, 15, 0 }; - assertDistribution(16, 4, expected4); - - const uint32_t expected5[] = { - 11, 12, 11, 13, 8, 13, 8, 9, 4, 5, 6, 12, 10, 15, 1, 1, 7, 9, 14, 2, 2, 14, 3, 3, 4, 5, 6, 7, 10, 15, 0, 0 }; - assertDistribution(16, 5, expected5); - - const uint32_t expected6[] = { - 13, 13, 13, 13, 9, 11, 8, 9, 11, 14, 9, 11, 14, 14, 8, 10, 11, 14, 4, 5, 5, 6, 6, 7, 8, 10, 12, 15, 1, 1, 1, 1, - 6, 7, 8, 10, 12, 15, 2, 2, 2, 2, 12, 15, 3, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7, 7, 9, 10, 12, 15, 0, 0, 0, 0 }; - assertDistribution(16, 6, expected6); - - const uint32_t expected7[] = { - 14, 14, 14, 13, 11, 14, 14, 10, 13, 14, 10, 12, 8, 8, 9, 10, 9, 10, 11, 12, 13, 15, 11, 12, 13, 13, 15, 8, 8, 9, 10, 11, - 11, 12, 13, 15, 4, 4, 5, 5, 5, 5, 15, 6, 6, 7, 7, 7, 8, 9, 9, 10, 11, 12, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, - 6, 6, 6, 7, 7, 8, 8, 9, 10, 11, 12, 13, 15, 2, 2, 2, 2, 2, 2, 2, 2, 12, 13, 15, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 9, 9, 10, 11, 12, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0 }; - assertDistribution(16, 7, expected7); - - const uint32_t expected8[] = { - 15, 14, 15, 15, 12, 14, 15, 12, 12, 11, 12, 13, 14, 13, 13, 13, 14, 15, 15, 9, 14, 9, 15, 10, 11, 11, 12, 8, 8, 8, 8, 9, - 9, 10, 10, 10, 11, 11, 12, 13, 13, 14, 10, 11, 11, 12, 13, 13, 14, 13, 13, 14, 15, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, - 10, 10, 11, 11, 12, 13, 13, 14, 15, 4, 4, 4, 4, 15, 5, 5, 5, 5, 5, 5, 5, 15, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, - 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 14, 15, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 13, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, - 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - assertDistribution(16, 8, expected8); - - const uint32_t expected9[] = { - 15, 15, 15, 15, 14, 14, 15, 13, 13, 13, 13, 13, 14, 14, 15, 12, 14, 15, 15, 11, 11, 12, 13, 13, 13, 14, 14, 15, 15, 10, 12, 12, - 12, 13, 13, 13, 14, 14, 15, 15, 9, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 15, 15, 8, 8, 8, 8, 9, 9, 9, - 9, 9, 9, 10, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 14, 14, 10, 10, 10, 11, 11, 11, 12, 12, 12, 12, - 13, 13, 14, 14, 14, 15, 15, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, - 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 4, 4, 4, 4, 4, 4, 4, 15, 15, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 14, 14, 14, 15, 15, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - assertDistribution(16, 9, expected9); -} - -TEST(BucketDistributionTest, testNumBucketBits) -{ - BucketDistribution bd(1, 4); - for (uint32_t i = 0; i <= 0xf; ++i) { - EXPECT_EQ(0u, bd.getColumn(document::BucketId(32, (rand() << 4) & i))); - } - - bd.reset(); - bd.setNumColumns(1); - bd.setNumBucketBits(8); - for (uint32_t i = 0; i <= 0xff; ++i) { - EXPECT_EQ(0u, bd.getColumn(document::BucketId(32, (rand() << 8) & i))); - } - - bd.reset(); - bd.setNumColumns(1); - bd.setNumBucketBits(16); - for (uint32_t i = 0; i <= 0xffff; ++i) { - EXPECT_EQ(0u, bd.getColumn(document::BucketId(32, (rand() << 16) & i))); - } -} diff --git a/vdslib/src/vespa/vdslib/CMakeLists.txt b/vdslib/src/vespa/vdslib/CMakeLists.txt index ace44439a23..cf5053a5ceb 100644 --- a/vdslib/src/vespa/vdslib/CMakeLists.txt +++ b/vdslib/src/vespa/vdslib/CMakeLists.txt @@ -1,7 +1,6 @@ # Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. vespa_add_library(vdslib SOURCES - bucketdistribution.cpp $ $ $ diff --git a/vdslib/src/vespa/vdslib/bucketdistribution.cpp b/vdslib/src/vespa/vdslib/bucketdistribution.cpp deleted file mode 100644 index 15947d82fed..00000000000 --- a/vdslib/src/vespa/vdslib/bucketdistribution.cpp +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#include "bucketdistribution.h" - -#include -LOG_SETUP(".bucketdistribution"); - -namespace vdslib { - -BucketDistribution::BucketDistribution(uint32_t numColumns, uint32_t numBucketBits) : - _numColumns(0), - _numBucketBits(numBucketBits), - _bucketToColumn(), - _lock() -{ - _bucketToColumn.resize(getNumBuckets()); - reset(); - setNumColumns(numColumns); -} - -BucketDistribution::~BucketDistribution() = default; - -void -BucketDistribution::getBucketCount(uint32_t numColumns, uint32_t numBucketBits, std::vector &ret) -{ - ret.resize(numColumns); - uint32_t cnt = getNumBuckets(numBucketBits) / numColumns; - uint32_t rst = getNumBuckets(numBucketBits) % numColumns; - for (uint32_t i = 0; i < numColumns; ++i) { - ret[i] = cnt + (i < rst ? 1 : 0); - } -} - -void -BucketDistribution::getBucketMigrateCount(uint32_t numColumns, uint32_t numBucketBits, std::vector &ret) -{ - getBucketCount(numColumns++, numBucketBits, ret); - uint32_t cnt = getNumBuckets(numBucketBits) / numColumns; - uint32_t rst = getNumBuckets(numBucketBits) % numColumns; - for (uint32_t i = 0; i < numColumns - 1; ++i) { - ret[i] -= cnt + (i < rst ? 1 : 0); - } -} - -void -BucketDistribution::reset() -{ - for (uint32_t & value : _bucketToColumn) { - value = 0; - } - _numColumns = 1; -} - -void -BucketDistribution::addColumn() -{ - uint32_t newColumns = _numColumns + 1; - std::vector migrate; - getBucketMigrateCount(_numColumns, _numBucketBits, migrate); - uint32_t numBuckets = getNumBuckets(_numBucketBits); - for (uint32_t i = 0; i < numBuckets; ++i) { - uint32_t old = _bucketToColumn[i]; - if (migrate[old] > 0) { - _bucketToColumn[i] = _numColumns; // move this bucket to the new column - migrate[old]--; - } - } - _numColumns = newColumns; -} - -void -BucketDistribution::setNumColumns(uint32_t numColumns) -{ - vespalib::LockGuard guard(_lock); - if (numColumns < _numColumns) { - reset(); - } - if (numColumns == _numColumns) { - return; - } - for (int i = numColumns - _numColumns; --i >= 0; ) { - addColumn(); - } -} - -void -BucketDistribution::setNumBucketBits(uint32_t numBucketBits) -{ - uint32_t numColumns; - { - vespalib::LockGuard guard(_lock); - if (numBucketBits == _numBucketBits) { - return; - } - _numBucketBits = numBucketBits; - _bucketToColumn.resize(getNumBuckets(numBucketBits)); - numColumns = _numColumns; - reset(); - } - setNumColumns(numColumns); -} - -uint32_t -BucketDistribution::getColumn(const document::BucketId &bucketId) const -{ - uint32_t ret = (uint32_t)(bucketId.getId() & (getNumBuckets(_numBucketBits) - 1)); - if (ret >= _bucketToColumn.size()) { - LOG(error, - "The bucket distribution map is not in sync with the number of bucket bits. " - "This should never happen! Distribution is broken!!"); - return 0; - } - return _bucketToColumn[ret]; -} - -} diff --git a/vdslib/src/vespa/vdslib/bucketdistribution.h b/vdslib/src/vespa/vdslib/bucketdistribution.h deleted file mode 100644 index 5d06be53b49..00000000000 --- a/vdslib/src/vespa/vdslib/bucketdistribution.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -#pragma once - -#include -#include -#include - -namespace vdslib { - -/** - * Stable algorithmic hash distribution; this class assigns hash buckets to targets. The number of hash buckets should - * be large compared to the number of targets. The mapping from hash value to hash bucket is performed outside this - * class. - */ -class BucketDistribution { -public: - /** - * Constructs a new bucket distribution object with a given number of columns and buckets. - * - * @param numColumns The number of columns to distribute to. - * @param numBucketBits The number of bits to use for bucket id. - */ - BucketDistribution(uint32_t numColumns, uint32_t numBucketBits); - ~BucketDistribution(); - - /** - * Returns the number of buckets that the given number of bucket bits will allow. - * - * @param numBucketBits The number of bits to use for bucket id. - * @return The number of buckets allowed. - */ - static uint32_t getNumBuckets(uint32_t numBucketBits) { return 1 << numBucketBits; } - - /** - * This method returns a list that contains the distributions of the given number of buckets over the given number - * of columns. - * - * @param numColumns The number of columns to distribute to. - * @param numBucketBits The number of bits to use for bucket id. - * @param ret List to fill with the bucket distribution. - */ - static void getBucketCount(uint32_t numColumns, uint32_t numBucketBits, std::vector &ret); - - /** - * This method returns a list similar to {@link this#getBucketCount(int,int)}, except that the returned list - * contains the number of buckets that will have to be migrated from each column if an additional column was added. - * - * @param numColumns The original number of columns. - * @param numBucketBits The number of bits to use for bucket id. - * @param ret List to fill with the number of buckets to migrate, one value per column. - */ - static void getBucketMigrateCount(uint32_t numColumns, uint32_t numBucketBits, std::vector &ret); - - /** - * Sets the number of columns to distribute to to 1, and resets the content of the internal bucket-to-column map so - * that it all buckets point to that single column. - */ - void reset(); - - /** - * Sets the number of columns to use for this document distribution object. This will reset and setup this object - * from scratch. The original number of buckets is maintained. - * - * @param numColumns The new number of columns to distribute to. - */ - void setNumColumns(uint32_t numColumns); - - /** - * Returns the number of columns to distribute to. - * - * @return The number of columns. - */ - uint32_t getNumColumns() const { return _numColumns; } - - /** - * Sets the number of buckets to use for this document distribution object. This will reset and setup this object - * from scratch. The original number of columns is maintained. - * - * @param numBucketBits The new number of bits to use for bucket id. - */ - void setNumBucketBits(uint32_t numBucketBits); - - /** - * Returns the number of bits used for bucket identifiers. - * - * @return The number of bits. - */ - uint32_t getNumBucketBits() const { return _numBucketBits; } - - /** - * Returns the number of buckets available using the configured number of bucket bits. - * - * @return The number of buckets. - */ - uint32_t getNumBuckets() const { return getNumBuckets(_numBucketBits); } - - /** - * This method maps the given bucket id to its corresponding column. - * - * @param bucketId The bucket whose column to lookup. - * @return The column to distribute the bucket to. - */ - uint32_t getColumn(const document::BucketId &bucketId) const; - -private: - /** - * Adds a single column to this bucket distribution object. This will modify the internal bucket-to-column map so - * that it takes into account the new column. - */ - void addColumn(); - -private: - uint32_t _numColumns; // The number of columns to distribute to. - uint32_t _numBucketBits; // The number of bits to use for bucket identification. - std::vector _bucketToColumn; // A map from bucket id to column index. - vespalib::Lock _lock; -}; - -} diff --git a/vespalib/CMakeLists.txt b/vespalib/CMakeLists.txt index ec003329999..278d32c118d 100644 --- a/vespalib/CMakeLists.txt +++ b/vespalib/CMakeLists.txt @@ -46,7 +46,6 @@ vespa_define_module( src/tests/datastore/unique_store src/tests/datastore/unique_store_dictionary src/tests/datastore/unique_store_string_allocator - src/tests/delegatelist src/tests/detect_type_benchmark src/tests/dotproduct src/tests/drop-file-from-cache @@ -94,7 +93,6 @@ vespa_define_module( src/tests/regex src/tests/rendezvous src/tests/runnable_pair - src/tests/rwlock src/tests/sha1 src/tests/sharedptr src/tests/signalhandler diff --git a/vespalib/src/tests/delegatelist/.cvsignore b/vespalib/src/tests/delegatelist/.cvsignore deleted file mode 100644 index 0e8f4d0be0b..00000000000 --- a/vespalib/src/tests/delegatelist/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.depend -Makefile -delegatelist_test diff --git a/vespalib/src/tests/delegatelist/.gitignore b/vespalib/src/tests/delegatelist/.gitignore deleted file mode 100644 index 42ac4beb0c3..00000000000 --- a/vespalib/src/tests/delegatelist/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.depend -Makefile -delegatelist_test -vespalib_delegatelist_test_app diff --git a/vespalib/src/tests/delegatelist/CMakeLists.txt b/vespalib/src/tests/delegatelist/CMakeLists.txt deleted file mode 100644 index 71551474445..00000000000 --- a/vespalib/src/tests/delegatelist/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(vespalib_delegatelist_test_app TEST - SOURCES - delegatelist.cpp - DEPENDS - vespalib -) -vespa_add_test(NAME vespalib_delegatelist_test_app COMMAND vespalib_delegatelist_test_app) diff --git a/vespalib/src/tests/delegatelist/delegatelist.cpp b/vespalib/src/tests/delegatelist/delegatelist.cpp deleted file mode 100644 index 4dc7e5c97d7..00000000000 --- a/vespalib/src/tests/delegatelist/delegatelist.cpp +++ /dev/null @@ -1,824 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include -#include -#include -#include -#include - -#include -LOG_SETUP("delegatelist_test"); - -using namespace vespalib; - -//----------------------------------------------------------------------------- - -class Test : public TestApp -{ -public: - void testEmpty(); - void testAdd(); - void testRemove(); - void testOneShot(); - void testMultiSnapshot(); - void testActors(); - void testWaitSnapshots(); - void stressTest(); - int Main() override; -}; - -//----------------------------------------------------------------------------- - -namespace { - -class Handler -{ -private: - int _num; -public: - Handler() : _num(0) {} - void add() { _num++; } - int getNum() { return _num; } -}; - -typedef DelegateList DL; - -void multicast(DL &dl) { - for (DL::Snapshot snap(dl) ; snap.valid(); snap.next()) { - snap.get()->add(); - } -} - -void multicast_clear(DL &dl) { - DL::Snapshot snap(dl); - dl.clear(); - for (; snap.valid(); snap.next()) { - snap.get()->add(); - } -} - -//----------------------------------------------------------------------------- - -enum { - CMD_MULTICAST, - CMD_MULTICAST_CLEAR, - CMD_ADD, - CMD_REMOVE, - CMD_CLEAR, - CMD_WAIT_SNAP, - CMD_DO, - CMD_DONE, - CMD_EXIT -}; - -struct Command -{ - DL *dl; - int cmd; - int cnt; - Handler *handler; - Command(DL *dl_, int cmd_, int cnt_, Handler *handler_) noexcept - : dl(dl_), cmd(cmd_), cnt(cnt_), handler(handler_) {} - Command(const Command &rhs) noexcept - : dl(rhs.dl), cmd(rhs.cmd), cnt(rhs.cnt), handler(rhs.handler) {} - Command &operator=(const Command &rhs) noexcept { - memcpy(this, &rhs, sizeof(Command)); - return *this; - } - bool operator==(const Command &rhs) noexcept { - return memcmp(this, &rhs, sizeof(Command)) == 0; - } -}; - -Command -cmd_multicast(DL *dl) { - return Command(dl, CMD_MULTICAST, 0, 0); -} - -Command -cmd_multicast_clear(DL *dl) { - return Command(dl, CMD_MULTICAST_CLEAR, 0, 0); -} - -Command -cmd_add(DL *dl, Handler *handler) { - return Command(dl, CMD_ADD, 0, handler); -} - -Command -cmd_remove(DL *dl, Handler *handler) { - return Command(dl, CMD_REMOVE, 0, handler); -} - -Command -cmd_clear(DL *dl) { - return Command(dl, CMD_CLEAR, 0, 0); -} - -Command -cmd_wait_snap(DL *dl) { - return Command(dl, CMD_WAIT_SNAP, 0, 0); -} - -Command -cmd_do(int cnt) { - return Command(0, CMD_DO, cnt, 0); -} - -Command -cmd_done() { - return Command(0, CMD_DONE, 0, 0); -} - -Command -cmd_exit() { - return Command(0, CMD_EXIT, 0, 0); -} - -typedef std::vector CmdList; -typedef std::pair HistEntry; -typedef std::vector HistList; - -//----------------------------------------------------------------------------- - -struct History { - Lock lock; - HistList list; - History() : lock(), list() {} - void add(const HistEntry &entry) { - LockGuard guard(lock); - list.push_back(entry); - } -}; - -//----------------------------------------------------------------------------- - -template -class Queue { -private: - std::queue _q; - Monitor _cond; - int _waitCnt; - Queue(const Queue &); - Queue &operator=(const Queue &); -public: - Queue() : _q(), _cond(), _waitCnt(0) {} - void enqueue(const T &entry) { - MonitorGuard guard(_cond); - _q.push(entry); - if (_waitCnt > 0) { - guard.signal(); - } - } - T dequeue() { - MonitorGuard guard(_cond); - CounterGuard cntGuard(_waitCnt); - while (_q.empty()) { - guard.wait(); - } - T tmp = _q.front(); - _q.pop(); - return tmp; - } - size_t size() const { return _q.size(); } -}; - -typedef Queue CmdListQueue; - -//----------------------------------------------------------------------------- - -class Actor : public FastOS_Runnable -{ -public: - enum { - STATE_INIT, - STATE_IDLE, - STATE_BUSY, - STATE_DONE - }; -private: - int _id; - History *_hist; - CmdListQueue _queue; - Monitor _cond; - int _state; - int _waitCnt; - int _opCnt; - bool _exit; - Actor(const Actor &); - Actor &operator=(const Actor &); - void setState(int state, MonitorGuard &guard); - void doneOp(const Command &cmd); - int perform(int cnt, int start, const CmdList &cmdList); -public: - Actor(int id, History *hist); - ~Actor(); - int getOpCnt() const { return _opCnt; } - int getState() const { return _state; } - void doIt(const CmdList &cmdList); - void doIt(const Command &cmd); - void waitState(int state); - void Run(FastOS_ThreadInterface *, void *) override; -}; - -Actor::Actor(int id, History *hist) - : _id(id), _hist(hist), _queue(), _cond(), _state(STATE_INIT), - _waitCnt(0), _opCnt(0), _exit(false) -{} -Actor::~Actor() {} - -void -Actor::setState(int state, MonitorGuard &guard) { - _state = state; - if (_waitCnt > 0) { - guard.broadcast(); - } -} - - -void -Actor::doneOp(const Command &cmd) -{ - ++_opCnt; - if (_hist != 0) { - _hist->add(HistEntry(cmd, _id)); - } -} - - -int -Actor::perform(int cnt, int start, const CmdList &cmdList) -{ - int doneIdx = cmdList.size(); - for (int i = 0; i < cnt; ++i) { - for (uint32_t idx = start; idx < cmdList.size(); ++idx) { - Command cmd = cmdList[idx]; - switch (cmd.cmd) { - case CMD_MULTICAST: - multicast(*cmd.dl); - doneOp(cmd); - break; - case CMD_MULTICAST_CLEAR: - multicast_clear(*cmd.dl); - doneOp(cmd); - break; - case CMD_ADD: - cmd.dl->add(cmd.handler); - doneOp(cmd); - break; - case CMD_REMOVE: - cmd.dl->remove(cmd.handler); - doneOp(cmd); - break; - case CMD_CLEAR: - cmd.dl->clear(); - doneOp(cmd); - break; - case CMD_WAIT_SNAP: - cmd.dl->waitSnapshots(); - doneOp(cmd); - break; - case CMD_DO: - idx = perform(cmd.cnt, idx + 1, cmdList); - break; - case CMD_DONE: - doneIdx = idx; - idx = cmdList.size(); - break; - case CMD_EXIT: - _exit = true; - return cmdList.size(); - break; - default: - LOG_ABORT("should not be reached"); // that does not seem to work - } - } - } - return doneIdx; -} - - -void -Actor::doIt(const CmdList &cmdList) -{ - MonitorGuard guard(_cond); - setState(STATE_BUSY, guard); - _queue.enqueue(cmdList); -} - - -void -Actor::doIt(const Command &cmd) -{ - CmdList cmdList; - cmdList.push_back(cmd); - doIt(cmdList); -} - - -void -Actor::waitState(int state) { - MonitorGuard guard(_cond); - CounterGuard cntGuard(_waitCnt); - while (_state != state) { - guard.wait(); - } -} - - -void -Actor::Run(FastOS_ThreadInterface *, void *) -{ - while (!_exit) { - { - MonitorGuard guard(_cond); - if (_queue.size() == 0) { - setState(STATE_IDLE, guard); - } - } - CmdList cmdList = _queue.dequeue(); - perform(1, 0, cmdList); - } - { - MonitorGuard guard(_cond); - setState(STATE_DONE, guard); - } -} - -} // namespace - -//----------------------------------------------------------------------------- - -void -Test::testEmpty() -{ - DL multicaster; - multicast(multicaster); - multicast_clear(multicaster); - DL::Snapshot empty_snap(multicaster); - EXPECT_TRUE(!empty_snap.valid()); -} - - -void -Test::testAdd() -{ - DL multicaster; - Handler h1; - Handler h2; - Handler h3; - Handler h4; - Handler h5; - - // ensure correct initial state - EXPECT_TRUE(h1.getNum() == 0); - EXPECT_TRUE(h2.getNum() == 0); - EXPECT_TRUE(h3.getNum() == 0); - EXPECT_TRUE(h4.getNum() == 0); - EXPECT_TRUE(h5.getNum() == 0); - - // test basic adding - multicaster.add(&h1); - multicast(multicaster); - multicaster.add(&h2); - multicast(multicaster); - multicaster.add(&h3); - multicast(multicaster); - multicaster.add(&h4); - multicast(multicaster); - multicaster.add(&h5); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 5); - EXPECT_TRUE(h2.getNum() == 4); - EXPECT_TRUE(h3.getNum() == 3); - EXPECT_TRUE(h4.getNum() == 2); - EXPECT_TRUE(h5.getNum() == 1); - - // duplicate adds - multicaster.add(&h1); - multicaster.add(&h1); - multicaster.add(&h1); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 6); - EXPECT_TRUE(h2.getNum() == 5); - EXPECT_TRUE(h3.getNum() == 4); - EXPECT_TRUE(h4.getNum() == 3); - EXPECT_TRUE(h5.getNum() == 2); -} - - -void -Test::testRemove() -{ - DL multicaster; - Handler h1; - Handler h2; - Handler h3; - Handler h4; - Handler h5; - - multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 1); - EXPECT_TRUE(h2.getNum() == 1); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 1); - EXPECT_TRUE(h5.getNum() == 1); - - // remove middle - multicaster.remove(&h3); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 2); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 2); - EXPECT_TRUE(h5.getNum() == 2); - - // remove head - multicaster.remove(&h1); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 3); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 3); - EXPECT_TRUE(h5.getNum() == 3); - - // remove tail - multicaster.remove(&h5); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 4); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 4); - EXPECT_TRUE(h5.getNum() == 3); - - // duplicate removes - multicaster.remove(&h1).remove(&h3).remove(&h5); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 5); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 5); - EXPECT_TRUE(h5.getNum() == 3); - - // remove all - multicaster.clear(); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 5); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 5); - EXPECT_TRUE(h5.getNum() == 3); -} - - -void -Test::testOneShot() -{ - DL multicaster; - Handler h1; - Handler h2; - Handler h3; - Handler h4; - Handler h5; - - // oneshot multicast removes handlers - multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5); - multicast_clear(multicaster); - multicast(multicaster); - EXPECT_TRUE(h1.getNum() == 1); - EXPECT_TRUE(h2.getNum() == 1); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 1); - EXPECT_TRUE(h5.getNum() == 1); -} - - -void -Test::testMultiSnapshot() -{ - DL multicaster; - Handler h1; - Handler h2; - Handler h3; - Handler h4; - Handler h5; - - DL::Snapshot empty_snap(multicaster); - multicaster.add(&h1).add(&h2).add(&h3).add(&h4).add(&h5); - DL::Snapshot snap1(multicaster); - multicaster.remove(&h3); - DL::Snapshot snap2(multicaster); - multicaster.remove(&h1); - DL::Snapshot snap3(multicaster); - multicaster.remove(&h5); - DL::Snapshot snap4(multicaster); - - EXPECT_TRUE(!empty_snap.valid()); - for (; snap1.valid(); snap1.next()) { - snap1.get()->add(); - } - EXPECT_TRUE(h1.getNum() == 1); - EXPECT_TRUE(h2.getNum() == 1); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 1); - EXPECT_TRUE(h5.getNum() == 1); - for (; snap2.valid(); snap2.next()) { - snap2.get()->add(); - } - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 2); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 2); - EXPECT_TRUE(h5.getNum() == 2); - for (; snap3.valid(); snap3.next()) { - snap3.get()->add(); - } - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 3); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 3); - EXPECT_TRUE(h5.getNum() == 3); - for (; snap4.valid(); snap4.next()) { - snap4.get()->add(); - } - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 4); - EXPECT_TRUE(h3.getNum() == 1); - EXPECT_TRUE(h4.getNum() == 4); - EXPECT_TRUE(h5.getNum() == 3); -} - - -void -Test::testActors() -{ - FastOS_ThreadPool pool(65000); - History hist; - Actor a1(1, &hist); - Actor a2(2, &hist); - DL dl; - Handler h1; - Handler h2; - - ASSERT_TRUE(pool.NewThread(&a1, 0) != 0); - ASSERT_TRUE(pool.NewThread(&a2, 0) != 0); - - { - CmdList prog; - prog.push_back(cmd_add(&dl, &h1)); - prog.push_back(cmd_multicast(&dl)); - prog.push_back(cmd_add(&dl, &h2)); - prog.push_back(cmd_multicast(&dl)); - a1.doIt(prog); - a1.waitState(Actor::STATE_IDLE); - } - - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 1); - - { - CmdList prog; - prog.push_back(cmd_remove(&dl, &h1)); - prog.push_back(cmd_multicast(&dl)); - prog.push_back(cmd_clear(&dl)); - prog.push_back(cmd_multicast(&dl)); - a2.doIt(prog); - a2.waitState(Actor::STATE_IDLE); - } - - EXPECT_TRUE(h1.getNum() == 2); - EXPECT_TRUE(h2.getNum() == 2); - - { - CmdList prog; - prog.push_back(cmd_add(&dl, &h1)); - prog.push_back(cmd_add(&dl, &h2)); - prog.push_back(cmd_multicast_clear(&dl)); - prog.push_back(cmd_multicast(&dl)); - a1.doIt(prog); - a1.waitState(Actor::STATE_IDLE); - } - - EXPECT_TRUE(h1.getNum() == 3); - EXPECT_TRUE(h2.getNum() == 3); - - { - CmdList prog; - prog.push_back(cmd_add(&dl, &h1)); - prog.push_back(cmd_add(&dl, &h2)); - prog.push_back(cmd_do(10)); - prog.push_back(cmd_do(10)); - prog.push_back(cmd_multicast(&dl)); - prog.push_back(cmd_done()); - prog.push_back(cmd_done()); - prog.push_back(cmd_exit()); - a2.doIt(prog); - a2.waitState(Actor::STATE_DONE); - } - - EXPECT_TRUE(h1.getNum() == 103); - EXPECT_TRUE(h2.getNum() == 103); - - EXPECT_TRUE(hist.list.size() == 114); - - EXPECT_TRUE(hist.list[0].first == cmd_add(&dl, &h1)); - EXPECT_TRUE(hist.list[1].first == cmd_multicast(&dl)); - EXPECT_TRUE(hist.list[2].first == cmd_add(&dl, &h2)); - EXPECT_TRUE(hist.list[3].first == cmd_multicast(&dl)); - for (int i = 0; i < 4; i++) { - EXPECT_TRUE(hist.list[i].second == 1); - } - - EXPECT_TRUE(hist.list[4].first == cmd_remove(&dl, &h1)); - EXPECT_TRUE(hist.list[5].first == cmd_multicast(&dl)); - EXPECT_TRUE(hist.list[6].first == cmd_clear(&dl)); - EXPECT_TRUE(hist.list[7].first == cmd_multicast(&dl)); - for (int i = 4; i < 8; i++) { - EXPECT_TRUE(hist.list[i].second == 2); - } - - EXPECT_TRUE(hist.list[8].first == cmd_add(&dl, &h1)); - EXPECT_TRUE(hist.list[9].first == cmd_add(&dl, &h2)); - EXPECT_TRUE(hist.list[10].first == cmd_multicast_clear(&dl)); - EXPECT_TRUE(hist.list[11].first == cmd_multicast(&dl)); - for (int i = 8; i < 12; i++) { - EXPECT_TRUE(hist.list[i].second == 1); - } - - EXPECT_TRUE(hist.list[12].first == cmd_add(&dl, &h1)); - EXPECT_TRUE(hist.list[13].first == cmd_add(&dl, &h2)); - EXPECT_TRUE(hist.list[12].second == 2); - EXPECT_TRUE(hist.list[13].second == 2); - - for (int i = 14; i < 114; i++) { - EXPECT_TRUE(hist.list[i].first == cmd_multicast(&dl)); - EXPECT_TRUE(hist.list[i].second == 2); - } - - a1.doIt(cmd_exit()); - a1.waitState(Actor::STATE_DONE); - - EXPECT_TRUE(a1.getOpCnt() == 8); - EXPECT_TRUE(a2.getOpCnt() == 106); -} - - -void -Test::stressTest() -{ - FastOS_ThreadPool pool(65000); - Actor a1(1, 0); - Actor a2(2, 0); - Actor a3(3, 0); - Actor a4(4, 0); - Actor a5(5, 0); - Actor a6(6, 0); - DL dl; - Handler h1; - Handler h2; - Handler h3; - Handler h4; - Handler h5; - int scale = 10000; - - ASSERT_TRUE(pool.NewThread(&a1, 0) != 0); - ASSERT_TRUE(pool.NewThread(&a2, 0) != 0); - ASSERT_TRUE(pool.NewThread(&a3, 0) != 0); - ASSERT_TRUE(pool.NewThread(&a4, 0) != 0); - ASSERT_TRUE(pool.NewThread(&a5, 0) != 0); - ASSERT_TRUE(pool.NewThread(&a6, 0) != 0); - - CmdList prog_multicast; - prog_multicast.push_back(cmd_do(10 * scale)); - prog_multicast.push_back(cmd_multicast(&dl)); - prog_multicast.push_back(cmd_done()); - prog_multicast.push_back(cmd_exit()); - - CmdList prog_wait_snap; - prog_wait_snap.push_back(cmd_do(10 * scale)); - prog_wait_snap.push_back(cmd_wait_snap(&dl)); - prog_wait_snap.push_back(cmd_done()); - prog_wait_snap.push_back(cmd_exit()); - - CmdList prog_add_remove_1; - prog_add_remove_1.push_back(cmd_do(scale)); - prog_add_remove_1.push_back(cmd_add(&dl, &h1)); - prog_add_remove_1.push_back(cmd_add(&dl, &h3)); - prog_add_remove_1.push_back(cmd_remove(&dl, &h2)); - prog_add_remove_1.push_back(cmd_remove(&dl, &h4)); - prog_add_remove_1.push_back(cmd_add(&dl, &h4)); - prog_add_remove_1.push_back(cmd_add(&dl, &h2)); - prog_add_remove_1.push_back(cmd_remove(&dl, &h5)); - prog_add_remove_1.push_back(cmd_remove(&dl, &h3)); - prog_add_remove_1.push_back(cmd_add(&dl, &h5)); - prog_add_remove_1.push_back(cmd_remove(&dl, &h1)); - prog_add_remove_1.push_back(cmd_done()); - prog_add_remove_1.push_back(cmd_exit()); - - CmdList prog_add_remove_2; - prog_add_remove_2.push_back(cmd_do(scale)); - prog_add_remove_2.push_back(cmd_add(&dl, &h5)); - prog_add_remove_2.push_back(cmd_add(&dl, &h4)); - prog_add_remove_2.push_back(cmd_remove(&dl, &h1)); - prog_add_remove_2.push_back(cmd_remove(&dl, &h3)); - prog_add_remove_2.push_back(cmd_add(&dl, &h1)); - prog_add_remove_2.push_back(cmd_remove(&dl, &h2)); - prog_add_remove_2.push_back(cmd_add(&dl, &h2)); - prog_add_remove_2.push_back(cmd_add(&dl, &h3)); - prog_add_remove_2.push_back(cmd_remove(&dl, &h5)); - prog_add_remove_2.push_back(cmd_remove(&dl, &h4)); - prog_add_remove_2.push_back(cmd_done()); - prog_add_remove_2.push_back(cmd_exit()); - - CmdList prog_add_remove_3; - prog_add_remove_3.push_back(cmd_do(scale)); - prog_add_remove_3.push_back(cmd_add(&dl, &h3)); - prog_add_remove_3.push_back(cmd_remove(&dl, &h4)); - prog_add_remove_3.push_back(cmd_remove(&dl, &h3)); - prog_add_remove_3.push_back(cmd_add(&dl, &h5)); - prog_add_remove_3.push_back(cmd_add(&dl, &h2)); - prog_add_remove_3.push_back(cmd_remove(&dl, &h2)); - prog_add_remove_3.push_back(cmd_add(&dl, &h1)); - prog_add_remove_3.push_back(cmd_add(&dl, &h4)); - prog_add_remove_3.push_back(cmd_remove(&dl, &h1)); - prog_add_remove_3.push_back(cmd_remove(&dl, &h5)); - prog_add_remove_3.push_back(cmd_done()); - prog_add_remove_3.push_back(cmd_exit()); - - a1.doIt(prog_multicast); - a2.doIt(prog_multicast); - a3.doIt(prog_wait_snap); - a4.doIt(prog_add_remove_1); - a5.doIt(prog_add_remove_2); - a6.doIt(prog_add_remove_3); - - a1.waitState(Actor::STATE_DONE); - a2.waitState(Actor::STATE_DONE); - a3.waitState(Actor::STATE_DONE); - a4.waitState(Actor::STATE_DONE); - a5.waitState(Actor::STATE_DONE); - a6.waitState(Actor::STATE_DONE); - - EXPECT_TRUE(a1.getOpCnt() == 10 * scale); - EXPECT_TRUE(a2.getOpCnt() == 10 * scale); - EXPECT_TRUE(a3.getOpCnt() == 10 * scale); - EXPECT_TRUE(a4.getOpCnt() == 10 * scale); - EXPECT_TRUE(a5.getOpCnt() == 10 * scale); - EXPECT_TRUE(a6.getOpCnt() == 10 * scale); -} - - -void -Test::testWaitSnapshots() -{ - FastOS_ThreadPool pool(65000); - Actor a1(1, 0); - DL dl; - std::unique_ptr s1; - std::unique_ptr s2; - ASSERT_TRUE(pool.NewThread(&a1, 0) != 0); - s1.reset(new DL::Snapshot(dl)); // create snap 1 - a1.doIt(cmd_wait_snap(&dl)); // wait for snaps - std::this_thread::sleep_for(1s); - EXPECT_TRUE(a1.getState() == Actor::STATE_BUSY); // still waiting... - s2.reset(new DL::Snapshot(dl)); // create snap 2 - s1.reset(); // destroy snap 1 - std::this_thread::sleep_for(1s); - EXPECT_TRUE(a1.getState() == Actor::STATE_IDLE); // wait done! - a1.doIt(cmd_exit()); - a1.waitState(Actor::STATE_DONE); - s2.reset(); // destroy snap 2 - EXPECT_TRUE(a1.getOpCnt() == 1); -} - -//----------------------------------------------------------------------------- - -struct Foo { void completeBarrier() {} }; - -int -Test::Main() -{ - TEST_INIT("delegatelist_test"); - LOG(info, "Lock size: %4zu bytes", sizeof(Lock)); - LOG(info, "ArrayQueue size: %4zu bytes", sizeof(ArrayQueue)); - LOG(info, "std::vector size: %4zu bytes", sizeof(std::vector)); - LOG(info, "EventBarrier size: %4zu bytes", sizeof(EventBarrier)); - LOG(info, "DelegateList size: %4zu bytes", sizeof(DelegateList)); - - testEmpty(); - testAdd(); - testRemove(); - testOneShot(); - testMultiSnapshot(); - - TEST_FLUSH(); - testActors(); - testWaitSnapshots(); - - TEST_FLUSH(); - stressTest(); - TEST_DONE(); -} - -TEST_APPHOOK(Test); diff --git a/vespalib/src/tests/rwlock/.gitignore b/vespalib/src/tests/rwlock/.gitignore deleted file mode 100644 index 3ba74c11b14..00000000000 --- a/vespalib/src/tests/rwlock/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.depend -Makefile -rwlock_test -vespalib_rwlock_test_app diff --git a/vespalib/src/tests/rwlock/CMakeLists.txt b/vespalib/src/tests/rwlock/CMakeLists.txt deleted file mode 100644 index 2eda95a200c..00000000000 --- a/vespalib/src/tests/rwlock/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -vespa_add_executable(vespalib_rwlock_test_app TEST - SOURCES - rwlock_test.cpp - DEPENDS - vespalib -) -vespa_add_test(NAME vespalib_rwlock_test_app COMMAND vespalib_rwlock_test_app) diff --git a/vespalib/src/tests/rwlock/rwlock_test.cpp b/vespalib/src/tests/rwlock/rwlock_test.cpp deleted file mode 100644 index 66e73c3a5d9..00000000000 --- a/vespalib/src/tests/rwlock/rwlock_test.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include -#include - -using namespace vespalib; - -class RWLockTest : public TestApp -{ -public: - int Main() override; - static RWLockReader rbvReader(RWLock & lock) { RWLockReader r(lock); return r; } - static RWLockWriter rbvWriter(RWLock & lock) { RWLockWriter r(lock); return r; } -}; - - -int -RWLockTest::Main() -{ - TEST_INIT("rwlock_test"); - - RWLock lock; - EXPECT_TRUE(lock._givenLocks == 0); - { - EXPECT_TRUE(lock._givenLocks == 0); - RWLockReader r1(lock); - EXPECT_TRUE(lock._givenLocks == 1); - RWLockReader r2(lock); - EXPECT_TRUE(lock._givenLocks == 2); - RWLockReader r3(lock); - EXPECT_TRUE(lock._givenLocks == 3); - } - EXPECT_TRUE(lock._givenLocks == 0); - { - EXPECT_TRUE(lock._givenLocks == 0); - RWLockWriter w(lock); - EXPECT_TRUE(lock._givenLocks == -1); - } - EXPECT_TRUE(lock._givenLocks == 0); - { - RWLockReader rbv(rbvReader(lock)); - EXPECT_TRUE(lock._givenLocks == 1); - RWLockReader copy(rbv); - EXPECT_TRUE(lock._givenLocks == 1); - RWLockReader copy2(copy); - EXPECT_TRUE(lock._givenLocks == 1); - } - EXPECT_TRUE(lock._givenLocks == 0); - { - RWLock lock2; - RWLockReader copy(rbvReader(lock)); - EXPECT_TRUE(lock._givenLocks == 1); - RWLockReader copy2(rbvReader(lock2)); - EXPECT_TRUE(lock._givenLocks == 1); - EXPECT_TRUE(lock2._givenLocks == 1); - RWLockReader rbv(rbvReader(lock)); - EXPECT_TRUE(lock._givenLocks == 2); - copy=rbv; - EXPECT_TRUE(lock._givenLocks == 1); - copy2=copy; - EXPECT_TRUE(lock2._givenLocks == 0); - EXPECT_TRUE(lock._givenLocks == 1); - } - EXPECT_TRUE(lock._givenLocks == 0); - { - RWLockWriter rbv(rbvWriter(lock)); - EXPECT_TRUE(lock._givenLocks == -1); - RWLockWriter copy(rbv); - EXPECT_TRUE(lock._givenLocks == -1); - RWLockWriter copy2(copy); - EXPECT_TRUE(lock._givenLocks == -1); - } - EXPECT_TRUE(lock._givenLocks == 0); - - TEST_DONE(); -} - -TEST_APPHOOK(RWLockTest) diff --git a/vespalib/src/tests/sync/sync_test.cpp b/vespalib/src/tests/sync/sync_test.cpp index c8888bc8e54..0925ce060a0 100644 --- a/vespalib/src/tests/sync/sync_test.cpp +++ b/vespalib/src/tests/sync/sync_test.cpp @@ -3,6 +3,44 @@ #include #include +namespace vespalib { +class TryLock +{ +private: + friend class LockGuard; + friend class MonitorGuard; + + std::unique_lock _guard; + std::condition_variable *_cond; + +public: + TryLock(const Lock &lock) + : _guard(*lock._mutex, std::try_to_lock), _cond(nullptr) + {} + TryLock(const Monitor &mon) + : _guard(*mon._mutex, std::try_to_lock), + _cond(_guard ? mon._cond.get() : nullptr) + {} + ~TryLock() = default; + + TryLock(const TryLock &) = delete; + TryLock &operator=(const TryLock &) = delete; + + /** + * @brief Check whether this object holds a lock + * + * @return true if this object holds a lock + **/ + bool hasLock() const { return static_cast(_guard); } + void unlock() { + if (_guard) { + _guard.unlock(); + _cond = nullptr; + } + } +}; + +} using namespace vespalib; #define CHECK_LOCKED(m) { TryLock tl(m); EXPECT_TRUE(!tl.hasLock()); } @@ -18,7 +56,7 @@ private: LockGuard lockMonitor() { return LockGuard(_monitor); } MonitorGuard obtainMonitor() { return MonitorGuard(_monitor); } public: - ~Test(); + ~Test() override; void testCountDownLatch(); int Main() override; }; @@ -139,97 +177,6 @@ Test::Main() MonitorGuard guard(monitor); CHECK_LOCKED(monitor); } - // TryLock hands the lock over to a LockGuard/MonitorGuard - { - Lock lock; - CHECK_UNLOCKED(lock); - TryLock a(lock); - CHECK_LOCKED(lock); - if (a.hasLock()) { - LockGuard guard(std::move(a)); - CHECK_LOCKED(lock); - } - CHECK_UNLOCKED(lock); - } - { - Monitor mon; - CHECK_UNLOCKED(mon); - TryLock a(mon); - CHECK_LOCKED(mon); - if (a.hasLock()) { - LockGuard guard(std::move(a)); - CHECK_LOCKED(mon); - } - CHECK_UNLOCKED(mon); - } - { - Monitor mon; - CHECK_UNLOCKED(mon); - TryLock a(mon); - CHECK_LOCKED(mon); - if (a.hasLock()) { - MonitorGuard guard(std::move(a)); - CHECK_LOCKED(mon); - } - CHECK_UNLOCKED(mon); - } - { - Lock lock; - - CHECK_UNLOCKED(lock); - TryLock a(lock); - CHECK_LOCKED(lock); - TryLock b(lock); - CHECK_LOCKED(lock); - - EXPECT_TRUE(a.hasLock()); - EXPECT_TRUE(!b.hasLock()); - { - CHECK_LOCKED(lock); - EXPECT_TRUE(a.hasLock()); - LockGuard guard(std::move(a)); - EXPECT_TRUE(!a.hasLock()); - CHECK_LOCKED(lock); - } - CHECK_UNLOCKED(lock); - } - // TryLock will unlock when exiting scope if lock was not passed on - { - Lock lock; - Monitor mon; - CHECK_UNLOCKED(lock); - CHECK_UNLOCKED(mon); - { - TryLock a(lock); - EXPECT_TRUE(a.hasLock()); - TryLock b(mon); - EXPECT_TRUE(b.hasLock()); - CHECK_LOCKED(lock); - CHECK_LOCKED(mon); - } - CHECK_UNLOCKED(lock); - CHECK_UNLOCKED(mon); - } - // TryLock explicitt unlock of lock - { - Lock lock; - TryLock tl(lock); - EXPECT_TRUE(tl.hasLock()); - tl.unlock(); - EXPECT_FALSE(tl.hasLock()); - tl.unlock(); - EXPECT_FALSE(tl.hasLock()); - } - // TryLock explicitt unlock of monitor - { - Monitor lock; - TryLock tl(lock); - EXPECT_TRUE(tl.hasLock()); - tl.unlock(); - EXPECT_FALSE(tl.hasLock()); - tl.unlock(); - EXPECT_FALSE(tl.hasLock()); - } // LockGuard/MonitorGuard have destructive move { Lock lock; diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp index df1b68cff12..1f8c72a5a64 100644 --- a/vespalib/src/vespa/vespalib/data/memorydatastore.cpp +++ b/vespalib/src/vespa/vespalib/data/memorydatastore.cpp @@ -5,8 +5,9 @@ namespace vespalib { using alloc::Alloc; +using LockGuard = std::lock_guard; -MemoryDataStore::MemoryDataStore(Alloc && initialAlloc, Lock * lock) : +MemoryDataStore::MemoryDataStore(Alloc && initialAlloc, std::mutex * lock) : _buffers(), _writePos(0), _lock(lock) diff --git a/vespalib/src/vespa/vespalib/data/memorydatastore.h b/vespalib/src/vespa/vespalib/data/memorydatastore.h index 2d02bfb107c..fa6113279da 100644 --- a/vespalib/src/vespa/vespalib/data/memorydatastore.h +++ b/vespalib/src/vespa/vespalib/data/memorydatastore.h @@ -3,8 +3,8 @@ #include #include -#include #include +#include namespace vespalib { @@ -24,7 +24,7 @@ public: private: void * _data; }; - MemoryDataStore(alloc::Alloc && initialAlloc=alloc::Alloc::alloc(256), Lock * lock=nullptr); + MemoryDataStore(alloc::Alloc && initialAlloc=alloc::Alloc::alloc(256), std::mutex * lock=nullptr); MemoryDataStore(const MemoryDataStore &) = delete; MemoryDataStore & operator = (const MemoryDataStore &) = delete; ~MemoryDataStore(); @@ -41,7 +41,7 @@ public: private: std::vector _buffers; size_t _writePos; - Lock * _lock; + std::mutex * _lock; }; class VariableSizeVector diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.cpp b/vespalib/src/vespa/vespalib/testkit/test_master.cpp index 4b673d0ee0d..60e51ac3a91 100644 --- a/vespalib/src/vespa/vespalib/testkit/test_master.cpp +++ b/vespalib/src/vespa/vespalib/testkit/test_master.cpp @@ -37,7 +37,7 @@ __thread TestMaster::ThreadState *TestMaster::_threadState = 0; TestMaster::TraceItem::~TraceItem() = default; TestMaster::ThreadState & -TestMaster::threadState(const vespalib::LockGuard &) +TestMaster::threadState(const lock_guard &) { if (_threadState == 0) { std::ostringstream threadName; @@ -55,7 +55,7 @@ TestMaster::threadState() return *_threadState; } { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); return threadState(guard); } } @@ -63,7 +63,7 @@ TestMaster::threadState() //----------------------------------------------------------------------------- void -TestMaster::checkFailed(const vespalib::LockGuard &guard, +TestMaster::checkFailed(const lock_guard &guard, const char *file, uint32_t line, const char *str) { ThreadState &thread = threadState(guard); @@ -81,7 +81,7 @@ TestMaster::checkFailed(const vespalib::LockGuard &guard, } void -TestMaster::printDiff(const vespalib::LockGuard &guard, +TestMaster::printDiff(const lock_guard &guard, const std::string &text, const std::string &file, uint32_t line, const std::string &lhs, const std::string &rhs) { @@ -106,7 +106,7 @@ TestMaster::printDiff(const vespalib::LockGuard &guard, } void -TestMaster::handleFailure(const vespalib::LockGuard &guard, bool fatal) +TestMaster::handleFailure(const lock_guard &guard, bool fatal) { ThreadState &thread = threadState(guard); if (fatal) { @@ -120,7 +120,7 @@ TestMaster::handleFailure(const vespalib::LockGuard &guard, bool fatal) } void -TestMaster::closeDebugFiles(const vespalib::LockGuard &) +TestMaster::closeDebugFiles(const lock_guard &) { if (_state.lhsFile != NULL) { fclose(_state.lhsFile); @@ -133,7 +133,7 @@ TestMaster::closeDebugFiles(const vespalib::LockGuard &) } void -TestMaster::importThreads(const vespalib::LockGuard &) +TestMaster::importThreads(const lock_guard &) { size_t importCnt = 0; for (size_t i = 0; i < _threadStorage.size(); ++i) { @@ -149,7 +149,7 @@ TestMaster::importThreads(const vespalib::LockGuard &) } bool -TestMaster::reportConclusion(const vespalib::LockGuard &) +TestMaster::reportConclusion(const lock_guard &) { bool ok = (_state.failCnt == 0); fprintf(stderr, "%s: info: summary --- %zu check(s) passed --- %zu check(s) failed\n", @@ -175,7 +175,7 @@ TestMaster::TestMaster() void TestMaster::init(const char *name) { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); _name = skip_path(name); fprintf(stderr, "%s: info: running test suite '%s'\n", _name.c_str(), _name.c_str()); } @@ -183,7 +183,7 @@ TestMaster::init(const char *name) std::string TestMaster::getName() { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); return _name; } @@ -226,7 +226,7 @@ TestMaster::setThreadIgnore(bool ignore) size_t revertCnt = (thread.failCnt - thread.preIgnoreFailCnt); thread.failCnt = thread.preIgnoreFailCnt; if (revertCnt > 0) { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); assert(_state.failCnt >= revertCnt); _state.failCnt -= revertCnt; } @@ -272,7 +272,7 @@ TestMaster::getThreadFailCnt() TestMaster::Progress TestMaster::getProgress() { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); return Progress(_state.passCnt, _state.failCnt); } @@ -280,7 +280,7 @@ void TestMaster::openDebugFiles(const std::string &lhsFile, const std::string &rhsFile) { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); closeDebugFiles(guard); _state.lhsFile = fopen(lhsFile.c_str(), "w"); _state.rhsFile = fopen(rhsFile.c_str(), "w"); @@ -318,7 +318,7 @@ TestMaster::check(bool rc, const char *file, uint32_t line, return true; } { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); checkFailed(guard, file, line, str); handleFailure(guard, fatal); } @@ -330,7 +330,7 @@ TestMaster::flush(const char *file, uint32_t line) { ThreadState &thread = threadState(); if (thread.passCnt > 0) { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); _state.passCnt += thread.passCnt; fprintf(stderr, "%s: info: flushed %zu passed check(s) from thread '%s' (%s:%d)\n", _name.c_str(), thread.passCnt, thread.name.c_str(), skip_path(file), line); @@ -349,7 +349,7 @@ TestMaster::trace(const char *file, uint32_t line) bool TestMaster::discardFailedChecks(size_t failCnt) { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); ThreadState &thread = threadState(guard); if (failCnt == _state.failCnt) { fprintf(stderr, "%s: info: discarding %zu failed check(s)\n", _name.c_str(), _state.failCnt); @@ -367,7 +367,7 @@ TestMaster::discardFailedChecks(size_t failCnt) bool TestMaster::fini() { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); closeDebugFiles(guard); importThreads(guard); return reportConclusion(guard); diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.h b/vespalib/src/vespa/vespalib/testkit/test_master.h index a9dc5ebb3a2..c20982b994d 100644 --- a/vespalib/src/vespa/vespalib/testkit/test_master.h +++ b/vespalib/src/vespa/vespalib/testkit/test_master.h @@ -2,10 +2,10 @@ #pragma once -#include #include #include #include +#include namespace vespalib { @@ -69,24 +69,25 @@ private: }; private: - vespalib::Lock _lock; + std::mutex _lock; std::string _name; std::string _path_prefix; SharedState _state; std::vector > _threadStorage; + using lock_guard = std::lock_guard; private: - ThreadState &threadState(const vespalib::LockGuard &); + ThreadState &threadState(const lock_guard &); ThreadState &threadState(); - void checkFailed(const vespalib::LockGuard &, + void checkFailed(const lock_guard &, const char *file, uint32_t line, const char *str); - void printDiff(const vespalib::LockGuard &, + void printDiff(const lock_guard &, const std::string &text, const std::string &file, uint32_t line, const std::string &lhs, const std::string &rhs); - void handleFailure(const vespalib::LockGuard &, bool do_abort); - void closeDebugFiles(const vespalib::LockGuard &); - void importThreads(const vespalib::LockGuard &); - bool reportConclusion(const vespalib::LockGuard &); + void handleFailure(const lock_guard &, bool do_abort); + void closeDebugFiles(const lock_guard &); + void importThreads(const lock_guard &); + bool reportConclusion(const lock_guard &); private: TestMaster(); diff --git a/vespalib/src/vespa/vespalib/testkit/test_master.hpp b/vespalib/src/vespa/vespalib/testkit/test_master.hpp index f165458c9aa..245c128b788 100644 --- a/vespalib/src/vespa/vespalib/testkit/test_master.hpp +++ b/vespalib/src/vespa/vespalib/testkit/test_master.hpp @@ -33,7 +33,7 @@ TestMaster::compare(const char *file, uint32_t line, lhs << a; rhs << b; { - vespalib::LockGuard guard(_lock); + lock_guard guard(_lock); checkFailed(guard, file, line, str.c_str()); printDiff(guard, str, file, line, lhs.str(), rhs.str()); handleFailure(guard, fatal); diff --git a/vespalib/src/vespa/vespalib/util/CMakeLists.txt b/vespalib/src/vespa/vespalib/util/CMakeLists.txt index fd645f9008c..ea2189fc3a8 100644 --- a/vespalib/src/vespa/vespalib/util/CMakeLists.txt +++ b/vespalib/src/vespa/vespalib/util/CMakeLists.txt @@ -40,7 +40,6 @@ vespa_add_library(vespalib_vespalib_util OBJECT reusable_set_pool.cpp runnable.cpp runnable_pair.cpp - rwlock.cpp sequence.cpp sha1.cpp sig_catch.cpp diff --git a/vespalib/src/vespa/vespalib/util/alloc.cpp b/vespalib/src/vespa/vespalib/util/alloc.cpp index 5ae499f5482..745fb50db03 100644 --- a/vespalib/src/vespa/vespalib/util/alloc.cpp +++ b/vespalib/src/vespa/vespalib/util/alloc.cpp @@ -4,11 +4,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -25,7 +25,7 @@ int _G_HugeFlags = 0; const size_t _G_pageSize = getpagesize(); size_t _G_MMapLogLimit = std::numeric_limits::max(); size_t _G_MMapNoCoreLimit = std::numeric_limits::max(); -Lock _G_lock; +std::mutex _G_lock; std::atomic _G_mmapCount(0); size_t @@ -362,7 +362,7 @@ MMapAllocator::salloc(size_t sz, void * wantedAddress) } #endif if (sz >= _G_MMapLogLimit) { - LockGuard guard(_G_lock); + std::lock_guard guard(_G_lock); _G_HugeMappings[buf] = MMapInfo(mmapId, sz, stackTrace); LOG(info, "%ld mappings of accumulated size %ld", _G_HugeMappings.size(), sum(_G_HugeMappings)); } @@ -412,7 +412,7 @@ void MMapAllocator::sfree(PtrAndSize alloc) retval = munmap(alloc.first, alloc.second); assert(retval == 0); if (alloc.second >= _G_MMapLogLimit) { - LockGuard guard(_G_lock); + std::lock_guard guard(_G_lock); MMapInfo info = _G_HugeMappings[alloc.first]; assert(alloc.second == info._sz); _G_HugeMappings.erase(alloc.first); diff --git a/vespalib/src/vespa/vespalib/util/delegatelist.hpp b/vespalib/src/vespa/vespalib/util/delegatelist.hpp deleted file mode 100644 index 716474f66f7..00000000000 --- a/vespalib/src/vespa/vespalib/util/delegatelist.hpp +++ /dev/null @@ -1,309 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include "eventbarrier.hpp" -#include "sync.h" - -namespace vespalib { - -/** - * Data structure for robust event multi-casting in a multi-threaded - * environment. The state tracked by this class can be modeled as a - * set of bald object pointers; the delegates. All interaction with - * the delegates is done through a snapshot of the delegate list. The - * list may be modified at any time. Modifications will not be visible - * to already existing snapshots. A separate method may be used to - * wait for the destruction of all currently active snapshots. This - * synchronization will ensure visibility of any previous - * modifications to the delegate list. State snapshotting is - * implemented with reference counted immutable lists. Snapshot - * waiting is implemented using event barriers. - **/ -template -class DelegateList -{ -private: - /** - * Simple class used to synchronize with the completion of an - * event barrier by coupling barrier completion to a gate. - **/ - struct Sync - { - Gate gate; - Sync() : gate() {} - void completeBarrier() { gate.countDown(); } - }; - - /** - * Inner structure used when keeping track of a set of delegates. - **/ - struct Node { - uint32_t refcnt; // the number of incoming pointers to this node. - T *delegate; // the delegate tracked by this node. - Node *next; // the next node in this list. - }; - - Lock _lock; // lock protecting access to this object - Node *_head; // head of current list of delegates - EventBarrier _barrier; // object used to resolve event barriers - Node *_freeNodes; // a list of recyclable internal nodes - int _activeNodes; // number of internal nodes currently in use - ArrayQueue _stack; // explicit stack for cheap 'recursion' - - /** - * Allocate a new node and initialize it with the given data - * members. Nodes are recycled internally by this object to reduce - * overhead. - * - * @return the new node - * @param delegate the delegate for the new node - * @param next the next pointer for the new node - **/ - Node *allocNode(T *delegate, Node *next) { - Node *node = _freeNodes; - if (node != 0) { - _freeNodes = node->next; - } else { - node = new Node(); - } - node->refcnt = 1; - node->delegate = delegate; - node->next = next; - ++_activeNodes; - return node; - } - - /** - * Copy a list of nodes. This will increase the reference count of - * the list. - * - * @return the copy of the list - * @param list the list to copy - **/ - Node *copyList(Node *list) { - if (list != 0) { - ++list->refcnt; - } - return list; - } - - /** - * Free a list of nodes. This will decrease the reference count of - * the list. Any nodes no longer in use will be put back on the - * internal free list. - * - * @return 0 - * @param list the list to free - **/ - Node *freeList(Node *list) { - while (list != 0 && --list->refcnt == 0) { - Node *node = list; - list = node->next; - node->next = _freeNodes; - _freeNodes = node; - --_activeNodes; - } - return 0; - } - - DelegateList(const DelegateList &); - DelegateList &operator=(const DelegateList &); - -public: - /** - * A snapshot of a delegate list. The only way to access the - * delegates kept by a delegate list is to create a snapshot of - * it. The snapshot lets the user traverse the list of delegates, - * accessing each of them in turn. The existence of a snapshot is - * used by the delegate list to identify that someone is observing - * the delegate list in a specific state. Snapshots should be - * created on the stack in a scope as close as possible to the - * code actually accessing the delegates. The delegate list itself - * may not be destructed until all snapshots of that list have - * been destructed. - **/ - class Snapshot - { - private: - DelegateList &_list; // the parent object - Node *_head; // head of the snapshotted list - Node *_node; // current position within snapshot - uint32_t _token; // token used for barrier resolving - - Snapshot(const Snapshot &); - Snapshot &operator=(const Snapshot &); - public: - /** - * Create a snapshot of the given delegate list. The snapshots - * current position will be set to the first delegate part of - * the snapshot. - * - * @param list the delegate list we are snapshotting - **/ - explicit Snapshot(DelegateList &list) : _list(list) { - LockGuard guard(list._lock); - _head = list.copyList(list._head); - _node = _head; - _token = list._barrier.startEvent(); - } - - /** - * Destructing a snapshot will tell the delegate list that we - * are no longer accessing the list in the state observed by - * the snapshot. - **/ - ~Snapshot() { - LockGuard guard(_list._lock); - _list.freeList(_head); - _list._barrier.completeEvent(_token); - } - - /** - * Check whether the current delegate is valid. A snapshot - * becomes invalid after the user has stepped through all - * delegates part of the snapshot using the 'next' method. - * - * @return true if the current delegate is valid - **/ - bool valid() const { - return (_node != 0); - } - - /** - * Step to the next delegate. This method may only be called - * if the 'valid' method returns true. - **/ - void next() { - _node = _node->next; - } - - /** - * Get the current delegate. This method may only be called if - * the 'valid' method returns true. - * - * @return current delegate - **/ - T *get() const { - return _node->delegate; - } - }; - - /** - * Create an initially empty delegate list. - **/ - DelegateList() - : _lock(), - _head(0), - _barrier(), - _freeNodes(0), - _activeNodes(0), - _stack() - { - } - - /** - * The destructor will clean up internal memory usage. The - * delegate list itself does not need to be empty when it is - * deleted. However, there may be no active snapshots of it and - * no-one may be waiting for snapshot destruction. - **/ - ~DelegateList() { - freeList(_head); - assert(_barrier.countBarriers() == 0); - assert(_barrier.countEvents() == 0); - assert(_activeNodes == 0); - while (_freeNodes != 0) { - Node *node = _freeNodes; - _freeNodes = node->next; - delete node; - } - } - - /** - * Add a delegate to this list. Adding a delegate that is already - * in the list will have no effect. - * - * @return this object, for chaining - * @param delegate the delegate to add - **/ - DelegateList &add(T *delegate) { - LockGuard guard(_lock); - Node *node = _head; - while (node != 0 && node->delegate != delegate) { - node = node->next; - } - if (node == 0) { - _head = allocNode(delegate, _head); - } - return *this; - } - - /** - * Remove a delegate from this list. - * - * @return this object, for chaining - * @param delegate the delegate to remove - **/ - DelegateList &remove(T *delegate) { - LockGuard guard(_lock); - _stack.clear(); - Node *node = _head; - while (node != 0 && node->delegate != delegate) { - _stack.push(node->delegate); - node = node->next; - } - if (node != 0) { // delegate found in list - node = copyList(node->next); - while (!_stack.empty()) { - try { - node = allocNode(_stack.back(), node); - } catch (...) { - freeList(node); - throw; - } - _stack.popBack(); - } - freeList(_head); - _head = node; - } - return *this; - } - - /** - * Remove all delegates currently in this list. - * - * @return this object, for chaining - **/ - DelegateList &clear() { - LockGuard guard(_lock); - _head = freeList(_head); - return *this; - } - - /** - * Wait for the destruction of all currently active snapshots of - * this list. This method will block until all relevant snapshots - * are destructed. The creation of new snapshots will not - * interfere with the completion of this method. This method is - * used to enforce visibility between threads; after this method - * returns, any modifications performed on the list before this - * method was invoked will be visible to all threads. - * - * @return this object, for chaining - **/ - DelegateList &waitSnapshots() { - Sync sync; - { - LockGuard guard(_lock); - if (!_barrier.startBarrier(sync)) { - return *this; - } - } - sync.gate.await(); - return *this; - } -}; - -} // namespace vespalib - diff --git a/vespalib/src/vespa/vespalib/util/ptrholder.h b/vespalib/src/vespa/vespalib/util/ptrholder.h index 1c06e5c53e6..be528ba25db 100644 --- a/vespalib/src/vespa/vespalib/util/ptrholder.h +++ b/vespalib/src/vespa/vespalib/util/ptrholder.h @@ -4,7 +4,7 @@ #include #include -#include +#include namespace vespalib { @@ -29,11 +29,11 @@ class PtrHolder private: std::shared_ptr _current; std::shared_ptr _next; - mutable Lock _lock; - - PtrHolder(const PtrHolder &); - PtrHolder &operator=(const PtrHolder &); + mutable std::mutex _lock; + using LockGuard = std::lock_guard; public: + PtrHolder(const PtrHolder &) = delete; + PtrHolder &operator=(const PtrHolder &) = delete; /** * @brief Create an empty PtrHolder with both current and new * pointers set to 0 @@ -53,14 +53,14 @@ public: * * @return true if the current value is set (not 0) **/ - bool hasValue() const { return (_current.get() != nullptr); } + bool hasValue() const { return bool(_current); } /** * @brief Check if the new value is set (not 0) * * @return true if the new value is set (not 0) **/ - bool hasNewValue() const { return (_next.get() != nullptr); } + bool hasNewValue() const { return bool(_next); } /** * @brief Set a new value diff --git a/vespalib/src/vespa/vespalib/util/rwlock.cpp b/vespalib/src/vespa/vespalib/util/rwlock.cpp deleted file mode 100644 index fc3799bc1d0..00000000000 --- a/vespalib/src/vespa/vespalib/util/rwlock.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#include "rwlock.h" -#include - -namespace vespalib { - -void RWLock::lockRead() { - MonitorGuard guard(_monitor); - CounterGuard waitCnt(_waitingReaders); - while (_givenLocks == -1 || _waitingWriters > 0) { - guard.wait(); - } - ++_givenLocks; -} - -void RWLock::unlockRead() { - MonitorGuard guard(_monitor); - assert(_givenLocks > 0); - if (--_givenLocks == 0 && _waitingWriters > 0) { - guard.broadcast(); - } -} - -void RWLock::lockWrite() { - MonitorGuard guard(_monitor); - CounterGuard waitCnt(_waitingWriters); - while (_givenLocks != 0) { - guard.wait(); - } - _givenLocks = -1; -} - -void RWLock::unlockWrite() { - MonitorGuard guard(_monitor); - assert(_givenLocks == -1); - _givenLocks = 0; - if (_waitingReaders > 0 || _waitingWriters > 0) { - guard.broadcast(); - } -} - -RWLock * -RWLockReader::stealLock() { - RWLock * ret(_lock); - assert(ret != nullptr); - _lock = nullptr; - return ret; -} - -RWLock * -RWLockWriter::stealLock() { - RWLock * ret(_lock); - assert(ret != nullptr); - _lock = nullptr; - return ret; -} - -} // namespace vespalib diff --git a/vespalib/src/vespa/vespalib/util/rwlock.h b/vespalib/src/vespa/vespalib/util/rwlock.h deleted file mode 100644 index 8818291ae6c..00000000000 --- a/vespalib/src/vespa/vespalib/util/rwlock.h +++ /dev/null @@ -1,240 +0,0 @@ -// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. - -#pragma once - -#include -#include - -class RWLockTest; - -namespace vespalib { - -/** - * @brief An RWLock is a reader/writer lock. It can either be held by - * any number of readers or a single writer at any time. - * - * The RWLockReader and RWLockWriter classes are used to acquire and - * release reader and writer locks respectively. - * - * Writer locks have priority above reader locks to prevent - * starvation. - **/ -class RWLock -{ -private: - friend class ::RWLockTest; - friend class RWLockReader; - friend class RWLockWriter; - - int _givenLocks; - int _waitingReaders; - int _waitingWriters; - Monitor _monitor; - - void lockRead(); - void unlockRead(); - void lockWrite(); - void unlockWrite(); -public: - /** - * @brief Create a new RWLock - **/ - RWLock() - : _givenLocks(0), - _waitingReaders(0), - _waitingWriters(0), - _monitor() {} - /** - * @brief Create a new RWLock, ignoring the right hand side. - * - * It makes no sense to copy the state of an RWLock, but we want - * to allow copying objects that contain RWLock objects. - * - * @param rhs ignore this - **/ - RWLock(const RWLock &rhs) - : _givenLocks(0), - _waitingReaders(0), - _waitingWriters(0), - _monitor() { (void) rhs;} - /** - * @brief Assignment operator ignoring the right hand side. - * - * It makes no sense to assign the state of one RWLock to another, - * but we want to allow assigning objects that contain RWLock - * objects. - * - * @param rhs ignore this - **/ - RWLock &operator=(const RWLock &rhs) { - (void) rhs; - return *this; - } - - /** - * To get an instance of RWLockReader or RWLockWriter that isn't - * associated with a specific RWLock at initialization, you may - * construct them from this tag type. - **/ - struct InitiallyUnlockedGuard {}; -}; - -#ifndef IAM_DOXYGEN -class RWLockReaderHandover -{ -private: - friend class RWLockReader; - RWLock *_lock; - RWLockReaderHandover(const RWLockReaderHandover &); - RWLockReaderHandover &operator=(const RWLockReaderHandover &); - RWLockReaderHandover(RWLock *m) : _lock(m) {} -public: -}; - -class RWLockWriterHandover -{ -private: - friend class RWLockWriter; - RWLock *_lock; - RWLockWriterHandover(const RWLockWriterHandover &); - RWLockWriterHandover &operator=(const RWLockWriterHandover &); - RWLockWriterHandover(RWLock *m) : _lock(m) {} -public: -}; -#endif - - -/** - * @brief An RWLockReader holds a reader lock on an RWLock. - * - * The lock is acquired in the constructor and released in the - * destructor. - * - * RWLockReader has destructive copy (like unique_ptr). Assigning from - * or copying a RWLockReader has the semantic of transferring the lock - * from one object to the other. Note that assigning from or copying - * a RWLockReader that does not have a lock will result in an assert. - **/ -class RWLockReader -{ -private: - RWLock * _lock; - RWLock * stealLock(); - void cleanup() { if (_lock != nullptr) { _lock->unlockRead(); } } -public: - - /** - * @brief Obtain reader lock. - * - * This will block until a reader lock can be acquired. - * - * @param lock the underlying RWLock object - **/ - RWLockReader(RWLock &lock) : _lock(&lock) { _lock->lockRead(); } - - /** - * @brief Construct initially unlocked guard. - * @param tag (unused) marker argument - **/ - RWLockReader(const RWLock::InitiallyUnlockedGuard &tag) : _lock(nullptr) { (void)tag; } - - /** - * @brief Steal the lock from the given RWLockReader - * - * @param rhs steal the lock from this one - **/ - RWLockReader(RWLockReader &rhs) : _lock(rhs.stealLock()) {} - - /** - * @brief Steal the lock from the given RWLockReader - * - * @param rhs steal the lock from this one - **/ - RWLockReader &operator=(RWLockReader & rhs) { - if (this != & rhs) { - cleanup(); - _lock = rhs.stealLock(); - } - return *this; - } - - /** - * @brief Release the lock obtained in the constructor - **/ - ~RWLockReader() { cleanup(); } - -#ifndef IAM_DOXYGEN - RWLockReader(const RWLockReaderHandover &rhs) : _lock(rhs._lock) {} - operator RWLockReaderHandover() { return RWLockReaderHandover(stealLock()); } -#endif -}; - - -/** - * @brief An RWLockWriter holds a writer lock on an RWLock. - * - * The lock is acquired in the constructor and released in the - * destructor. - * - * RWLockWriter has destructive copy (like unique_ptr). Assigning from - * or copying a RWLockWriter has the semantic of transferring the lock - * from one object to the other, and assignment is similar. Note that - * assigning from or copying a RWLockWriter that does not have a lock - * will result in an assert. - **/ -class RWLockWriter -{ -private: - RWLock * _lock; - RWLock * stealLock(); - void cleanup() { if (_lock != nullptr) { _lock->unlockWrite(); } } -public: - - /** - * @brief Obtain writer lock. - * - * This will block until a writer lock can be acquired. - * - * @param lock the underlying RWLock object - **/ - RWLockWriter(RWLock &lock) : _lock(&lock) { _lock->lockWrite(); } - - /** - * @brief Construct initially unlocked guard. - * @param tag (unused) marker argument - **/ - RWLockWriter(const RWLock::InitiallyUnlockedGuard &tag) : _lock(nullptr) { (void)tag; } - - /** - * @brief Steal the lock from the given RWLockWriter - * - * @param rhs steal the lock from this one - **/ - RWLockWriter(RWLockWriter &rhs) : _lock(rhs.stealLock()) {} - - /** - * @brief Steal the lock from the given RWLockWriter - * - * @param rhs steal the lock from this one - **/ - RWLockWriter &operator=(RWLockWriter & rhs) { - if (this != & rhs) { - cleanup(); - _lock = rhs.stealLock(); - } - return *this; - } - - /** - * @brief Release the lock obtained in the constructor - **/ - ~RWLockWriter() { cleanup(); } - -#ifndef IAM_DOXYGEN - RWLockWriter(const RWLockWriterHandover &rhs) : _lock(rhs._lock) {} - operator RWLockWriterHandover() { return RWLockWriterHandover(stealLock()); } -#endif -}; - -} // namespace vespalib - diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp index 886003a2ab6..e0d78c5d1b7 100644 --- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp +++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.cpp @@ -69,7 +69,7 @@ SimpleThreadBundle::UP SimpleThreadBundle::Pool::obtain() { { - LockGuard guard(_lock); + std::lock_guard guard(_lock); if (!_bundles.empty()) { SimpleThreadBundle::UP ret(_bundles.back()); _bundles.pop_back(); @@ -82,7 +82,7 @@ SimpleThreadBundle::Pool::obtain() void SimpleThreadBundle::Pool::release(SimpleThreadBundle::UP bundle) { - LockGuard guard(_lock); + std::lock_guard guard(_lock); _bundles.push_back(bundle.get()); bundle.release(); } diff --git a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h index dbf9f7025b6..135fc2d7562 100644 --- a/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h +++ b/vespalib/src/vespa/vespalib/util/simple_thread_bundle.h @@ -2,7 +2,6 @@ #pragma once -#include "sync.h" #include "count_down_latch.h" #include "thread.h" #include "runnable.h" @@ -94,8 +93,8 @@ public: class Pool { private: - Lock _lock; - size_t _bundleSize; + std::mutex _lock; + size_t _bundleSize; std::vector _bundles; public: diff --git a/vespalib/src/vespa/vespalib/util/sync.cpp b/vespalib/src/vespa/vespalib/util/sync.cpp index 3819b2b3369..ac55f12c341 100644 --- a/vespalib/src/vespa/vespalib/util/sync.cpp +++ b/vespalib/src/vespa/vespalib/util/sync.cpp @@ -19,47 +19,10 @@ Monitor::Monitor() noexcept Monitor::Monitor(Monitor &&rhs) noexcept = default; Monitor::~Monitor() = default; - -TryLock::TryLock(const Lock &lock) - : _guard(*lock._mutex, std::try_to_lock), - _cond(nullptr) -{} - -TryLock::TryLock(const Monitor &mon) - : _guard(*mon._mutex, std::try_to_lock), - _cond(_guard ? mon._cond.get() : nullptr) -{} - -TryLock::TryLock(TryLock &&rhs) noexcept - : _guard(std::move(rhs._guard)), - _cond(rhs._cond) -{ - rhs._cond = nullptr; -} - -TryLock::~TryLock() = default; - -bool -TryLock::hasLock() const { - return static_cast(_guard); -} - -void -TryLock::unlock() { - if (_guard) { - _guard.unlock(); - _cond = nullptr; - } -} - LockGuard::LockGuard() : _guard() {} LockGuard::LockGuard(LockGuard &&rhs) noexcept : _guard(std::move(rhs._guard)) { } LockGuard::LockGuard(const Lock &lock) : _guard(*lock._mutex) { } -LockGuard::LockGuard(TryLock &&tlock) : _guard(std::move(tlock._guard)) -{ - tlock._cond = nullptr; -} LockGuard & LockGuard::operator=(LockGuard &&rhs) noexcept{ @@ -93,16 +56,6 @@ MonitorGuard::MonitorGuard(const Monitor &monitor) : _guard(*monitor._mutex), _cond(monitor._cond.get()) { } -MonitorGuard::MonitorGuard(TryLock &&tlock) - : _guard(), - _cond(nullptr) -{ - if (tlock._guard && tlock._cond != nullptr) { - _guard = std::move(tlock._guard); - _cond = tlock._cond; - tlock._cond = nullptr; - } -} MonitorGuard & MonitorGuard::operator=(MonitorGuard &&rhs) noexcept { diff --git a/vespalib/src/vespa/vespalib/util/sync.h b/vespalib/src/vespa/vespalib/util/sync.h index b1227ce658e..3207206a753 100644 --- a/vespalib/src/vespa/vespalib/util/sync.h +++ b/vespalib/src/vespa/vespalib/util/sync.h @@ -69,89 +69,6 @@ public: }; -/** - * @brief A TryLock object is used to try to obtain the lock on a Lock - * or a Monitor without blocking. - * - * A TryLock will typically fail to obatin the lock if someone else - * already has it. In that case, the TryLock object has no further - * use. - * - * If the TryLock managed to acquire the lock, it can be passed over - * to a LockGuard or MonitorGuard object. If the lock is not passed - * on, the TryLock object will release it when it goes out of scope. - * - * Note that passing the lock obtained from a Lock to a MonitorGuard - * is illegal. Also note that if the TryLock fails to aquire the lock, - * it cannot be passed on. Trying to do so will result in an assert. - * - * copy/assignment of a TryLock is illegal. - * - *
- * Example:
- *
- * Lock lock;
- * TryLock tl(lock);
- * if (tl.hasLock()) {
- *   LockGuard guard(tl)
- *   ... do stuff
- * } // the lock is released as 'guard' goes out of scope
- * 
- **/ -class TryLock -{ -private: - friend class LockGuard; - friend class MonitorGuard; - - std::unique_lock _guard; - std::condition_variable *_cond; - -public: - /** - * @brief Try to obtain the lock represented by the given Lock object - * - * @param lock the lock to obtain - **/ - TryLock(const Lock &lock); - - /** - * @brief Try to lock the given Monitor - * - * @param mon the monitor to lock - **/ - TryLock(const Monitor &mon); - - TryLock(TryLock &&rhs) noexcept; - - /** - * @brief Release the lock held by this object, if any - **/ - ~TryLock(); - - TryLock(const TryLock &) = delete; - TryLock &operator=(const TryLock &) = delete; - - TryLock &operator=(TryLock &&rhs) noexcept; - - /** - * @brief Check whether this object holds a lock - * - * @return true if this object holds a lock - **/ - bool hasLock() const; - /** - * @brief Release the lock held by this object. - * - * No methods may be invoked after invoking unlock (except the - * destructor). Note that this method should only be used if you - * need to release the lock before the object is destructed, as - * the destructor will release the lock. - **/ - void unlock(); -}; - - /** * @brief A LockGuard holds the lock on either a Lock or a Monitor. * @@ -191,17 +108,6 @@ public: **/ LockGuard(const Lock &lock); - /** - * @brief Create a LockGuard from a TryLock. - * - * The TryLock may have been created from either a Lock or a - * Monitor, but it must have managed to acquire the lock. The lock - * will be handed over from the TryLock to the new object. - * - * @param tlock take the lock from this one - **/ - LockGuard(TryLock &&tlock); - LockGuard &operator=(LockGuard &&rhs) noexcept; /** @@ -267,16 +173,6 @@ public: * @param monitor take the lock on it **/ MonitorGuard(const Monitor &monitor); - /** - * @brief Create a MonitorGuard from a TryLock. - * - * The TryLock must have been created from a Monitor, and it must - * have managed to acquire the lock. The lock will be handed over - * from the TryLock to the new object. - * - * @param tlock take the lock from this one - **/ - MonitorGuard(TryLock &&tlock); MonitorGuard &operator=(MonitorGuard &&rhs) noexcept; diff --git a/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp b/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp index 8307954faae..db238279fa3 100644 --- a/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp +++ b/vsm/src/vespa/vsm/vsm/vsm-adapter.cpp @@ -116,7 +116,7 @@ DocsumTools::obtainFieldNames(const FastS_VsmsummaryHandle &cfg) void VSMAdapter::configure(const VSMConfigSnapshot & snapshot) { - vespalib::LockGuard guard(_lock); + std::lock_guard guard(_lock); LOG(debug, "(re-)configure VSM (docsum tools)"); std::shared_ptr summary(snapshot.getConfig().release()); @@ -141,7 +141,7 @@ VSMAdapter::configure(const VSMConfigSnapshot & snapshot) } // init keyword extractor - std::unique_ptr kwExtractor(new KeywordExtractor(NULL)); + auto kwExtractor = std::make_unique(nullptr); kwExtractor->AddLegalIndexSpec(_highlightindexes.c_str()); vespalib::string spec = kwExtractor->GetLegalIndexSpec(); LOG(debug, "index highlight spec: '%s'", spec.c_str()); diff --git a/vsm/src/vespa/vsm/vsm/vsm-adapter.h b/vsm/src/vespa/vsm/vsm/vsm-adapter.h index 31e472713de..f6895dd71a6 100644 --- a/vsm/src/vespa/vsm/vsm/vsm-adapter.h +++ b/vsm/src/vespa/vsm/vsm/vsm-adapter.h @@ -127,7 +127,7 @@ private: vespalib::PtrHolder _docsumTools; std::unique_ptr _juniperProps; - vespalib::Lock _lock; + std::mutex _lock; VSMAdapter(const VSMAdapter &); VSMAdapter &operator=(const VSMAdapter &); -- cgit v1.2.3