コード例 #1
0
ファイル: zset_testcase.cpp プロジェクト: rchunping/ardb
void test_zsets_union(Ardb& db)
{
    DBID dbid = 0;
    db.ZClear(dbid, "myzset1");
    db.ZClear(dbid, "myzset2");
    db.ZAdd(dbid, "myzset1", ValueData((int64) 1), "one");
    db.ZAdd(dbid, "myzset1", ValueData((int64) 2), "two");
    db.ZAdd(dbid, "myzset2", ValueData((int64) 1), "one");
    db.ZAdd(dbid, "myzset2", ValueData((int64) 2), "two");
    db.ZAdd(dbid, "myzset2", ValueData((int64) 3), "three");
    SliceArray keys;
    keys.push_back("myzset1");
    keys.push_back("myzset2");
    WeightArray ws;
    ws.push_back(10);
    ws.push_back(4);
    db.ZUnionStore(dbid, "myzset3", keys, ws);

    CHECK_FATAL(db.ZCard(dbid, "myzset3") != 3, "Fail:");
    ZSetQueryOptions options;
    options.withscores = true;
    ValueDataArray values;
    db.ZRange(dbid, "myzset3", 0, -1, values, options);
    std::string str;
    CHECK_FATAL(values.size() != 6, "Fail:%zu", values.size());
    CHECK_FATAL(values[0].ToString(str) != "three", "Fail:%s", values[0].ToString(str).c_str());
    CHECK_FATAL(values[2].ToString(str) != "one", "Fail:%s", values[2].ToString(str).c_str());
    CHECK_FATAL(values[4].ToString(str) != "two", "Fail:%s", values[4].ToString(str).c_str());
}
コード例 #2
0
ファイル: zset_testcase.cpp プロジェクト: rchunping/ardb
void test_zsets_inter(Ardb& db)
{
    DBID dbid = 0;
    db.ZClear(dbid, "myzset1");
    db.ZClear(dbid, "myzset2");
    db.ZAdd(dbid, "myzset1", ValueData((int64) 1), "one");
    db.ZAdd(dbid, "myzset1", ValueData((int64) 2), "two");
    db.ZAdd(dbid, "myzset2", ValueData((int64) 1), "one");
    db.ZAdd(dbid, "myzset2", ValueData((int64) 2), "two");
    db.ZAdd(dbid, "myzset2", ValueData((int64) 3), "three");
    SliceArray keys;
    keys.push_back("myzset1");
    keys.push_back("myzset2");
    WeightArray ws;
    ws.push_back(20);
    ws.push_back(4);
    db.ZInterStore(dbid, "myzset3", keys, ws);

    int zcard = db.ZCard(dbid, "myzset3");
    CHECK_FATAL(zcard != 2, "Fail:%d", zcard);
    ZSetQueryOptions options;
    options.withscores = true;
    ValueDataArray values;
    db.ZRange(dbid, "myzset3", 0, -1, values, options);
    std::string str;
    CHECK_FATAL(values.size() != 4, "Fail:%zu", values.size());
    CHECK_FATAL(values[0].ToString(str) != "one", "Fail:");
}
コード例 #3
0
ファイル: zsets.cpp プロジェクト: ericcapricorn/ardb
	int Ardb::ZUnionStore(const DBID& db, const Slice& dst, SliceArray& keys,
			WeightArray& weights, AggregateType type)
	{
		while (weights.size() < keys.size())
		{
			weights.push_back(1);
		}

		ValueScoreMap vm;
		struct ZUnionWalk: public WalkHandler
		{
				uint32_t z_weight;
				ValueScoreMap& z_vm;
				AggregateType z_aggre_type;
				ZUnionWalk(uint32_t ws, ValueScoreMap& vm, AggregateType type) :
						z_weight(ws), z_vm(vm), z_aggre_type(type)
				{
				}
				int OnKeyValue(KeyObject* k, ValueObject* value, uint32 cursor)
				{
					ZSetKeyObject* zsk = (ZSetKeyObject*) k;
					double score = 0;
					switch (z_aggre_type)
					{
						case AGGREGATE_MIN:
						{
							score = z_weight * zsk->score;
							if (score < z_vm[zsk->value])
							{
								z_vm[zsk->value] = score;
							}
							break;
						}
						case AGGREGATE_MAX:
						{
							score = z_weight * (zsk->score);
							if (score > z_vm[zsk->value])
							{
								z_vm[zsk->value] = score;
							}
							break;
						}
						case AGGREGATE_SUM:
						default:
						{
							score = z_weight * (zsk->score) + z_vm[zsk->value];
							z_vm[zsk->value] = score;
							break;
						}
					}
					return 0;
				}
		};
		SliceArray::iterator kit = keys.begin();
		uint32_t idx = 0;
		while (kit != keys.end())
		{
			ZSetMetaValue meta;
			if (0 == GetZSetMetaValue(db, *kit, meta))
			{
				Slice empty;
				ZSetKeyObject tmp(*kit, empty, meta.min_score, db);
				ZUnionWalk walk(weights[idx], vm, type);
				Walk(tmp, false, &walk);
			}
			idx++;
			kit++;
		}
		if (vm.size() > 0)
		{
			double min_score = 0, max_score = 0;
			BatchWriteGuard guard(GetEngine());
			ZClear(db, dst);
			KeyLockerGuard keyguard(m_key_locker, db, dst);
			ZSetMetaValue meta;
			meta.size = vm.size();
			while (!vm.empty())
			{
				ValueScoreMap::iterator it = vm.begin();
				ZSetKeyObject zsk(dst, it->first, it->second, db);
				ValueObject zsv;
				zsv.type = EMPTY;
				ZSetScoreKeyObject zk(dst, it->first, db);
				ValueObject zv;
				zv.type = DOUBLE;
				zv.v.double_v = it->second;
				if (zv.v.double_v < min_score)
				{
					min_score = zv.v.double_v;
				}
				if (zv.v.double_v > max_score)
				{
					max_score = zv.v.double_v;
				}
				SetValue(zsk, zsv);
				SetValue(zk, zv);
				//reduce memory footprint for huge data set
				vm.erase(it);
			}
			meta.min_score = min_score;
			meta.max_score = max_score;
			SetZSetMetaValue(db, dst, meta);
		}
		return vm.size();
	}
