int ReservedValue( ListNode *list, char *name) { Sort *pos = SortsHead(list); while( pos != NULL && (strcmp( SortValue(pos), name)) != 0) { pos = SortNext(pos); } return( pos != NULL ); }
Sort *CreateVec_Sec( char *name, char *base, int hasvec, int hassec) { Sort *temp = CreateSort(); SortValue(temp) = heapstr(name); SortBase(temp) = heapstr(base); SortHasvec(temp) = hasvec; SortHassec(temp) = hassec; return(temp); }
void WriteReservedTokens( FILE *outfile, ListNode *list) { int count = 1; Sort *pos = SortsHead(list); while( pos != NULL) { fprintf( outfile, "#define %s %d\n", SortValue(pos), count++); pos = SortNext(pos); } fprintf( outfile, "\n" ); }
Sort *CreateSort() { Sort *sort_node = HEAP(Sort); SortValue(sort_node) = NULL; SortBase(sort_node) = NULL; SortNext(sort_node) = NULL; SortHasvec(sort_node) = 0; SortHassec(sort_node) = 0; return(sort_node); }
void WriteSorts( FILE *initfile, char *prefix, char *postfix, ListNode *reserved, ListNode *sorts ) { Sort *sort_pos = SortsHead( sorts ); char sepchar = '('; int indent, len, lwidth, i; sprintf( buffer, " Sort%d", ListSize( sorts )); indent = strlen( buffer ) + 2; lwidth = indent; fprintf( initfile, "%s", buffer ); if( sort_pos != NULL) { while( sort_pos != NULL) { fprintf( initfile, "%c ", sepchar ); if( reserved != NULL && ReservedValue( reserved, SortValue(sort_pos))) { sprintf( buffer, "%s%s", SortValue(sort_pos), postfix ); } else { sprintf( buffer, "%s%s%s", prefix, SortValue(sort_pos), postfix ); } len = strlen( buffer ) + 2; if( len + lwidth > MAX_LINE_WIDTH ) { fprintf( initfile, "\n" ); for( i = 0; i < indent; i ++ ){ fprintf( initfile, " " ); } lwidth = indent; } fprintf( initfile, "%s", buffer ); lwidth += len; sepchar = ','; sort_pos = SortNext(sort_pos); } fprintf( initfile, "),\n"); } else { fprintf( initfile, "(),\n"); } }
void InitReserved( ListNode *reserved, char *list ) { char *tok; Sort *temp; tok = strtok( list, " " ); while( tok != NULL ) { temp = CreateSort(); SortValue( temp ) = heapstr( tok ); AddToSortList( temp, reserved ); tok = strtok( NULL, " " ); } }
void AddVec_Sec( ListNode *vec_secs, char *name, char *base, int has_vec, int has_sec ) { Sort *pos = SortsHead(vec_secs), *temp; while( pos != NULL && (strcmp( SortValue(pos), name) != 0)) { pos = SortNext(pos); } if( pos == NULL) { temp = CreateVec_Sec( name, base, has_vec, has_sec); AddToSortList( temp, vec_secs ); } }
void WriteVec_SecTokens( FILE *outfile, char *table, ListNode *reserved, ListNode *vec_secs) { Sort *pos = SortsHead(vec_secs); char *init_secondary_str = Initialise(SECONDARY_STR), *init_vector_str = Initialise(VECTOR_STR); while( pos != NULL) { fprintf( outfile, "#define %s_%s ", table, SortValue(pos)); if( SortHassec(pos)) { fprintf( outfile, "%s(", init_secondary_str ); } if( SortHasvec(pos)) { fprintf( outfile, "%s(", init_vector_str ); } if( ReservedValue( reserved, SortBase(pos))) { fprintf( outfile, "%s", SortBase(pos)); } else { fprintf( outfile, "%s_%s", table, SortBase(pos)); } if( SortHasvec(pos)) { fprintf(outfile, ")"); } if( SortHassec(pos)) { fprintf(outfile, ")"); } fprintf( outfile, "\n"); pos = SortNext(pos); } fprintf( outfile, "\n" ); }
int Ardb::Sort(const DBID& db, const Slice& key, const StringArray& args, ValueArray& values) { SortOptions options; if (parse_sort_options(options, args) < 0) { DEBUG_LOG("Failed to parse sort options."); return ERR_INVALID_ARGS; } int type = Type(db, key); ValueArray sortvals; switch (type) { case LIST_META: { LRange(db, key, 0, -1, sortvals); break; } case SET_ELEMENT: { SMembers(db, key, sortvals); break; } case ZSET_ELEMENT_SCORE: { QueryOptions tmp; ZRange(db, key, 0, -1, sortvals, tmp); if(NULL == options.by) { options.nosort = true; } break; } default: { return ERR_INVALID_TYPE; } } if (sortvals.empty()) { return 0; } if (options.with_limit) { if (options.limit_offset < 0) { options.limit_offset = 0; } if ((uint32) options.limit_offset > sortvals.size()) { values.clear(); return 0; } if (options.limit_count < 0) { options.limit_count = sortvals.size(); } } std::vector<SortValue> sortvec; if (!options.nosort) { if (NULL != options.by) { sortvec.reserve(sortvals.size()); } for (uint32 i = 0; i < sortvals.size(); i++) { if (NULL != options.by) { sortvec.push_back(SortValue(&sortvals[i])); if (GetValueByPattern(db, options.by, sortvals[i], sortvec[i].cmp) < 0) { DEBUG_LOG("Failed to get value by pattern:%s", options.by); sortvec[i].cmp.Clear(); continue; } } if (options.with_alpha) { if (NULL != options.by) { value_convert_to_raw(sortvec[i].cmp); } else { value_convert_to_raw(sortvals[i]); } } else { if (NULL != options.by) { value_convert_to_number(sortvec[i].cmp); } else { value_convert_to_number(sortvals[i]); } } } if (NULL != options.by) { if (!options.is_desc) { std::sort(sortvec.begin(), sortvec.end(), less_value<SortValue>); } else { std::sort(sortvec.begin(), sortvec.end(), greater_value<SortValue>); } } else { if (!options.is_desc) { std::sort(sortvals.begin(), sortvals.end(), less_value<ValueObject>); } else { std::sort(sortvals.begin(), sortvals.end(), greater_value<ValueObject>); } } } if (!options.with_limit) { options.limit_offset = 0; options.limit_count = sortvals.size(); } uint32 count = 0; for (uint32 i = options.limit_offset; i < sortvals.size() && count < (uint32) options.limit_count; i++, count++) { ValueObject* patternObj = NULL; if (NULL != options.by) { patternObj = sortvec[i].value; } else { patternObj = &(sortvals[i]); } if (options.get_patterns.empty()) { values.push_back(*patternObj); } else { for (uint32 j = 0; j < options.get_patterns.size(); j++) { ValueObject vo; if (GetValueByPattern(db, options.get_patterns[j], *patternObj, vo) < 0) { DEBUG_LOG("Failed to get value by pattern for:%s", options.get_patterns[j]); vo.Clear(); } values.push_back(vo); } } } if (options.store_dst != NULL && !values.empty()) { BatchWriteGuard guard(GetEngine()); LClear(db, options.store_dst); ValueArray::iterator it = values.begin(); uint64 score = 0; while (it != values.end()) { if (it->type != EMPTY) { ListKeyObject lk(options.store_dst, score, db); SetValue(lk, *it); score++; } it++; } ListMetaValue meta; meta.min_score = 0; meta.max_score = (score - 1); meta.size = score; SetListMetaValue(db, options.store_dst, meta); } return 0; }
void AddUnionSort( Structs *structure, char *sort) { Sort *temp = CreateSort(); SortValue(temp) = sort; AddToSortList( temp, StructUnion_sorts(structure) ); }
void AddChildrenName( Structs *structure, char *name) { Sort *temp = CreateSort(); SortValue(temp) = heapstr(name); AddToSortList( temp, StructChildren_names(structure) ); }
void AddChildrenSort( Structs *structure, char *sort) { Sort *temp = CreateSort(); SortValue(temp) = Capitalise(sort); AddToSortList( temp, StructChildren_sorts(structure) ); }
int Ardb::SortCommand(Context& ctx, const Slice& key, SortOptions& options, DataArray& values) { values.clear(); KeyType keytype = KEY_END; GetType(ctx, key, keytype); switch (keytype) { case LIST_META: { ListRange(ctx, key, 0, -1); break; } case SET_META: { SetMembers(ctx, key); break; } case ZSET_META: { ZSetRange(ctx, key, 0, -1, false, false, OP_GET); if (NULL == options.by) { options.nosort = true; } break; } default: { return ERR_INVALID_TYPE; } } DataArray sortvals; if (ctx.reply.MemberSize() > 0) { for (uint32 i = 0; i < ctx.reply.MemberSize(); i++) { Data v; v.SetString(ctx.reply.MemberAt(i).str, true); sortvals.push_back(v); } } if (sortvals.empty()) { return 0; } if (options.with_limit) { if (options.limit_offset < 0) { options.limit_offset = 0; } if ((uint32) options.limit_offset > sortvals.size()) { values.clear(); return 0; } if (options.limit_count < 0) { options.limit_count = sortvals.size(); } } std::vector<SortValue> sortvec; if (!options.nosort) { if (NULL != options.by) { sortvec.reserve(sortvals.size()); } for (uint32 i = 0; i < sortvals.size(); i++) { if (NULL != options.by) { sortvec.push_back(SortValue(&sortvals[i])); if (GetValueByPattern(ctx, options.by, sortvals[i], sortvec[i].cmp) < 0) { DEBUG_LOG("Failed to get value by pattern:%s", options.by); sortvec[i].cmp.Clear(); continue; } } if (options.with_alpha) { if (NULL != options.by) { sortvec[i].cmp.ToString(); } else { sortvals[i].ToString(); } } } if (NULL != options.by) { if (!options.is_desc) { std::sort(sortvec.begin(), sortvec.end(), less_value<SortValue>); } else { std::sort(sortvec.begin(), sortvec.end(), greater_value<SortValue>); } } else { if (!options.is_desc) { std::sort(sortvals.begin(), sortvals.end(), less_value<Data>); } else { std::sort(sortvals.begin(), sortvals.end(), greater_value<Data>); } } } if (!options.with_limit) { options.limit_offset = 0; options.limit_count = sortvals.size(); } uint32 count = 0; for (uint32 i = options.limit_offset; i < sortvals.size() && count < (uint32) options.limit_count; i++, count++) { Data* patternObj = NULL; if (NULL != options.by) { patternObj = sortvec[i].value; } else { patternObj = &(sortvals[i]); } if (options.get_patterns.empty()) { values.push_back(*patternObj); } else { for (uint32 j = 0; j < options.get_patterns.size(); j++) { Data vo; if (GetValueByPattern(ctx, options.get_patterns[j], *patternObj, vo) < 0) { DEBUG_LOG("Failed to get value by pattern for:%s", options.get_patterns[j]); vo.Clear(); } values.push_back(vo); } } } uint32 step = options.get_patterns.empty() ? 1 : options.get_patterns.size(); switch (options.aggregate) { case AGGREGATE_SUM: case AGGREGATE_AVG: { DataArray result; result.resize(step); for (uint32 i = 0; i < result.size(); i++) { for (uint32 j = i; j < values.size(); j += step) { result[i].IncrBy(values[j]); } } if (options.aggregate == AGGREGATE_AVG) { size_t count = values.size() / step; for (uint32 i = 0; i < result.size(); i++) { result[i].SetDouble(result[i].NumberValue() / count); } } values.assign(result.begin(), result.end()); break; } case AGGREGATE_MAX: case AGGREGATE_MIN: { DataArray result; result.resize(step); for (uint32 i = 0; i < result.size(); i++) { for (uint32 j = i; j < values.size(); j += step) { if (result[i].IsNil()) { result[i] = values[j]; } else { if (options.aggregate == AGGREGATE_MIN) { if (values[j] < result[i]) { result[i] = values[j]; } } else { if (values[j] > result[i]) { result[i] = values[j]; } } } } } values.assign(result.begin(), result.end()); break; } case AGGREGATE_COUNT: { size_t size = values.size() / step; values.clear(); Data v; v.SetInt64(size); values.push_back(v); break; } default: { break; } } if (options.store_dst != NULL && !values.empty()) { DeleteKey(ctx, options.store_dst); ValueObject list_meta; list_meta.key.key = options.store_dst; list_meta.key.type = KEY_META; list_meta.key.db = ctx.currentDB; list_meta.type = LIST_META; list_meta.meta.SetEncoding(COLLECTION_ECODING_ZIPLIST); BatchWriteGuard guard(GetKeyValueEngine()); DataArray::iterator it = values.begin(); while (it != values.end()) { if (!it->IsNil()) { std::string tmp; it->GetDecodeString(tmp); ListInsert(ctx, list_meta, NULL, tmp, false, false); } it++; } SetKeyValue(ctx, list_meta); } return 0; }