size_t
UTF8SuffixStringFieldSearcher::matchTerms(const FieldRef & f, const size_t mintsz)
{
    (void) mintsz;
    termcount_t words = 0;
    const byte * srcbuf = reinterpret_cast<const byte *> (f.data());
    const byte * srcend = srcbuf + f.size();
    if (f.size() >= _buf->size()) {
        _buf->reserve(f.size() + 1);
    }
    cmptype_t * dstbuf = &(*_buf.get())[0];
    size_t tokenlen = 0;

    for( ; srcbuf < srcend; ) {
        if (*srcbuf == 0) {
            ++_zeroCount;
            ++srcbuf;
        }
        srcbuf = tokenize(srcbuf, _buf->capacity(), dstbuf, tokenlen);
        for (QueryTermList::iterator it = _qtl.begin(), mt = _qtl.end(); it != mt; ++it) {
            QueryTerm & qt = **it;
            const cmptype_t * term;
            termsize_t tsz = qt.term(term);
            if (matchTermSuffix(term, tsz, dstbuf, tokenlen)) {
                addHit(qt, words);
            }
        }
        words++;
    }
    return words;
}
示例#2
0
    bool AllMatchExpression::matches( const BSONObj& doc, MatchDetails* details ) const {
        FieldRef path;
        path.parse(_path);

        bool traversedArray = false;
        int32_t idxPath = 0;
        BSONElement e = getFieldDottedOrArray( doc, path, &idxPath, &traversedArray );

        string rest = pathToString( path, idxPath+1 );

        if ( e.type() != Array || traversedArray || rest.size() == 0 ) {
            return matchesSingleElement( e );
        }

        BSONElementSet all;

        BSONObjIterator i( e.Obj() );
        while ( i.more() ) {
            BSONElement e = i.next();
            if ( ! e.isABSONObj() )
                continue;

            e.Obj().getFieldsDotted( rest, all );
        }

        return _match( all );
    }
