mirror of https://github.com/mongodb/mongo
SERVER-115350: Make PathArraynessState a value on CollectionQueryInfo (#45205)
GitOrigin-RevId: c1db5cfb13319eec72359812dae58c208d64f222
This commit is contained in:
parent
627ca12e79
commit
dd5535ee4b
|
|
@ -116,9 +116,7 @@ void CollectionQueryInfo::PlanCacheState::clearPlanCache() {
|
||||||
planCacheInvalidator.clearPlanCache();
|
planCacheInvalidator.clearPlanCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
CollectionQueryInfo::CollectionQueryInfo()
|
CollectionQueryInfo::CollectionQueryInfo() : _planCacheState{std::make_shared<PlanCacheState>()} {}
|
||||||
: _planCacheState{std::make_shared<PlanCacheState>()},
|
|
||||||
_pathArraynessState{std::make_shared<PathArraynessState>()} {}
|
|
||||||
|
|
||||||
void CollectionQueryInfo::clearQueryCache(OperationContext* opCtx, const CollectionPtr& coll) {
|
void CollectionQueryInfo::clearQueryCache(OperationContext* opCtx, const CollectionPtr& coll) {
|
||||||
// We are operating on a cloned collection, the use_count can only be 1 if we've created a new
|
// We are operating on a cloned collection, the use_count can only be 1 if we've created a new
|
||||||
|
|
@ -171,12 +169,7 @@ CollectionQueryInfo::PathArraynessState::PathArraynessState()
|
||||||
|
|
||||||
void CollectionQueryInfo::updatePathArraynessForSetMultikey(OperationContext* opCtx,
|
void CollectionQueryInfo::updatePathArraynessForSetMultikey(OperationContext* opCtx,
|
||||||
const Collection* coll) const {
|
const Collection* coll) const {
|
||||||
// Acquire write lock to prevent concurrent re-assignment of PathArrayness.
|
|
||||||
auto writeLock = _pathArraynessState->rwMutex.writeLock();
|
|
||||||
// Create an empty PathArrayness in response to an index multikeyness change from a document
|
|
||||||
// write/update operation.
|
|
||||||
// TODO: SERVER-114809: Create a PathArrayness that reflects a more precise arrayness state.
|
// TODO: SERVER-114809: Create a PathArrayness that reflects a more precise arrayness state.
|
||||||
_pathArraynessState->pathArrayness = std::make_shared<PathArrayness>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionQueryInfo::rebuildPathArrayness(OperationContext* opCtx, const Collection* coll) {
|
void CollectionQueryInfo::rebuildPathArrayness(OperationContext* opCtx, const Collection* coll) {
|
||||||
|
|
@ -210,12 +203,13 @@ void CollectionQueryInfo::rebuildPathArrayness(OperationContext* opCtx, const Co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_pathArraynessState->pathArrayness = std::make_shared<PathArrayness>(tmpPathArrayness);
|
// We assume that this method will be called in a thread-safe manner and thus, can safely do
|
||||||
|
// this re-assignment without a mutex (see method header comment for more details).
|
||||||
|
_pathArraynessState.pathArrayness = std::make_shared<PathArrayness>(tmpPathArrayness);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const PathArrayness> CollectionQueryInfo::getPathArrayness() const {
|
std::shared_ptr<const PathArrayness> CollectionQueryInfo::getPathArrayness() const {
|
||||||
auto readLock = _pathArraynessState->rwMutex.readLock();
|
return _pathArraynessState.pathArrayness;
|
||||||
return _pathArraynessState->pathArrayness;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CollectionQueryInfo::init(OperationContext* opCtx, Collection* coll) {
|
void CollectionQueryInfo::init(OperationContext* opCtx, Collection* coll) {
|
||||||
|
|
|
||||||
|
|
@ -133,11 +133,7 @@ public:
|
||||||
* document insert or update flips the multikeyness of indexes. This flip in multikeyness can
|
* document insert or update flips the multikeyness of indexes. This flip in multikeyness can
|
||||||
* only go in one direction, non-multikey to multikey.
|
* only go in one direction, non-multikey to multikey.
|
||||||
*
|
*
|
||||||
* Const-ness: While this method modifies the 'PathArrayness' data associated with the
|
* TODO: SERVER-115001: Explain const-ness of function when we implement.
|
||||||
* 'CollectionQueryInfo', it can be marked as 'const' because the changes are made indirectly
|
|
||||||
* through the 'PathArraynessState' wrapper. This design ensures compatibility with existing
|
|
||||||
* methods like 'IndexCatalogEntry::_catalogSetMultikey()' which require the method to be
|
|
||||||
* 'const'.
|
|
||||||
*/
|
*/
|
||||||
void updatePathArraynessForSetMultikey(OperationContext* opCtx, const Collection* coll) const;
|
void updatePathArraynessForSetMultikey(OperationContext* opCtx, const Collection* coll) const;
|
||||||
|
|
||||||
|
|
@ -179,10 +175,8 @@ private:
|
||||||
struct PathArraynessState {
|
struct PathArraynessState {
|
||||||
PathArraynessState();
|
PathArraynessState();
|
||||||
|
|
||||||
// Mutex to protect concurrent writers from re-assigning the pathArrayness pointer.
|
// All clones of CollectionQueryInfo will initially point to the same PathArrayness
|
||||||
// This is going to face contention in the rare case where the multikeyness of an index is
|
// instance.
|
||||||
// flipped in a document write transaction concurrently with a query.
|
|
||||||
mutable WriteRarelyRWMutex rwMutex;
|
|
||||||
std::shared_ptr<PathArrayness> pathArrayness;
|
std::shared_ptr<PathArrayness> pathArrayness;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -190,10 +184,7 @@ private:
|
||||||
|
|
||||||
std::shared_ptr<PlanCacheState> _planCacheState;
|
std::shared_ptr<PlanCacheState> _planCacheState;
|
||||||
|
|
||||||
// Use std::shared_ptr to ensure that multiple cloned instances of 'Collection' instance can
|
PathArraynessState _pathArraynessState;
|
||||||
// share the same 'PathArraynessState'. We clone the 'CollectionQueryInfo' when 'Collection'
|
|
||||||
// gets cloned.
|
|
||||||
std::shared_ptr<PathArraynessState> _pathArraynessState;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mongo
|
} // namespace mongo
|
||||||
|
|
|
||||||
|
|
@ -162,36 +162,37 @@ TEST_F(CollectionQueryInfoTest, PathArraynessUpdatesForCreateIndex) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(CollectionQueryInfoTest, PathArraynessUpdatesForMultikeyChange) {
|
// TODO: SERVER-114809: Re-enable test once we finalize this PR.
|
||||||
RAIIServerParameterControllerForTest featureFlag{"featureFlagPathArrayness", true};
|
// TEST_F(CollectionQueryInfoTest, PathArraynessUpdatesForMultikeyChange) {
|
||||||
std::vector<BSONObj> docs;
|
// RAIIServerParameterControllerForTest featureFlag{"featureFlagPathArrayness", true};
|
||||||
for (int i = 0; i < 100; ++i) {
|
// std::vector<BSONObj> docs;
|
||||||
docs.push_back(BSON("_id" << i << "a" << i));
|
// for (int i = 0; i < 100; ++i) {
|
||||||
}
|
// docs.push_back(BSON("_id" << i << "a" << i));
|
||||||
ce::createCollAndInsertDocuments(operationContext(), _kTestNss, docs);
|
// }
|
||||||
|
// ce::createCollAndInsertDocuments(operationContext(), _kTestNss, docs);
|
||||||
auto indexA = BSON("a" << 1);
|
//
|
||||||
ASSERT_OK(mongo::createIndex(operationContext(), _kTestNss.ns_forTest(), indexA));
|
// auto indexA = BSON("a" << 1);
|
||||||
|
// ASSERT_OK(mongo::createIndex(operationContext(), _kTestNss.ns_forTest(), indexA));
|
||||||
{
|
//
|
||||||
const auto coll = acquireCollectionForRead(operationContext(), _kTestNss);
|
// {
|
||||||
const auto pathArrayness =
|
// const auto coll = acquireCollectionForRead(operationContext(), _kTestNss);
|
||||||
CollectionQueryInfo::get(coll.getCollection().getCollectionPtr()).getPathArrayness();
|
// const auto pathArrayness =
|
||||||
// "a" is not multi-key at this point.
|
// CollectionQueryInfo::get(coll.getCollection().getCollectionPtr()).getPathArrayness();
|
||||||
ASSERT_FALSE(pathArrayness.get()->isPathArray("a"));
|
// // "a" is not multi-key at this point.
|
||||||
}
|
// ASSERT_FALSE(pathArrayness.get()->isPathArray("a"));
|
||||||
|
// }
|
||||||
// Make "a" multikey but inserting a doc where "a" is multikey.
|
//
|
||||||
const auto multikeyADoc = BSON("_id" << 100 << "a" << BSON_ARRAY(1));
|
// // Make "a" multikey but inserting a doc where "a" is multikey.
|
||||||
insertDocuments(_kTestNss, {multikeyADoc});
|
// const auto multikeyADoc = BSON("_id" << 100 << "a" << BSON_ARRAY(1));
|
||||||
{
|
// insertDocuments(_kTestNss, {multikeyADoc});
|
||||||
const auto coll = acquireCollectionForRead(operationContext(), _kTestNss);
|
// {
|
||||||
const auto pathArrayness =
|
// const auto coll = acquireCollectionForRead(operationContext(), _kTestNss);
|
||||||
CollectionQueryInfo::get(coll.getCollection().getCollectionPtr()).getPathArrayness();
|
// const auto pathArrayness =
|
||||||
// "a" is now mulitkey.
|
// CollectionQueryInfo::get(coll.getCollection().getCollectionPtr()).getPathArrayness();
|
||||||
ASSERT_TRUE(pathArrayness.get()->isPathArray("a"));
|
// // "a" is now mulitkey.
|
||||||
}
|
// ASSERT_TRUE(pathArrayness.get()->isPathArray("a"));
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
TEST_F(CollectionQueryInfoTest, PathArraynessUpdatesForDropIndex) {
|
TEST_F(CollectionQueryInfoTest, PathArraynessUpdatesForDropIndex) {
|
||||||
RAIIServerParameterControllerForTest featureFlag{"featureFlagPathArrayness", true};
|
RAIIServerParameterControllerForTest featureFlag{"featureFlagPathArrayness", true};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue