summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/working_set.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/exec/working_set.cpp')
-rw-r--r--src/mongo/db/exec/working_set.cpp393
1 files changed, 196 insertions, 197 deletions
diff --git a/src/mongo/db/exec/working_set.cpp b/src/mongo/db/exec/working_set.cpp
index 746ace2f3ca..5e531af346a 100644
--- a/src/mongo/db/exec/working_set.cpp
+++ b/src/mongo/db/exec/working_set.cpp
@@ -33,248 +33,247 @@
namespace mongo {
- using std::string;
+using std::string;
- WorkingSet::MemberHolder::MemberHolder() : member(NULL) { }
- WorkingSet::MemberHolder::~MemberHolder() {}
+WorkingSet::MemberHolder::MemberHolder() : member(NULL) {}
+WorkingSet::MemberHolder::~MemberHolder() {}
- WorkingSet::WorkingSet() : _freeList(INVALID_ID) { }
+WorkingSet::WorkingSet() : _freeList(INVALID_ID) {}
- WorkingSet::~WorkingSet() {
- for (size_t i = 0; i < _data.size(); i++) {
- delete _data[i].member;
- }
+WorkingSet::~WorkingSet() {
+ for (size_t i = 0; i < _data.size(); i++) {
+ delete _data[i].member;
}
-
- WorkingSetID WorkingSet::allocate() {
- if (_freeList == INVALID_ID) {
- // The free list is empty so we need to make a single new WSM to return. This relies on
- // vector::resize being amortized O(1) for efficient allocation. Note that the free list
- // remains empty until something is returned by a call to free().
- WorkingSetID id = _data.size();
- _data.resize(_data.size() + 1);
- _data.back().nextFreeOrSelf = id;
- _data.back().member = new WorkingSetMember();
- return id;
- }
-
- // Pop the head off the free list and return it.
- WorkingSetID id = _freeList;
- _freeList = _data[id].nextFreeOrSelf;
- _data[id].nextFreeOrSelf = id; // set to self to mark as in-use
+}
+
+WorkingSetID WorkingSet::allocate() {
+ if (_freeList == INVALID_ID) {
+ // The free list is empty so we need to make a single new WSM to return. This relies on
+ // vector::resize being amortized O(1) for efficient allocation. Note that the free list
+ // remains empty until something is returned by a call to free().
+ WorkingSetID id = _data.size();
+ _data.resize(_data.size() + 1);
+ _data.back().nextFreeOrSelf = id;
+ _data.back().member = new WorkingSetMember();
return id;
}
- void WorkingSet::free(const WorkingSetID& i) {
- MemberHolder& holder = _data[i];
- verify(i < _data.size()); // ID has been allocated.
- verify(holder.nextFreeOrSelf == i); // ID currently in use.
-
- // Free resources and push this WSM to the head of the freelist.
- holder.member->clear();
- holder.nextFreeOrSelf = _freeList;
- _freeList = i;
- }
-
- void WorkingSet::flagForReview(const WorkingSetID& i) {
- WorkingSetMember* member = get(i);
- verify(WorkingSetMember::OWNED_OBJ == member->state);
- _flagged.insert(i);
+ // Pop the head off the free list and return it.
+ WorkingSetID id = _freeList;
+ _freeList = _data[id].nextFreeOrSelf;
+ _data[id].nextFreeOrSelf = id; // set to self to mark as in-use
+ return id;
+}
+
+void WorkingSet::free(const WorkingSetID& i) {
+ MemberHolder& holder = _data[i];
+ verify(i < _data.size()); // ID has been allocated.
+ verify(holder.nextFreeOrSelf == i); // ID currently in use.
+
+ // Free resources and push this WSM to the head of the freelist.
+ holder.member->clear();
+ holder.nextFreeOrSelf = _freeList;
+ _freeList = i;
+}
+
+void WorkingSet::flagForReview(const WorkingSetID& i) {
+ WorkingSetMember* member = get(i);
+ verify(WorkingSetMember::OWNED_OBJ == member->state);
+ _flagged.insert(i);
+}
+
+const unordered_set<WorkingSetID>& WorkingSet::getFlagged() const {
+ return _flagged;
+}
+
+bool WorkingSet::isFlagged(WorkingSetID id) const {
+ invariant(id < _data.size());
+ return _flagged.end() != _flagged.find(id);
+}
+
+void WorkingSet::clear() {
+ for (size_t i = 0; i < _data.size(); i++) {
+ delete _data[i].member;
}
+ _data.clear();
- const unordered_set<WorkingSetID>& WorkingSet::getFlagged() const {
- return _flagged;
- }
-
- bool WorkingSet::isFlagged(WorkingSetID id) const {
- invariant(id < _data.size());
- return _flagged.end() != _flagged.find(id);
- }
+ // Since working set is now empty, the free list pointer should
+ // point to nothing.
+ _freeList = INVALID_ID;
- void WorkingSet::clear() {
- for (size_t i = 0; i < _data.size(); i++) {
- delete _data[i].member;
- }
- _data.clear();
+ _flagged.clear();
+}
- // Since working set is now empty, the free list pointer should
- // point to nothing.
- _freeList = INVALID_ID;
+//
+// Iteration
+//
- _flagged.clear();
+WorkingSet::iterator::iterator(WorkingSet* ws, size_t index) : _ws(ws), _index(index) {
+ // If we're currently not pointing at an allocated member, then we have
+ // to advance to the first one, unless we're already at the end.
+ if (_index < _ws->_data.size() && isFree()) {
+ advance();
}
+}
- //
- // Iteration
- //
-
- WorkingSet::iterator::iterator(WorkingSet* ws, size_t index)
- : _ws(ws),
- _index(index) {
- // If we're currently not pointing at an allocated member, then we have
- // to advance to the first one, unless we're already at the end.
- if (_index < _ws->_data.size() && isFree()) {
- advance();
- }
- }
+void WorkingSet::iterator::advance() {
+ // Move forward at least once in the data list.
+ _index++;
- void WorkingSet::iterator::advance() {
- // Move forward at least once in the data list.
+ // While we haven't hit the end and the current member is not in use. (Skips ahead until
+ // we find the next allocated member.)
+ while (_index < _ws->_data.size() && isFree()) {
_index++;
-
- // While we haven't hit the end and the current member is not in use. (Skips ahead until
- // we find the next allocated member.)
- while (_index < _ws->_data.size() && isFree()) {
- _index++;
- }
}
+}
- bool WorkingSet::iterator::isFree() const {
- return _ws->_data[_index].nextFreeOrSelf != _index;
- }
+bool WorkingSet::iterator::isFree() const {
+ return _ws->_data[_index].nextFreeOrSelf != _index;
+}
- void WorkingSet::iterator::free() {
- dassert(!isFree());
- _ws->free(_index);
- }
+void WorkingSet::iterator::free() {
+ dassert(!isFree());
+ _ws->free(_index);
+}
- void WorkingSet::iterator::operator++() {
- dassert(_index < _ws->_data.size());
- advance();
- }
+void WorkingSet::iterator::operator++() {
+ dassert(_index < _ws->_data.size());
+ advance();
+}
- bool WorkingSet::iterator::operator==(const WorkingSet::iterator& other) const {
- return (_index == other._index);
- }
+bool WorkingSet::iterator::operator==(const WorkingSet::iterator& other) const {
+ return (_index == other._index);
+}
- bool WorkingSet::iterator::operator!=(const WorkingSet::iterator& other) const {
- return (_index != other._index);
- }
+bool WorkingSet::iterator::operator!=(const WorkingSet::iterator& other) const {
+ return (_index != other._index);
+}
- WorkingSetMember& WorkingSet::iterator::operator*() {
- dassert(_index < _ws->_data.size() && !isFree());
- return *_ws->_data[_index].member;
- }
+WorkingSetMember& WorkingSet::iterator::operator*() {
+ dassert(_index < _ws->_data.size() && !isFree());
+ return *_ws->_data[_index].member;
+}
- WorkingSetMember* WorkingSet::iterator::operator->() {
- dassert(_index < _ws->_data.size() && !isFree());
- return _ws->_data[_index].member;
- }
+WorkingSetMember* WorkingSet::iterator::operator->() {
+ dassert(_index < _ws->_data.size() && !isFree());
+ return _ws->_data[_index].member;
+}
- WorkingSet::iterator WorkingSet::begin() {
- return WorkingSet::iterator(this, 0);
- }
+WorkingSet::iterator WorkingSet::begin() {
+ return WorkingSet::iterator(this, 0);
+}
- WorkingSet::iterator WorkingSet::end() {
- return WorkingSet::iterator(this, _data.size());
- }
+WorkingSet::iterator WorkingSet::end() {
+ return WorkingSet::iterator(this, _data.size());
+}
- //
- // WorkingSetMember
- //
+//
+// WorkingSetMember
+//
- WorkingSetMember::WorkingSetMember() : state(WorkingSetMember::INVALID), isSuspicious(false) { }
+WorkingSetMember::WorkingSetMember() : state(WorkingSetMember::INVALID), isSuspicious(false) {}
- WorkingSetMember::~WorkingSetMember() { }
+WorkingSetMember::~WorkingSetMember() {}
- void WorkingSetMember::clear() {
- for (size_t i = 0; i < WSM_COMPUTED_NUM_TYPES; i++) {
- _computed[i].reset();
- }
-
- keyData.clear();
- obj.reset();
- state = WorkingSetMember::INVALID;
- }
-
- bool WorkingSetMember::hasLoc() const {
- return state == LOC_AND_IDX || state == LOC_AND_UNOWNED_OBJ || state == LOC_AND_OWNED_OBJ;
+void WorkingSetMember::clear() {
+ for (size_t i = 0; i < WSM_COMPUTED_NUM_TYPES; i++) {
+ _computed[i].reset();
}
- bool WorkingSetMember::hasObj() const {
- return hasOwnedObj() || hasUnownedObj();
+ keyData.clear();
+ obj.reset();
+ state = WorkingSetMember::INVALID;
+}
+
+bool WorkingSetMember::hasLoc() const {
+ return state == LOC_AND_IDX || state == LOC_AND_UNOWNED_OBJ || state == LOC_AND_OWNED_OBJ;
+}
+
+bool WorkingSetMember::hasObj() const {
+ return hasOwnedObj() || hasUnownedObj();
+}
+
+bool WorkingSetMember::hasOwnedObj() const {
+ return state == OWNED_OBJ || state == LOC_AND_OWNED_OBJ;
+}
+
+bool WorkingSetMember::hasUnownedObj() const {
+ return state == LOC_AND_UNOWNED_OBJ;
+}
+
+bool WorkingSetMember::hasComputed(const WorkingSetComputedDataType type) const {
+ return _computed[type].get();
+}
+
+const WorkingSetComputedData* WorkingSetMember::getComputed(
+ const WorkingSetComputedDataType type) const {
+ verify(_computed[type]);
+ return _computed[type].get();
+}
+
+void WorkingSetMember::addComputed(WorkingSetComputedData* data) {
+ verify(!hasComputed(data->type()));
+ _computed[data->type()].reset(data);
+}
+
+void WorkingSetMember::setFetcher(RecordFetcher* fetcher) {
+ _fetcher.reset(fetcher);
+}
+
+RecordFetcher* WorkingSetMember::releaseFetcher() {
+ return _fetcher.release();
+}
+
+bool WorkingSetMember::hasFetcher() const {
+ return NULL != _fetcher.get();
+}
+
+bool WorkingSetMember::getFieldDotted(const string& field, BSONElement* out) const {
+ // If our state is such that we have an object, use it.
+ if (hasObj()) {
+ *out = obj.value().getFieldDotted(field);
+ return true;
}
- bool WorkingSetMember::hasOwnedObj() const {
- return state == OWNED_OBJ || state == LOC_AND_OWNED_OBJ;
- }
+ // Our state should be such that we have index data/are covered.
+ for (size_t i = 0; i < keyData.size(); ++i) {
+ BSONObjIterator keyPatternIt(keyData[i].indexKeyPattern);
+ BSONObjIterator keyDataIt(keyData[i].keyData);
- bool WorkingSetMember::hasUnownedObj() const {
- return state == LOC_AND_UNOWNED_OBJ;
- }
-
- bool WorkingSetMember::hasComputed(const WorkingSetComputedDataType type) const {
- return _computed[type].get();
- }
+ while (keyPatternIt.more()) {
+ BSONElement keyPatternElt = keyPatternIt.next();
+ verify(keyDataIt.more());
+ BSONElement keyDataElt = keyDataIt.next();
- const WorkingSetComputedData* WorkingSetMember::getComputed(const WorkingSetComputedDataType type) const {
- verify(_computed[type]);
- return _computed[type].get();
+ if (field == keyPatternElt.fieldName()) {
+ *out = keyDataElt;
+ return true;
+ }
+ }
}
- void WorkingSetMember::addComputed(WorkingSetComputedData* data) {
- verify(!hasComputed(data->type()));
- _computed[data->type()].reset(data);
- }
+ return false;
+}
- void WorkingSetMember::setFetcher(RecordFetcher* fetcher) {
- _fetcher.reset(fetcher);
- }
+size_t WorkingSetMember::getMemUsage() const {
+ size_t memUsage = 0;
- RecordFetcher* WorkingSetMember::releaseFetcher() {
- return _fetcher.release();
+ if (hasLoc()) {
+ memUsage += sizeof(RecordId);
}
- bool WorkingSetMember::hasFetcher() const {
- return NULL != _fetcher.get();
+ // XXX: Unowned objects count towards current size.
+ // See SERVER-12579
+ if (hasObj()) {
+ memUsage += obj.value().objsize();
}
- bool WorkingSetMember::getFieldDotted(const string& field, BSONElement* out) const {
- // If our state is such that we have an object, use it.
- if (hasObj()) {
- *out = obj.value().getFieldDotted(field);
- return true;
- }
-
- // Our state should be such that we have index data/are covered.
- for (size_t i = 0; i < keyData.size(); ++i) {
- BSONObjIterator keyPatternIt(keyData[i].indexKeyPattern);
- BSONObjIterator keyDataIt(keyData[i].keyData);
-
- while (keyPatternIt.more()) {
- BSONElement keyPatternElt = keyPatternIt.next();
- verify(keyDataIt.more());
- BSONElement keyDataElt = keyDataIt.next();
-
- if (field == keyPatternElt.fieldName()) {
- *out = keyDataElt;
- return true;
- }
- }
- }
-
- return false;
+ for (size_t i = 0; i < keyData.size(); ++i) {
+ const IndexKeyDatum& keyDatum = keyData[i];
+ memUsage += keyDatum.keyData.objsize();
}
- size_t WorkingSetMember::getMemUsage() const {
- size_t memUsage = 0;
-
- if (hasLoc()) {
- memUsage += sizeof(RecordId);
- }
-
- // XXX: Unowned objects count towards current size.
- // See SERVER-12579
- if (hasObj()) {
- memUsage += obj.value().objsize();
- }
-
- for (size_t i = 0; i < keyData.size(); ++i) {
- const IndexKeyDatum& keyDatum = keyData[i];
- memUsage += keyDatum.keyData.objsize();
- }
-
- return memUsage;
- }
+ return memUsage;
+}
} // namespace mongo