size_t
UTF8StrChrFieldSearcher::matchTerms(const FieldRef & f, const size_t mintsz)
{
    (void) mintsz;
    termcount_t words(0);
    const byte * n = reinterpret_cast<const byte *> (f.data());
    const byte * e = n + f.size();
    if (f.size() >= _buf->size()) {
        _buf->reserve(f.size() + 1);
    }
    cmptype_t * fn = &(*_buf.get())[0];
    size_t fl(0);

    for( ; n < e; ) {
        if (!*n) { _zeroCount++; n++; }
        n = tokenize(n, _buf->capacity(), fn, fl);
        for(QueryTermList::iterator it=_qtl.begin(), mt=_qtl.end(); it != mt; it++) {
            QueryTerm & qt = **it;
            const cmptype_t * term;
            termsize_t tsz = qt.term(term);
            if ((tsz <= fl) && (prefix() || qt.isPrefix() || (tsz == fl))) {
                const cmptype_t *tt=term, *et=term+tsz;
                for (const cmptype_t *fnt=fn; (tt < et) && (*tt == *fnt); tt++, fnt++);
                if (tt == et) {
                    addHit(qt, words);
                }
            }
        }
        words++;
    }
    NEED_CHAR_STAT(addAnyUtf8Field(f.size()));
    return words;
}
示例#4
0
TEST(System, gemv_blocked_scaled_diagonal) {
  Set points;
  FieldRef<simit_float,2> b = points.addField<simit_float,2>("b");
  FieldRef<simit_float,2> c = points.addField<simit_float,2>("c");
  FieldRef<simit_float,2> a = points.addField<simit_float,2>("a");

  ElementRef p0 = points.add();
  ElementRef p1 = points.add();
  ElementRef p2 = points.add();

  a.set(p0, {1.0, 2.0});
  a.set(p1, {3.0, 4.0});
  a.set(p2, {5.0, 6.0});

  b.set(p0, {1.0, 1.0});
  b.set(p1, {1.0, 1.0});
  b.set(p2, {1.0, 1.0});

  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();
  func.bind("points", &points);
  func.runSafe();

  ASSERT_EQ(30.0,  c.get(p0)(0));
  ASSERT_EQ(60.0,  c.get(p0)(1));

  ASSERT_EQ(210.0, c.get(p1)(0));
  ASSERT_EQ(280.0, c.get(p1)(1));

  ASSERT_EQ(550.0, c.get(p2)(0));
  ASSERT_EQ(660.0, c.get(p2)(1));
}
示例#5
0
TEST(System, vector_dot_intrinsic) {
  Set points;
  FieldRef<simit_float> x = points.addField<simit_float>("x");
  FieldRef<simit_float> z = points.addField<simit_float>("z");

  ElementRef p0 = points.add();
  ElementRef p1 = points.add();
  ElementRef p2 = points.add();
  ElementRef p3 = points.add();
  ElementRef p4 = points.add();
  ElementRef p5 = points.add();
  ElementRef p6 = points.add();
  ElementRef p7 = points.add();
  ElementRef p8 = points.add();
  ElementRef p9 = points.add();
  ElementRef p10 = points.add();
  x.set(p0, 1.0);
  x.set(p1, 2.0);
  x.set(p2, 3.0);
  x.set(p3, 4.0);
  x.set(p4, 5.0);
  x.set(p5, 6.0);
  x.set(p6, 7.0);
  x.set(p7, 8.0);
  x.set(p8, 9.0);
  x.set(p9, 10.0);
  x.set(p10, 11.0);

  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();
  func.bind("points", &points);

  func.runSafe();
  SIMIT_EXPECT_FLOAT_EQ(506.0, (int)z.get(p0));
}
示例#6
0
Status setElementAtPath(const FieldRef& path,
                        const BSONElement& value,
                        mutablebson::Document* doc) {
    size_t deepestElemPathPart;
    mutablebson::Element deepestElem(doc->end());

    // Get the existing parents of this path
    Status status = findLongestPrefix(path, doc->root(), &deepestElemPathPart, &deepestElem);

    // TODO: All this is pretty awkward, why not return the position immediately after the
    // consumed path or use a signed sentinel?  Why is it a special case when we've consumed the
    // whole path?

    if (!status.isOK() && status.code() != ErrorCodes::NonExistentPath)
        return status;

    // Inc the path by one *unless* we matched nothing
    if (status.code() != ErrorCodes::NonExistentPath) {
        ++deepestElemPathPart;
    } else {
        deepestElemPathPart = 0;
        deepestElem = doc->root();
    }

    if (deepestElemPathPart == path.numParts()) {
        // The full path exists already in the document, so just set a value
        return deepestElem.setValueBSONElement(value);
    } else {
        // Construct the rest of the path we need with empty documents and set the value
        StringData leafFieldName = path.getPart(path.numParts() - 1);
        mutablebson::Element leafElem = doc->makeElementWithNewFieldName(leafFieldName, value);
        dassert(leafElem.ok());
        return createPathAt(path, deepestElemPathPart, deepestElem, leafElem);
    }
}
示例#7
0
void NurbsCurveEmitter::Fill(const FieldRef& field)
{
	MFnNurbsCurve curve(mObject);

	// Get the range for U and V.
	MPlug minValuePlug = curve.findPlug("minValue");
	MPlug maxValuePlug = curve.findPlug("maxValue");

	const Double minValue = minValuePlug.asDouble();
	const Double maxValue = maxValuePlug.asDouble();

	const Double valueRange = maxValue - minValue;

	int i = 0;
	for (i = 0; i < static_cast<int>(mSample); ++ i)
	{
		double u = Stokes::Random::NextAsDouble();
		double v = Stokes::Random::NextAsDouble();
		double w = Stokes::Random::NextAsDouble();

		double param = u * valueRange + minValue;

		MPoint p;
		curve.getPointAtParam(param, p, MSpace::kWorld);
		MVector t = curve.tangent(param, MSpace::kWorld);
		t.normalize();
		MVector n = curve.normal(param, MSpace::kWorld);
		n.normalize();
		MVector b = n ^ t;

		double r = sqrt(v);
		double phi = w * 2.0 * M_PI;
		double x = r * cos(phi);
		double y = r * sin(phi);

		// TODO: No radius here.
		MPoint newP = p + n * x + b * y;

		MVector radialDirection = newP - p;
		radialDirection.normalize();
		
		Stokes::Vectorf noisedPoint(Random::NextAsFloat() * mScale.x - mOffset.x, Random::NextAsFloat() * mScale.y - mOffset.y, static_cast<Float>(u) * mScale.z - mOffset.z);
		Float displacement = Stokes::Noiser::FractalBrownianMotion(noisedPoint, mDisplacedH, mDisplacedLacunarity, mDisplacedOctave) * mDisplacedAmplitude;
		MPoint displacedP = newP + radialDirection * displacement;
		Stokes::Vectorf worldPoint(static_cast<Stokes::Float>(displacedP.x), static_cast<Stokes::Float>(displacedP.y), static_cast<Stokes::Float>(displacedP.z));

		Stokes::Vectoriu index;
		if (field->CalculateIndexFromWorldPoint(worldPoint, index))
		{
			Float density = Stokes::Noiser::FractalBrownianMotion(noisedPoint, mH, mLacunarity, mOctave) * mAmplitude;
			if (density > 0)
			{
				field->Access(index)[0] += density;
			}
		}
	}
}
示例#8
0
bool hasArrayFilter(const FieldRef& fieldRef) {
    auto size = fieldRef.numParts();
    for (size_t i = 0; i < size; i++) {
        auto fieldPart = fieldRef.getPart(i);
        if (isArrayFilterIdentifier(fieldPart)) {
            return true;
        }
    }
    return false;
}
示例#9
0
文件: path.cpp 项目: i80and/mongo
void BSONElementIterator::ArrayIterationState::reset(const FieldRef& ref, int start) {
    restOfPath = ref.dottedField(start).toString();
    hasMore = restOfPath.size() > 0;
    if (hasMore) {
        nextPieceOfPath = ref.getPart(start);
        nextPieceOfPathIsNumber = isAllDigits(nextPieceOfPath);
    } else {
        nextPieceOfPathIsNumber = false;
    }
}
示例#10
0
    Status UpdateDriver::createFromQuery(const BSONObj& query, mutablebson::Document& doc) {
        BSONObjIteratorSorted i(query);
        while (i.more()) {
            BSONElement e = i.next();
            // TODO: get this logic/exclude-list from the query system?
            if (e.fieldName()[0] == '$' || e.fieldNameStringData() == "_id")
                continue;


            if (e.type() == Object && e.embeddedObject().firstElementFieldName()[0] == '$') {
                // we have something like { x : { $gt : 5 } }
                // this can be a query piece
                // or can be a dbref or something

                int op = e.embeddedObject().firstElement().getGtLtOp();
                if (op > 0) {
                    // This means this is a $gt type filter, so don't make it part of the new
                    // object.
                    continue;
                }

                if (mongoutils::str::equals(e.embeddedObject().firstElement().fieldName(),
                                              "$not")) {
                    // A $not filter operator is not detected in getGtLtOp() and should not
                    // become part of the new object.
                    continue;
                }
            }

            // Add to the field to doc after expanding and checking for conflicts.
            FieldRef elemName;
            const StringData& elemNameSD(e.fieldNameStringData());
            elemName.parse(elemNameSD);

            size_t pos;
            mutablebson::Element* elemFound = NULL;

            Status status = pathsupport::findLongestPrefix(elemName, doc.root(), &pos, elemFound);
            // Not NonExistentPath, of OK, return
            if (!(status.code() == ErrorCodes::NonExistentPath || status.isOK()))
                return status;

            status = pathsupport::createPathAt(elemName,
                                               0,
                                               doc.root(),
                                               doc.makeElementWithNewFieldName(
                                                       elemName.getPart(elemName.numParts()-1),
                                                       e));
            if (!status.isOK())
                return status;
        }
        return Status::OK();
    }
