summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mongo/SConscript8
-rw-r--r--src/mongo/db/catalog/collection_info_cache.cpp47
-rw-r--r--src/mongo/db/catalog/collection_info_cache.h8
-rw-r--r--src/mongo/db/ops/SConscript2
-rw-r--r--src/mongo/db/ops/update.cpp8
-rw-r--r--src/mongo/db/ops/update_driver.cpp2
-rw-r--r--src/mongo/db/ops/update_driver.h6
-rw-r--r--src/mongo/db/ops/update_driver_test.cpp4
-rw-r--r--src/mongo/db/ops/update_lifecycle.h2
-rw-r--r--src/mongo/db/ops/update_lifecycle_impl.cpp2
-rw-r--r--src/mongo/db/ops/update_lifecycle_impl.h2
-rw-r--r--src/mongo/db/update_index_data.cpp (renamed from src/mongo/db/index_set.cpp)49
-rw-r--r--src/mongo/db/update_index_data.h (renamed from src/mongo/db/index_set.h)32
-rw-r--r--src/mongo/db/update_index_data_test.cpp (renamed from src/mongo/db/index_set_test.cpp)35
14 files changed, 155 insertions, 52 deletions
diff --git a/src/mongo/SConscript b/src/mongo/SConscript
index a9b8d0ebaae..6a230b45b64 100644
--- a/src/mongo/SConscript
+++ b/src/mongo/SConscript
@@ -149,8 +149,8 @@ env.CppUnitTest('bsonobjbuilder_test', ['bson/bsonobjbuilder_test.cpp'],
env.CppUnitTest('namespacestring_test', ['db/namespace_string_test.cpp'],
LIBDEPS=['bson'])
-env.CppUnitTest('index_set_test', ['db/index_set_test.cpp'],
- LIBDEPS=['bson','index_set'])
+env.CppUnitTest('update_index_data_test', ['db/update_index_data_test.cpp'],
+ LIBDEPS=['bson','update_index_data','db/common'])
env.Library('path',
['db/matcher/path.cpp',
@@ -547,7 +547,7 @@ if has_option( "mm" ):
else:
mmapFiles += [ "util/mmap_${OS_FAMILY}.cpp" ]
-env.Library('index_set', [ 'db/index_set.cpp' ] )
+env.Library('update_index_data', [ 'db/update_index_data.cpp' ], LIPDEPS=[ 'db/common' ])
# Global Configuration. Used by both mongos and mongod.
env.Library('global_environment_experiment',
@@ -907,8 +907,8 @@ serveronlyLibdeps = ["coreshard",
"defaultversion",
"global_optime",
"index_key_validate",
- "index_set",
'range_deleter',
+ "update_index_data",
's/metadata',
's/batch_write_types',
"db/catalog/collection_options",
diff --git a/src/mongo/db/catalog/collection_info_cache.cpp b/src/mongo/db/catalog/collection_info_cache.cpp
index 85122d0d926..aea1af88c42 100644
--- a/src/mongo/db/catalog/collection_info_cache.cpp
+++ b/src/mongo/db/catalog/collection_info_cache.cpp
@@ -32,10 +32,12 @@
#include "mongo/db/catalog/collection_info_cache.h"
-#include "mongo/db/d_concurrency.h"
-#include "mongo/db/query/plan_cache.h"
#include "mongo/db/catalog/collection.h"
+#include "mongo/db/d_concurrency.h"
+#include "mongo/db/fts/fts_spec.h"
#include "mongo/db/index/index_descriptor.h"
+#include "mongo/db/index_legacy.h"
+#include "mongo/db/query/plan_cache.h"
#include "mongo/util/debug_util.h"
#include "mongo/util/log.h"
@@ -61,13 +63,40 @@ namespace mongo {
void CollectionInfoCache::computeIndexKeys() {
_indexedPaths.clear();
- IndexCatalog::IndexIterator i = _collection->getIndexCatalog()->getIndexIterator( true );
- while( i.more() ) {
- BSONObj key = i.next()->keyPattern();
- BSONObjIterator j( key );
- while ( j.more() ) {
- BSONElement e = j.next();
- _indexedPaths.addPath( e.fieldName() );
+ IndexCatalog::IndexIterator i = _collection->getIndexCatalog()->getIndexIterator(true);
+ while (i.more()) {
+ IndexDescriptor* descriptor = i.next();
+
+ if (descriptor->getAccessMethodName() != IndexNames::TEXT) {
+ BSONObj key = descriptor->keyPattern();
+ BSONObjIterator j(key);
+ while (j.more()) {
+ BSONElement e = j.next();
+ _indexedPaths.addPath(e.fieldName());
+ }
+ }
+ else {
+ fts::FTSSpec ftsSpec(descriptor->infoObj());
+
+ if (ftsSpec.wildcard()) {
+ _indexedPaths.allPathsIndexed();
+ }
+ else {
+ for (size_t i = 0; i < ftsSpec.numExtraBefore(); ++i) {
+ _indexedPaths.addPath(ftsSpec.extraBefore(i));
+ }
+ for (fts::Weights::const_iterator it = ftsSpec.weights().begin();
+ it != ftsSpec.weights().end();
+ ++it) {
+ _indexedPaths.addPath(it->first);
+ }
+ for (size_t i = 0; i < ftsSpec.numExtraAfter(); ++i) {
+ _indexedPaths.addPath(ftsSpec.extraAfter(i));
+ }
+ // Any update to a path containing "language" as a component could change the
+ // language of a subdocument. Add the override field as a path component.
+ _indexedPaths.addPathComponent(ftsSpec.languageOverrideField());
+ }
}
}
diff --git a/src/mongo/db/catalog/collection_info_cache.h b/src/mongo/db/catalog/collection_info_cache.h
index 874018fdc89..3948c55e5c0 100644
--- a/src/mongo/db/catalog/collection_info_cache.h
+++ b/src/mongo/db/catalog/collection_info_cache.h
@@ -32,9 +32,9 @@
#include <boost/scoped_ptr.hpp>
-#include "mongo/db/index_set.h"
-#include "mongo/db/query/query_settings.h"
#include "mongo/db/query/plan_cache.h"
+#include "mongo/db/query/query_settings.h"
+#include "mongo/db/update_index_data.h"
namespace mongo {
@@ -73,7 +73,7 @@ namespace mongo {
/* get set of index keys for this namespace. handy to quickly check if a given
field is indexed (Note it might be a secondary component of a compound index.)
*/
- const IndexPathSet& indexKeys() {
+ const UpdateIndexData& indexKeys() {
if ( !_keysComputed )
computeIndexKeys();
return _indexedPaths;
@@ -97,7 +97,7 @@ namespace mongo {
// --- index keys cache
bool _keysComputed;
- IndexPathSet _indexedPaths;
+ UpdateIndexData _indexedPaths;
// A cache for query plans.
boost::scoped_ptr<PlanCache> _planCache;
diff --git a/src/mongo/db/ops/SConscript b/src/mongo/db/ops/SConscript
index 8748b5586e1..82f7a214c3c 100644
--- a/src/mongo/db/ops/SConscript
+++ b/src/mongo/db/ops/SConscript
@@ -207,7 +207,7 @@ env.Library(
'$BUILD_DIR/mongo/bson',
'$BUILD_DIR/mongo/db/common',
'$BUILD_DIR/mongo/db/query/query_planner',
- '$BUILD_DIR/mongo/index_set',
+ '$BUILD_DIR/mongo/update_index_data',
'update',
],
)
diff --git a/src/mongo/db/ops/update.cpp b/src/mongo/db/ops/update.cpp
index 4a95d8c92c9..921f7fd02e6 100644
--- a/src/mongo/db/ops/update.cpp
+++ b/src/mongo/db/ops/update.cpp
@@ -37,9 +37,10 @@
#include "mongo/bson/mutable/algorithm.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/client/dbclientinterface.h"
+#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/database_holder.h"
#include "mongo/db/clientcursor.h"
-#include "mongo/db/index_set.h"
+#include "mongo/db/operation_context_impl.h"
#include "mongo/db/ops/update_driver.h"
#include "mongo/db/ops/update_executor.h"
#include "mongo/db/ops/update_lifecycle.h"
@@ -47,10 +48,9 @@
#include "mongo/db/query/get_executor.h"
#include "mongo/db/query/lite_parsed_query.h"
#include "mongo/db/query/query_planner_common.h"
-#include "mongo/db/repl/repl_coordinator_global.h"
#include "mongo/db/repl/oplog.h"
-#include "mongo/db/operation_context_impl.h"
-#include "mongo/db/catalog/collection.h"
+#include "mongo/db/repl/repl_coordinator_global.h"
+#include "mongo/db/update_index_data.h"
#include "mongo/platform/unordered_set.h"
#include "mongo/util/log.h"
diff --git a/src/mongo/db/ops/update_driver.cpp b/src/mongo/db/ops/update_driver.cpp
index 9492cb13851..672aad85d73 100644
--- a/src/mongo/db/ops/update_driver.cpp
+++ b/src/mongo/db/ops/update_driver.cpp
@@ -390,7 +390,7 @@ namespace mongo {
return _affectIndices;
}
- void UpdateDriver::refreshIndexKeys(const IndexPathSet* indexedFields) {
+ void UpdateDriver::refreshIndexKeys(const UpdateIndexData* indexedFields) {
_indexedFields = indexedFields;
}
diff --git a/src/mongo/db/ops/update_driver.h b/src/mongo/db/ops/update_driver.h
index 29a702a1917..0b9fd951cb8 100644
--- a/src/mongo/db/ops/update_driver.h
+++ b/src/mongo/db/ops/update_driver.h
@@ -35,11 +35,11 @@
#include "mongo/base/status.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/db/field_ref_set.h"
-#include "mongo/db/index_set.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/ops/modifier_interface.h"
#include "mongo/db/ops/modifier_table.h"
#include "mongo/db/query/canonical_query.h"
+#include "mongo/db/update_index_data.h"
namespace mongo {
@@ -107,7 +107,7 @@ namespace mongo {
bool isDocReplacement() const;
bool modsAffectIndices() const;
- void refreshIndexKeys(const IndexPathSet* indexedFields);
+ void refreshIndexKeys(const UpdateIndexData* indexedFields);
bool logOp() const;
void setLogOp(bool logOp);
@@ -153,7 +153,7 @@ namespace mongo {
// applied that participate in indices?
//
// NOTE: Owned by the collection's info cache!.
- const IndexPathSet* _indexedFields;
+ const UpdateIndexData* _indexedFields;
//
// mutable properties after parsing
diff --git a/src/mongo/db/ops/update_driver_test.cpp b/src/mongo/db/ops/update_driver_test.cpp
index b9213821cb3..27f26d9dd3a 100644
--- a/src/mongo/db/ops/update_driver_test.cpp
+++ b/src/mongo/db/ops/update_driver_test.cpp
@@ -31,7 +31,7 @@
#include "mongo/base/string_data.h"
#include "mongo/bson/mutable/document.h"
#include "mongo/bson/mutable/mutable_bson_test_utils.h"
-#include "mongo/db/index_set.h"
+#include "mongo/db/update_index_data.h"
#include "mongo/db/json.h"
#include "mongo/unittest/unittest.h"
@@ -39,7 +39,7 @@ namespace {
using mongo::BSONObj;
using mongo::fromjson;
- using mongo::IndexPathSet;
+ using mongo::UpdateIndexData;
using mongo::mutablebson::Document;
using mongo::StringData;
using mongo::UpdateDriver;
diff --git a/src/mongo/db/ops/update_lifecycle.h b/src/mongo/db/ops/update_lifecycle.h
index 4cb5076aa88..ed5b55d3e5d 100644
--- a/src/mongo/db/ops/update_lifecycle.h
+++ b/src/mongo/db/ops/update_lifecycle.h
@@ -56,7 +56,7 @@ namespace mongo {
/**
* Return a pointer to any indexes if there is a collection.
*/
- virtual const IndexPathSet* getIndexKeys() const = 0;
+ virtual const UpdateIndexData* getIndexKeys() const = 0;
/**
* Returns the shard keys as immutable fields
diff --git a/src/mongo/db/ops/update_lifecycle_impl.cpp b/src/mongo/db/ops/update_lifecycle_impl.cpp
index 5ae625923e5..87648c37403 100644
--- a/src/mongo/db/ops/update_lifecycle_impl.cpp
+++ b/src/mongo/db/ops/update_lifecycle_impl.cpp
@@ -61,7 +61,7 @@ namespace mongo {
return _collection;
}
- const IndexPathSet* UpdateLifecycleImpl::getIndexKeys() const {
+ const UpdateIndexData* UpdateLifecycleImpl::getIndexKeys() const {
if (_collection)
return &_collection->infoCache()->indexKeys();
return NULL;
diff --git a/src/mongo/db/ops/update_lifecycle_impl.h b/src/mongo/db/ops/update_lifecycle_impl.h
index c5a5b15ac67..fa612463757 100644
--- a/src/mongo/db/ops/update_lifecycle_impl.h
+++ b/src/mongo/db/ops/update_lifecycle_impl.h
@@ -52,7 +52,7 @@ namespace mongo {
virtual bool canContinue() const;
- virtual const IndexPathSet* getIndexKeys() const;
+ virtual const UpdateIndexData* getIndexKeys() const;
virtual const std::vector<FieldRef*>* getImmutableFields() const;
diff --git a/src/mongo/db/index_set.cpp b/src/mongo/db/update_index_data.cpp
index 5e16d0d90b0..2d93b5b6381 100644
--- a/src/mongo/db/index_set.cpp
+++ b/src/mongo/db/update_index_data.cpp
@@ -1,4 +1,4 @@
-// index_set.cpp
+// update_index_data.cpp
/**
* Copyright (C) 2013 10gen Inc.
@@ -29,32 +29,47 @@
*/
#include "mongo/bson/util/builder.h"
-#include "mongo/db/index_set.h"
+#include "mongo/db/field_ref.h"
+#include "mongo/db/update_index_data.h"
namespace mongo {
- void IndexPathSet::addPath( const StringData& path ) {
+ UpdateIndexData::UpdateIndexData() : _allPathsIndexed( false ) { }
+
+ void UpdateIndexData::addPath( const StringData& path ) {
string s;
if ( getCanonicalIndexField( path, &s ) ) {
- _canonical.insert( s );
+ _canonicalPaths.insert( s );
}
else {
- _canonical.insert( path.toString() );
+ _canonicalPaths.insert( path.toString() );
}
}
- void IndexPathSet::clear() {
- _canonical.clear();
+ void UpdateIndexData::addPathComponent( const StringData& pathComponent ) {
+ _pathComponents.insert( pathComponent.toString() );
+ }
+
+ void UpdateIndexData::allPathsIndexed() {
+ _allPathsIndexed = true;
}
- bool IndexPathSet::mightBeIndexed( const StringData& path ) const {
+ void UpdateIndexData::clear() {
+ _canonicalPaths.clear();
+ }
+
+ bool UpdateIndexData::mightBeIndexed( const StringData& path ) const {
+ if ( _allPathsIndexed ) {
+ return true;
+ }
+
StringData use = path;
string x;
if ( getCanonicalIndexField( path, &x ) )
use = StringData( x );
- for ( std::set<string>::const_iterator i = _canonical.begin();
- i != _canonical.end();
+ for ( std::set<string>::const_iterator i = _canonicalPaths.begin();
+ i != _canonicalPaths.end();
++i ) {
StringData idx( *i );
@@ -66,10 +81,22 @@ namespace mongo {
return true;
}
+ FieldRef pathFieldRef( path );
+ for ( std::set<string>::const_iterator i = _pathComponents.begin();
+ i != _pathComponents.end();
+ ++i ) {
+ const string& pathComponent = *i;
+ for ( size_t partIdx = 0; partIdx < pathFieldRef.numParts(); ++partIdx ) {
+ if ( pathComponent == pathFieldRef.getPart( partIdx ) ) {
+ return true;
+ }
+ }
+ }
+
return false;
}
- bool IndexPathSet::_startsWith( const StringData& a, const StringData& b ) const {
+ bool UpdateIndexData::_startsWith( const StringData& a, const StringData& b ) const {
if ( !a.startsWith( b ) )
return false;
diff --git a/src/mongo/db/index_set.h b/src/mongo/db/update_index_data.h
index b0a25a73773..90541b35df2 100644
--- a/src/mongo/db/index_set.h
+++ b/src/mongo/db/update_index_data.h
@@ -1,4 +1,4 @@
-// index_set.h
+// update_index_data.h
/**
* Copyright (C) 2013 10gen Inc.
@@ -42,10 +42,33 @@ namespace mongo {
*/
bool getCanonicalIndexField( const StringData& fullName, std::string* out );
- class IndexPathSet {
+
+ /**
+ * Holds pre-processed index spec information to allow update to quickly determine if an update
+ * can be applied as a delta to a document, or if the document must be re-indexed.
+ */
+ class UpdateIndexData {
public:
+ UpdateIndexData();
+
+ /**
+ * Register a path. Any update targeting this path (or a parent of this path) will
+ * trigger a recomputation of the document's index keys.
+ */
void addPath( const StringData& path );
+ /**
+ * Register a path component. Any update targeting a path that contains this exact
+ * component will trigger a recomputation of the document's index keys.
+ */
+ void addPathComponent( const StringData& pathComponent );
+
+ /**
+ * Register the "wildcard" path. All updates will trigger a recomputation of the document's
+ * index keys.
+ */
+ void allPathsIndexed();
+
void clear();
bool mightBeIndexed( const StringData& path ) const;
@@ -54,7 +77,10 @@ namespace mongo {
bool _startsWith( const StringData& a, const StringData& b ) const;
- std::set<std::string> _canonical;
+ std::set<std::string> _canonicalPaths;
+ std::set<std::string> _pathComponents;
+
+ bool _allPathsIndexed;
};
}
diff --git a/src/mongo/db/index_set_test.cpp b/src/mongo/db/update_index_data_test.cpp
index 595fac04238..244356d2845 100644
--- a/src/mongo/db/index_set_test.cpp
+++ b/src/mongo/db/update_index_data_test.cpp
@@ -1,4 +1,4 @@
-// index_set_tests.cpp
+// update_index_data_tests.cpp
/* Copyright 2012 10gen Inc.
*
@@ -29,12 +29,12 @@
#include "mongo/unittest/unittest.h"
-#include "mongo/db/index_set.h"
+#include "mongo/db/update_index_data.h"
namespace mongo {
- TEST( IndexPathSetTest, Simple1 ) {
- IndexPathSet a;
+ TEST( UpdateIndexDataTest, Simple1 ) {
+ UpdateIndexData a;
a.addPath( "a.b" );
ASSERT_TRUE( a.mightBeIndexed( "a.b" ) );
ASSERT_TRUE( a.mightBeIndexed( "a" ) );
@@ -45,14 +45,35 @@ namespace mongo {
ASSERT_FALSE( a.mightBeIndexed( "a.c" ) );
}
- TEST( IndexPathSetTest, Simple2 ) {
- IndexPathSet a;
+ TEST( UpdateIndexDataTest, Simple2 ) {
+ UpdateIndexData a;
a.addPath( "ab" );
ASSERT_FALSE( a.mightBeIndexed( "a" ) );
}
+ TEST( UpdateIndexDataTest, Component1 ) {
+ UpdateIndexData a;
+ a.addPathComponent( "a" );
+ ASSERT_FALSE( a.mightBeIndexed( "" ) );
+ ASSERT_TRUE( a.mightBeIndexed( "a" ) );
+ ASSERT_TRUE( a.mightBeIndexed( "b.a" ) );
+ ASSERT_TRUE( a.mightBeIndexed( "a.b" ) );
+ ASSERT_TRUE( a.mightBeIndexed( "b.a.c" ) );
+ ASSERT_FALSE( a.mightBeIndexed( "b.c" ) );
+ ASSERT_FALSE( a.mightBeIndexed( "ab" ) );
+ }
+
+ TEST( UpdateIndexDataTest, AllPathsIndexed1 ) {
+ UpdateIndexData a;
+ a.allPathsIndexed();
+ ASSERT_TRUE( a.mightBeIndexed( "a" ) );
+ ASSERT_TRUE( a.mightBeIndexed( "" ) );
+ a.addPathComponent( "a" );
+ ASSERT_TRUE( a.mightBeIndexed( "a" ) );
+ ASSERT_TRUE( a.mightBeIndexed( "b" ) );
+ }
- TEST( IndexPathSetTest, getCanonicalIndexField1 ) {
+ TEST( UpdateIndexDataTest, getCanonicalIndexField1 ) {
string x;
ASSERT_FALSE( getCanonicalIndexField( "a", &x ) );