///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHSLICEBUILD, "mthSliceBuild" ) INT32 mthSliceBuild( const CHAR *fieldName, const bson::BSONElement &e, _mthSAction *action, bson::BSONObjBuilder &builder ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSLICEBUILD ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; INT32 begin = 0 ; INT32 limit = -1 ; if ( e.eoo() ) { goto done ; } else if ( Array == e.type() ) { action->getSlicePair( begin, limit ) ; _mthSliceIterator i( e.embeddedObject(), begin, limit ) ; BSONArrayBuilder sliceBuilder( builder.subarrayStart( fieldName ) ) ; while ( i.more() ) { sliceBuilder.append( i.next() ) ; } sliceBuilder.doneFast() ; } else { builder.append( e ) ; } done: PD_TRACE_EXITRC( SDB__MTHSLICEBUILD, rc ) ; return rc ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHELEMMATCHONEPARSER_PARSE, "_mthElemMatchOneParser::parse" ) INT32 _mthElemMatchOneParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHELEMMATCHONEPARSER_PARSE ) ; if ( Object != e.type() ) { PD_LOG( PDERROR, "$elemMatch(One) requires object value" ) ; rc = SDB_INVALIDARG ; goto error ; } rc = action.getMatcher().loadPattern( e.embeddedObject() ) ; if ( SDB_OK != rc ) { PD_LOG( PDERROR, "failed to load match pattern:%d", rc ) ; goto error ; } action.setName( _name.c_str() ) ; action.setAttribute( MTH_S_ATTR_PROJECTION ) ; action.setFunc( &mthElemMatchOneBuild, &mthElemMatchOneGet ) ; done: PD_TRACE_EXITRC( SDB__MTHELEMMATCHONEPARSER_PARSE, rc ) ; return rc ; error: goto done ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHELEMMATCHGETN, "mthElemMatchGetN" ) static INT32 mthElemMatchGetN( const CHAR *fieldName, const bson::BSONElement &in, _mthSAction *action, bson::BSONElement &out, INT32 n ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHELEMMATCHGETN ) ; if ( Array == in.type() ) { BSONObjBuilder objBuilder ; BSONArrayBuilder arrayBuilder( objBuilder.subarrayStart( fieldName ) ) ; _mthElemMatchIterator i( in.embeddedObject(), &( action->getMatcher() ), n ) ; do { BSONElement next ; rc = i.next( next ) ; if ( SDB_OK == rc ) { arrayBuilder.append( next ) ; } else if ( SDB_DMS_EOC == rc ) { arrayBuilder.doneFast() ; rc = SDB_OK ; break ; } else { PD_LOG( PDERROR, "failed to get next element:%d", rc ) ; goto error ; } } while ( TRUE ) ; action->setObj( objBuilder.obj() ) ; out = action->getObj().getField( fieldName ) ; } else { out = BSONElement() ; } done: PD_TRACE_EXITRC( SDB__MTHELEMMATCHGETN, rc ) ; return rc ; error: goto done ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHSLICEGET, "mthSliceGet" ) INT32 mthSliceGet( const CHAR *fieldName, const bson::BSONElement &in, _mthSAction *action, bson::BSONElement &out ) { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSLICEGET ) ; SDB_ASSERT( NULL != action, "can not be null" ) ; INT32 begin = 0 ; INT32 limit = -1 ; if ( Array != in.type() ) { out = in ; goto done ; } else if ( Array == in.type() ) { BSONObjBuilder subBuilder ; action->getSlicePair( begin, limit ) ; _mthSliceIterator i( in.embeddedObject(), begin, limit ) ; BSONArrayBuilder sliceBuilder( subBuilder.subarrayStart( fieldName ) ) ; while ( i.more() ) { sliceBuilder.append( i.next() ) ; } sliceBuilder.doneFast() ; action->setObj( subBuilder.obj() ) ; out = action->getObj().getField( fieldName ) ; } done: PD_TRACE_EXITRC( SDB__MTHSLICEGET, rc ) ; return rc ; }
UINT32 _utilBSONHasherObsolete::hash( const bson::BSONElement &e ) { UINT32 hashCode = 0 ; HASH_COMBINE( hashCode, e.canonicalType() ) ; switch( e.type() ) { case EOO: case Undefined: case jstNULL: case MaxKey: case MinKey: break ; case Bool: HASH_COMBINE( hashCode, e.boolean() ) ; break ; case Timestamp: { UINT64 v = e._opTime().asDate() ; UINT32 h = hash( &v, sizeof( v ) ) ; HASH_COMBINE( hashCode, h ) ; } break ; case Date: { UINT64 v = e.date().millis ; UINT32 h = hash( &v, sizeof( v ) ) ; HASH_COMBINE( hashCode, h ) ; } break ; case NumberDouble: case NumberLong: case NumberInt: { FLOAT64 dv = e.Number() ; UINT64 uv = dv ; UINT32 afp = ( dv - uv ) * 1000000 ; UINT32 h1 = 0 ; UINT32 h2 = 0 ; h1 = hash( &uv, sizeof( uv ) ) ; h2 = hash( &afp, sizeof( afp ) ) ; HASH_COMBINE( hashCode, h1 ) ; HASH_COMBINE( hashCode, h2 ) ; break ; } case jstOID: HASH_COMBINE( hashCode, hash( e.OID() ) ) ; break ; case Code: case Symbol: case String: HASH_COMBINE( hashCode, hash( e.valuestrsafe(), e.valuestrsize() - 1 ) ) ; break ; case Object: case Array: HASH_COMBINE( hashCode, hash( e.embeddedObject() ) ) ; break ; case DBRef: case BinData: HASH_COMBINE( hashCode, hash( e.value(), e.valuesize() ) ) ; break ; case RegEx: HASH_COMBINE( hashCode, hash( e.regex() ) ) ; HASH_COMBINE( hashCode, hash( e.regexFlags() ) ) ; break ; case CodeWScope: HASH_COMBINE( hashCode, hash( e.codeWScopeCode() ) ) ; HASH_COMBINE( hashCode, hash( e.codeWScopeObject() ) ) ; break ; } return hashCode ; }
///PD_TRACE_DECLARE_FUNCTION ( SDB__MTHSUBSTRPARSER_PARSE, "_mthSubStrParser::parse" ) INT32 _mthSubStrParser::parse( const bson::BSONElement &e, _mthSAction &action ) const { INT32 rc = SDB_OK ; PD_TRACE_ENTRY( SDB__MTHSUBSTRPARSER_PARSE ) ; INT32 begin = 0 ; INT32 limit = -1 ; #if defined (_DEBUG) if ( 0 != _name.compare( e.fieldName() ) ) { PD_LOG( PDERROR, "field name[%s] is not valid", e.fieldName() ) ; rc = SDB_INVALIDARG ; goto error ; } #endif if ( e.isNumber() && 0 <= e.numberInt()) { limit = e.numberInt() ; } else if ( e.isNumber() ) { begin = e.numberInt() ; } else if ( Array == e.type() ) { BSONObjIterator i( e.embeddedObject() ) ; BSONElement ele ; if ( !i.more() ) { goto invalid_arg ; } ele = i.next() ; if ( !ele.isNumber() ) { goto invalid_arg ; } begin = ele.numberInt() ; if ( !i.more() ) { goto invalid_arg ; } ele = i.next() ; if ( !ele.isNumber() ) { goto invalid_arg ; } limit = ele.numberInt() ; } else { PD_LOG( PDERROR, "invalid element" ) ; rc = SDB_INVALIDARG ; goto error ; } action.setAttribute( MTH_S_ATTR_PROJECTION ) ; action.setFunc( &mthSubStrBuild, &mthSubStrGet ) ; action.setName( _name.c_str() ) ; action.setArg( BSON( "arg1" << begin << "arg2" << limit ) ) ; done: PD_TRACE_EXITRC( SDB__MTHSUBSTRPARSER_PARSE, rc ) ; return rc ; error: goto done ; invalid_arg: PD_LOG( PDERROR, "invalid substr argument:%s", e.toString( TRUE, TRUE ).c_str() ) ; rc = SDB_INVALIDARG ; goto error ; }