示例#11
0
TEST(System, gemv_blocked_nw) {
  // Points
  Set points;
  FieldRef<simit_float,2> b = points.addField<simit_float,2>("b");
  FieldRef<simit_float,2> c = points.addField<simit_float,2>("c");

  ElementRef p0 = points.add();
  ElementRef p1 = points.add();
  ElementRef p2 = points.add();

  b.set(p0, {1.0, 2.0});
  b.set(p1, {3.0, 4.0});
  b.set(p2, {5.0, 6.0});

  // Taint c
  c.set(p0, {42.0, 42.0});
  c.set(p2, {42.0, 42.0});

  // Springs
  Set springs(points,points);
  FieldRef<simit_float,2,2> a = springs.addField<simit_float,2,2>("a");

  ElementRef s0 = springs.add(p0,p1);
  ElementRef s1 = springs.add(p1,p2);

  a.set(s0, {1.0, 2.0, 3.0, 4.0});
  a.set(s1, {5.0, 6.0, 7.0, 8.0});

  // Compile program and bind arguments
  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();

  func.bind("points", &points);
  func.bind("springs", &springs);

  func.runSafe();

  // Check that outputs are correct
  // TODO: add support for comparing a tensorref like so: b0 == {1.0, 2.0, 3.0}
  TensorRef<simit_float,2> c0 = c.get(p0);
  ASSERT_EQ(5.0, c0(0));
  ASSERT_EQ(11.0, c0(1));

  TensorRef<simit_float,2> c1 = c.get(p1);
  ASSERT_EQ(39.0, c1(0));
  ASSERT_EQ(53.0, c1(1));

  TensorRef<simit_float,2> c2 = c.get(p2);
  ASSERT_EQ(0.0, c2(0));
  ASSERT_EQ(0.0, c2(1));
}
示例#12
0
/**
 * Helper function to check if path conflicts are all prefixes.
 */