コード例 #4
0
ファイル: zsets.cpp プロジェクト: ericcapricorn/ardb
	int Ardb::ZInterStore(const DBID& db, const Slice& dst, SliceArray& keys,
			WeightArray& weights, AggregateType type)
	{
		while (weights.size() < keys.size())
		{
			weights.push_back(1);
		}
		uint32_t min_size = 0;
		ZSetMetaValueArray metas;
		uint32_t min_idx = 0;
		uint32_t idx = 0;
		SliceArray::iterator kit = keys.begin();
		while (kit != keys.end())
		{
			ZSetMetaValue meta;
			if (0 == GetZSetMetaValue(db, *kit, meta))
			{
				if (min_size == 0 || min_size > meta.size)
				{
					min_size = meta.size;
					min_idx = idx;
				}
			}
			metas.push_back(meta);
			kit++;
			idx++;
		}

		struct ZInterWalk: public WalkHandler
		{
				uint32_t z_weight;
				ValueScoreMap& z_cmp;
				ValueScoreMap& z_result;
				AggregateType z_aggre_type;
				ZInterWalk(uint32_t weight, ValueScoreMap& cmp,
						ValueScoreMap& result, AggregateType type) :
						z_weight(weight), z_cmp(cmp), z_result(result), z_aggre_type(
								type)
				{
				}
				int OnKeyValue(KeyObject* k, ValueObject* value, uint32 cursor)
				{
					ZSetKeyObject* zsk = (ZSetKeyObject*) k;
					if ((&z_cmp != &z_result) && z_cmp.count(zsk->value) == 0)
					{
						return 0;
					}
					switch (z_aggre_type)
					{
						case AGGREGATE_MIN:
						{
							double score = z_weight * zsk->score;
							ValueScoreMap::iterator it = z_cmp.find(zsk->value);
							if (it == z_cmp.end() || score < it->second)
							{
								z_result[zsk->value] = score;
							}
							break;
						}
						case AGGREGATE_MAX:
						{
							double score = z_weight * zsk->score;
							ValueScoreMap::iterator it = z_cmp.find(zsk->value);
							if (it == z_cmp.end() || score > it->second)
							{
								z_result[zsk->value] = score;
							}
							break;
						}
						case AGGREGATE_SUM:
						default:
						{
							if (z_cmp.count(zsk->value) == 0)
							{
								z_result[zsk->value] = z_weight * (zsk->score);
							} else
							{
								z_result[zsk->value] = z_weight * (zsk->score)
										+ z_cmp[zsk->value];
							}
							break;
						}
					}
					return 0;
				}
		};
		ValueScoreMap cmp1, cmp2;
		Slice empty;
		ZSetKeyObject cmp_start(keys[min_idx], empty, metas[min_idx].min_score,
				db);
		ZInterWalk walk(weights[min_idx], cmp1, cmp1, type);
		Walk(cmp_start, false, &walk);
		ValueScoreMap* cmp = &cmp1;
		ValueScoreMap* result = &cmp2;
		for (uint32_t i = 0; i < keys.size(); i++)
		{
			if (i != min_idx)
			{
				Slice empty;
				ZSetKeyObject tmp(keys.at(i), empty, metas[i].min_score, db);
				ZInterWalk walk(weights[i], *cmp, *result, type);
				Walk(tmp, false, &walk);
				cmp->clear();
				ValueScoreMap* old = cmp;
				cmp = result;
				result = old;
			}
		}

		if (cmp->size() > 0)
		{
			double min_score = 0, max_score = 0;
			BatchWriteGuard guard(GetEngine());
			ZClear(db, dst);
			KeyLockerGuard keyguard(m_key_locker, db, dst);
			ZSetMetaValue meta;
			meta.size = cmp->size();
			while (!cmp->empty())
			{
				ValueScoreMap::iterator it = cmp->begin();
				ZSetKeyObject zsk(dst, it->first, it->second, db);
				ValueObject zsv;
				zsv.type = EMPTY;
				ZSetScoreKeyObject zk(dst, it->first, db);
				ValueObject zv;
				zv.type = DOUBLE;
				zv.v.double_v = it->second;
				if (zv.v.double_v < min_score)
				{
					min_score = zv.v.double_v;
				}
				if (zv.v.double_v > max_score)
				{
					max_score = zv.v.double_v;
				}
				SetValue(zsk, zsv);
				SetValue(zk, zv);
				//reduce memory footprint for huge data set
				cmp->erase(it);
			}
			meta.min_score = min_score;
			meta.max_score = max_score;
			SetZSetMetaValue(db, dst, meta);
		}
		return cmp->size();
	}