IndexBounds ChunkManager::collapseQuerySolution(const QuerySolutionNode* node) { if (node->children.size() == 0) { invariant(node->getType() == STAGE_IXSCAN); const IndexScanNode* ixNode = static_cast<const IndexScanNode*>(node); return ixNode->bounds; } if (node->children.size() == 1) { // e.g. FETCH -> IXSCAN return collapseQuerySolution(node->children.front()); } // children.size() > 1, assert it's OR / SORT_MERGE. if (node->getType() != STAGE_OR && node->getType() != STAGE_SORT_MERGE) { // Unexpected node. We should never reach here. error() << "could not generate index bounds on query solution tree: " << node->toString(); dassert(false); // We'd like to know this error in testing. // Bail out with all shards in production, since this isn't a fatal error. return IndexBounds(); } IndexBounds bounds; for (vector<QuerySolutionNode*>::const_iterator it = node->children.begin(); it != node->children.end(); it++) { // The first branch under OR if (it == node->children.begin()) { invariant(bounds.size() == 0); bounds = collapseQuerySolution(*it); if (bounds.size() == 0) { // Got unexpected node in query solution tree return IndexBounds(); } continue; } IndexBounds childBounds = collapseQuerySolution(*it); if (childBounds.size() == 0) { // Got unexpected node in query solution tree return IndexBounds(); } invariant(childBounds.size() == bounds.size()); for (size_t i = 0; i < bounds.size(); i++) { bounds.fields[i].intervals.insert(bounds.fields[i].intervals.end(), childBounds.fields[i].intervals.begin(), childBounds.fields[i].intervals.end()); } } for (size_t i = 0; i < bounds.size(); i++) { IndexBoundsBuilder::unionize(&bounds.fields[i]); } return bounds; }
void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range, unsigned int streamOffset) { mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset); }