static Status checkPathIsPrefixOf(const FieldRef& path, const FieldRefSet& conflictPaths) {
    for (FieldRefSet::const_iterator it = conflictPaths.begin(); it != conflictPaths.end(); ++it) {
        const FieldRef* conflictingPath = *it;
        // Conflicts are always prefixes (or equal to) the path, or vice versa
        if (path.numParts() > conflictingPath->numParts()) {
            string errMsg = stream() << "field at '" << conflictingPath->dottedField()
                                     << "' must be exactly specified, field at sub-path '"
                                     << path.dottedField() << "'found";
            return Status(ErrorCodes::NotExactValueField, errMsg);
        }
    }

    return Status::OK();
}
示例#13
0
static BSONElement findEqualityElement(const EqualityMatches& equalities, const FieldRef& path) {
    int parentPathPart;
    const BSONElement& parentEl =
        pathsupport::findParentEqualityElement(equalities, path, &parentPathPart);

    if (parentPathPart == static_cast<int>(path.numParts()))
        return parentEl;

    if (parentEl.type() != Object)
        return BSONElement();

    StringData suffixStr = path.dottedSubstring(parentPathPart, path.numParts());
    BSONMatchableDocument matchable(parentEl.Obj());
    return extractKeyElementFromMatchable(matchable, suffixStr);
}
示例#14
0
TEST(System, vector_add) {
  Set points;
  FieldRef<simit_float> x = points.addField<simit_float>("x");

  ElementRef p0 = points.add();
  x.set(p0, 42.0);

  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();
  func.bind("points", &points);

  func.runSafe();

  SIMIT_EXPECT_FLOAT_EQ(84.0, (int)x.get(p0));
}
示例#15
0
 Status basicIsUpdatable(const FieldRef& field) {
     StringData firstPart = field.getPart(0);
     if (firstPart.compare("_id") == 0) {
         return Status(ErrorCodes::BadValue, "updated cannot affect the _id");
     }
     return Status::OK();
 }
示例#16
0
    bool LeafMatchExpression::matches( const BSONObj& doc, MatchDetails* details ) const {
        //log() << "e doc: " << doc << " path: " << _path << std::endl;

        FieldRef path;
        path.parse(_path);

        bool traversedArray = false;
        int32_t idxPath = 0;
        BSONElement e = getFieldDottedOrArray( doc, path, &idxPath, &traversedArray );

        string rest = pathToString( path, idxPath+1 );

        if ( e.type() != Array || traversedArray ) {
            return matchesSingleElement( e );
        }

        BSONObjIterator i( e.Obj() );
        while ( i.more() ) {
            BSONElement x = i.next();
            bool found = false;
            if ( rest.size() == 0 ) {
                found = matchesSingleElement( x );
            }
            else if ( x.isABSONObj() ) {
                BSONElement y = x.Obj().getField( rest );
                found = matchesSingleElement( y );
            }

            if ( found ) {
                if ( !_allHaveToMatch ) {
                    if ( details && details->needRecord() ) {
                        // this block doesn't have to be inside the _allHaveToMatch handler
                        // but this matches the old semantics
                        details->setElemMatchKey( x.fieldName() );
                    }
                    return true;
                }
            }
            else if ( _allHaveToMatch ) {
                return false;
            }
        }

        return matchesSingleElement( e );
    }
