Exemplo n.º 1
0
PlanCacheKey PlanCache::computeKey(const CanonicalQuery& cq) const {
    StringBuilder keyBuilder;
    encodeKeyForMatch(cq.root(), &keyBuilder);
    encodeKeyForSort(cq.getQueryRequest().getSort(), &keyBuilder);
    encodeKeyForProj(cq.getQueryRequest().getProj(), &keyBuilder);
    return keyBuilder.str();
}
Exemplo n.º 2
0
    /**
     * Traverses expression tree pre-order.
     * Appends an encoding of each node's match type and path name
     * to the output stream.
     */
    void PlanCache::encodeKeyForMatch(const MatchExpression* tree,
                                      StringBuilder* keyBuilder) const {
        // Encode match type and path.
        *keyBuilder << encodeMatchType(tree->matchType());

        encodeUserString(tree->path(), keyBuilder);

        // GEO and GEO_NEAR require additional encoding.
        if (MatchExpression::GEO == tree->matchType()) {
            encodeGeoMatchExpression(static_cast<const GeoMatchExpression*>(tree), keyBuilder);
        }
        else if (MatchExpression::GEO_NEAR == tree->matchType()) {
            encodeGeoNearMatchExpression(static_cast<const GeoNearMatchExpression*>(tree),
                                         keyBuilder);
        }

        // Encode indexability.
        const IndexabilityDiscriminators& discriminators =
            _indexabilityState.getDiscriminators(tree->path());
        if (!discriminators.empty()) {
            *keyBuilder << kEncodeDiscriminatorsBegin;
            // For each discriminator on this path, append the character '0' or '1'.
            for (const IndexabilityDiscriminator& discriminator : discriminators) {
                *keyBuilder << discriminator(tree);
            }
            *keyBuilder << kEncodeDiscriminatorsEnd;
        }

        // Traverse child nodes.
        // Enclose children in [].
        if (tree->numChildren() > 0) {
            *keyBuilder << kEncodeChildrenBegin;
        }
        // Use comma to separate children encoding.
        for (size_t i = 0; i < tree->numChildren(); ++i) {
            if (i > 0) {
                *keyBuilder << kEncodeChildrenSeparator;
            }
            encodeKeyForMatch(tree->getChild(i), keyBuilder);
        }
        if (tree->numChildren() > 0) {
            *keyBuilder << kEncodeChildrenEnd;
        }
    }