示例#17
0
bool isPositional(const FieldRef& fieldRef, size_t* pos, size_t* count) {
    // 'count' is optional.
    size_t dummy;
    if (count == NULL) {
        count = &dummy;
    }

    *count = 0;
    size_t size = fieldRef.numParts();
    for (size_t i = 0; i < size; i++) {
        StringData fieldPart = fieldRef.getPart(i);
        if ((fieldPart.size() == 1) && (fieldPart[0] == '$')) {
            if (*count == 0)
                *pos = i;
            (*count)++;
        }
    }
    return *count > 0;
}
示例#18
0
TEST(System, vector_dot_blocked) {
  Set points;
  FieldRef<simit_float,3> x = points.addField<simit_float,3>("x");
  FieldRef<simit_float> z = points.addField<simit_float>("z");

  ElementRef p0 = points.add();
  ElementRef p1 = points.add();
  ElementRef p2 = points.add();
  x.set(p0, {1.0,2.0,3.0});
  x.set(p1, {4.0,5.0,6.0});
  x.set(p2, {7.0,8.0,9.0});

  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();
  func.bind("points", &points);

  func.runSafe();
  SIMIT_EXPECT_FLOAT_EQ(285.0, (simit_float)z.get(p0));
}
int FieldRef::compare(const FieldRef& other) const {
    const size_t toCompare = std::min(_size, other._size);
    for (size_t i = 0; i < toCompare; i++) {
        if (getPart(i) == other.getPart(i)) {
            continue;
        }
        return getPart(i) < other.getPart(i) ? -1 : 1;
    }

    const size_t rest = _size - toCompare;
    const size_t otherRest = other._size - toCompare;
    if ((rest == 0) && (otherRest == 0)) {
        return 0;
    } else if (rest < otherRest) {
        return -1;
    } else {
        return 1;
    }
}
示例#20
0
    BSONElement getFieldDottedOrArray( const BSONObj& doc,
                                       const FieldRef& path,
                                       size_t* idxPath ) {
        if ( path.numParts() == 0 )
            return doc.getField( "" );

        BSONElement res;

        BSONObj curr = doc;
        bool stop = false;
        size_t partNum = 0;
        while ( partNum < path.numParts() && !stop ) {

            res = curr.getField( path.getPart( partNum ) );

            switch ( res.type() ) {

            case EOO:
                stop = true;
                break;

            case Object:
                curr = res.Obj();
                ++partNum;
                break;

            case Array:
                stop = true;
                break;

            default:
                if ( partNum+1 < path.numParts() ) {
                    res = BSONElement();
                }
                stop = true;

            }
        }

        *idxPath = partNum;
        return res;
    }
示例#21
0
TEST(System, vector_add_large_system) {
  Set points;
  FieldRef<simit_float> x = points.addField<simit_float>("x");

  std::vector<ElementRef> ps;
  for(size_t i = 0; i < 2557; ++i) {
    ps.push_back(points.add());
    x.set(ps.back(), (simit_float)i);
  }

  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();
  func.bind("points", &points);

  func.runSafe();

  for(size_t i = 0; i < ps.size(); ++i) {
    SIMIT_EXPECT_FLOAT_EQ(i*2, (size_t)x.get(ps[i]));
  }
}
示例#22
0
Status isUpdatable(const FieldRef& field) {
    const size_t numParts = field.numParts();

    if (numParts == 0) {
        return Status(ErrorCodes::EmptyFieldName, "An empty update path is not valid.");
    }

    for (size_t i = 0; i != numParts; ++i) {
        const StringData part = field.getPart(i);

        if (part.empty()) {
            return Status(ErrorCodes::EmptyFieldName,
                          mongolutils::str::stream()
                              << "The update path '" << field.dottedField()
                              << "' contains an empty field name, which is not allowed.");
        }
    }

    return Status::OK();
}
示例#23
0
TEST(System, vector_assign_blocked) {
  Set points;
  FieldRef<simit_float,2> x = points.addField<simit_float,2>("x");

  ElementRef p0 = points.add();
  ElementRef p1 = points.add();
  x.set(p0, {1.0, 2.0});
  x.set(p1, {3.0, 4.0});

  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();
  func.bind("points", &points);

  func.runSafe();

  SIMIT_EXPECT_FLOAT_EQ(2.0, x.get(p0)(0));
  SIMIT_EXPECT_FLOAT_EQ(4.0, x.get(p0)(1));
  SIMIT_EXPECT_FLOAT_EQ(6.0, x.get(p1)(0));
  SIMIT_EXPECT_FLOAT_EQ(8.0, x.get(p1)(1));
}
示例#24
0
    bool ArrayMatchingMatchExpression::matches( const BSONObj& doc, MatchDetails* details ) const {

        FieldRef path;
        path.parse(_path);

        bool traversedArray = false;
        int32_t idxPath = 0;
        BSONElement e = getFieldDottedOrArray( doc, path, &idxPath, &traversedArray );

        string rest = pathToString( path, idxPath+1 );

        if ( rest.size() == 0 ) {
            if ( e.type() == Array )
                return matchesArray( e.Obj(), details );
            return false;
        }

        if ( e.type() != Array )
            return false;

        BSONObjIterator i( e.Obj() );
        while ( i.more() ) {
            BSONElement x = i.next();
            if ( ! x.isABSONObj() )
                continue;

            BSONElement sub = x.Obj().getFieldDotted( rest );
            if ( sub.type() != Array )
                continue;

            if ( matchesArray( sub.Obj(), NULL ) ) {
                if ( details && details->needRecord() ) {
                    // trying to match crazy semantics??
                    details->setElemMatchKey( x.fieldName() );
                }
                return true;
            }
        }

        return false;
    }
示例#25
0
    bool TypeMatchExpression::_matches( const StringData& path,
                                        const MatchableDocument* doc,
                                        MatchDetails* details ) const {

        FieldRef fieldRef;
        fieldRef.parse( path );

        bool traversedArray = false;
        size_t idxPath = 0;
        BSONElement e = doc->getFieldDottedOrArray( fieldRef, &idxPath, &traversedArray );

        string rest = fieldRef.dottedField( idxPath + 1 );

        if ( e.type() != Array ) {
            return matchesSingleElement( e );
        }

        BSONObjIterator i( e.Obj() );
        while ( i.more() ) {
            BSONElement x = i.next();
            bool found = false;
            if ( rest.size() == 0 ) {
                found = matchesSingleElement( x );
            }
            else if ( x.isABSONObj() ) {
                BSONMatchableDocument doc( x.Obj() );
                found = _matches( rest, &doc, details );
            }

            if ( found ) {
                if ( details && details->needRecord() ) {
                    // this block doesn't have to be inside the _allHaveToMatch handler
                    // but this matches the old semantics
                    details->setElemMatchKey( x.fieldName() );
                }
                return true;
            }
        }

        return false;
    }
示例#26
0
TEST(System, gemv_assemble_from_points) {
  // Points
  Set points;
  FieldRef<simit_float> a = points.addField<simit_float>("a");
  FieldRef<simit_float> b = points.addField<simit_float>("b");
  FieldRef<simit_float> c = points.addField<simit_float>("c");

  ElementRef p0 = points.add();
  ElementRef p1 = points.add();
  ElementRef p2 = points.add();

  b.set(p0, 1.0);
  b.set(p1, 2.0);
  b.set(p2, 3.0);

  a.set(p0, 1.0);
  a.set(p1, 2.0);
  a.set(p2, 3.0);

  c.set(p0, 42.0);

  // Springs
  Set springs(points,points);

  springs.add(p0,p1);
  springs.add(p1,p2);

  // Compile program and bind arguments
  Function func = loadFunction(TEST_FILE_NAME, "main");
  if (!func.defined()) FAIL();

  func.bind("points", &points);
  func.bind("springs", &springs);

  func.runSafe();

  // Check that outputs are correct
  ASSERT_EQ(1.0, c.get(p0));
  ASSERT_EQ(4.0, c.get(p1));
  ASSERT_EQ(0.0, c.get(p2));
}
示例#27
0
    void FieldRefSet::getConflicts(const FieldRef* toCheck, FieldRefSet* conflicts) const {

        // If the set is empty, there is no work to do.
        if (_fieldSet.empty())
            return;

        StringData prefixStr = safeFirstPart(toCheck);
        FieldRef prefixField;
        prefixField.parse(prefixStr);

        FieldSet::iterator it = _fieldSet.lower_bound(&prefixField);
        // Now, iterate over all the present fields in the set that have the same prefix.

        while (it != _fieldSet.end() && safeFirstPart(*it) == prefixStr) {
            size_t common = (*it)->commonPrefixSize(*toCheck);
            if ((*it)->numParts() == common || toCheck->numParts() == common) {
                conflicts->_fieldSet.insert(*it);
            }
            ++it;
        }
    }
示例#28
0
/**
 * Helper function to check if the current equality match paths conflict with a new path.
 */
static Status checkEqualityConflicts(const EqualityMatches& equalities, const FieldRef& path) {
    int parentPathPart = -1;
    const BSONElement& parentEl = findParentEqualityElement(equalities, path, &parentPathPart);

    if (parentEl.eoo())
        return Status::OK();

    string errMsg = "cannot infer query fields to set, ";

    StringData pathStr = path.dottedField();
    StringData prefixStr = path.dottedSubstring(0, parentPathPart);
    StringData suffixStr = path.dottedSubstring(parentPathPart, path.numParts());

    if (suffixStr.size() != 0)
        errMsg += stream() << "both paths '" << pathStr << "' and '" << prefixStr
                           << "' are matched";
    else
        errMsg += stream() << "path '" << pathStr << "' is matched twice";

    return Status(ErrorCodes::NotSingleValueField, errMsg);
}
FieldRef UpdateIndexData::getCanonicalIndexField(const FieldRef& path) {
    if (path.numParts() <= 1)
        return path;

    // The first part of the path must always be a valid field name, since it's not possible to
    // store a top-level array or '$' field name in a document.
    FieldRef buf(path.getPart(0));
    for (size_t i = 1; i < path.numParts(); ++i) {
        auto pathComponent = path.getPart(i);

        if (pathComponent == "$"_sd) {
            continue;
        }

        if (FieldRef::isNumericPathComponentLenient(pathComponent)) {
            // Peek ahead to see if the next component is also all digits. This implies that the
            // update is attempting to create a numeric field name which would violate the
            // "ambiguous field name in array" constraint for multi-key indexes. Break early in this
            // case and conservatively return that this path affects the prefix of the consecutive
            // numerical path components. For instance, an input such as 'a.0.1.b.c' would return
            // the canonical index path of 'a'.
            if ((i + 1) < path.numParts() &&
                FieldRef::isNumericPathComponentLenient(path.getPart(i + 1))) {
                break;
            }
            continue;
        }

        buf.appendPart(pathComponent);
    }

    return buf;
}
示例#30
0
    bool FieldRefSet::insert(const FieldRef* toInsert, const FieldRef** conflict) {

        // We can determine if two fields conflict by checking their common prefix.
        //
        // If each field is exactly of the size of the common prefix, this means the fields are
        // the same. If one of the fields is greater than the common prefix and the other
        // isn't, the latter is a prefix of the former. And vice-versa.
        //
        // Example:
        //
        // inserted >      |    a          a.c
        // exiting  v      |   (0)        (+1)
        // ----------------|------------------------
        //      a (0)      |  equal      prefix <
        //      a.b (+1)   | prefix ^      *
        //
        // * Disjoint sub-trees

        // At each insertion, we only need to bother checking the fields in the set that have
        // at least some common prefix with the 'toInsert' field.
        StringData  prefixStr = safeFirstPart(toInsert);
        FieldRef prefixField;
        prefixField.parse(prefixStr);
        FieldSet::iterator it = _fieldSet.lower_bound(&prefixField);

        // Now, iterate over all the present fields in the set that have the same prefix.
        while (it != _fieldSet.end() && safeFirstPart(*it) == prefixStr) {
            size_t common = (*it)->commonPrefixSize(*toInsert);
            if ((*it)->numParts() == common || toInsert->numParts() == common) {
                *conflict = *it;
                return false;
            }
            ++it;
        }

        _fieldSet.insert(it, toInsert);
        *conflict = NULL;
        return true;
    }