-
Notifications
You must be signed in to change notification settings - Fork 576
feat(tdigest): add the support of TDIGEST.REVRANK command #3130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: unstable
Are you sure you want to change the base?
Changes from 8 commits
03b69e1
97df4a1
70a39d3
dde8410
0d3e9cc
bb172a8
a64add4
3954b1f
05d1202
f688e14
8bcad0f
46ac984
495e072
2b6785d
3af3b54
f3d85d3
e68689d
eb8674f
c70f410
b991d0d
4c9a41d
543fda0
e0d39a7
a4ed14c
9d6c532
ff658f8
53e82f8
6df3309
201afed
0851c22
c7ed36f
3a898fe
3711578
4b4f684
bd268b4
8e6a7f9
6662240
e7f06a2
367981c
4b8cd6a
07836fd
f44bc56
2aded75
f4a9c53
5023de8
e3629d9
ae05623
0cf8c8a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -186,6 +186,67 @@ rocksdb::Status TDigest::Add(engine::Context& ctx, const Slice& digest_name, con | |
| return storage_->Write(ctx, storage_->DefaultWriteOptions(), batch->GetWriteBatch()); | ||
| } | ||
|
|
||
| rocksdb::Status TDigest::RevRank(engine::Context& ctx, const Slice& digest_name, const std::vector<double>& inputs, | ||
| std::vector<int>* result) { | ||
| auto ns_key = AppendNamespacePrefix(digest_name); | ||
| TDigestMetadata metadata; | ||
| { | ||
| LockGuard guard(storage_->GetLockManager(), ns_key); | ||
|
|
||
| if (auto status = getMetaDataByNsKey(ctx, ns_key, &metadata); !status.ok()) { | ||
| return status; | ||
| } | ||
|
|
||
| if (metadata.total_observations == 0) { | ||
| result->resize(inputs.size(), -2); | ||
| return rocksdb::Status::OK(); | ||
| } | ||
|
|
||
| if (metadata.unmerged_nodes > 0) { | ||
| auto batch = storage_->GetWriteBatchBase(); | ||
| WriteBatchLogData log_data(kRedisTDigest); | ||
| if (auto status = batch->PutLogData(log_data.Encode()); !status.ok()) { | ||
| return status; | ||
| } | ||
|
|
||
| if (auto status = mergeCurrentBuffer(ctx, ns_key, batch, &metadata); !status.ok()) { | ||
| return status; | ||
| } | ||
|
|
||
| std::string metadata_bytes; | ||
| metadata.Encode(&metadata_bytes); | ||
| if (auto status = batch->Put(metadata_cf_handle_, ns_key, metadata_bytes); !status.ok()) { | ||
| return status; | ||
| } | ||
|
|
||
| if (auto status = storage_->Write(ctx, storage_->DefaultWriteOptions(), batch->GetWriteBatch()); !status.ok()) { | ||
| return status; | ||
| } | ||
|
|
||
| ctx.RefreshLatestSnapshot(); | ||
| } | ||
| } | ||
|
Comment on lines
222
to
237
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi @donghao526 , The merge action could be refactored into a function to reduce duplication of the same logic. Best Regards, |
||
|
|
||
| std::vector<Centroid> centroids; | ||
| if (auto status = dumpCentroids(ctx, ns_key, metadata, ¢roids); !status.ok()) { | ||
| return status; | ||
| } | ||
|
|
||
| auto dump_centroids = DummyCentroids(metadata, centroids); | ||
|
|
||
| result->clear(); | ||
| result->reserve(inputs.size()); | ||
|
|
||
| for (auto value : inputs) { | ||
| auto status_or_rank = TDigestRevRank(dump_centroids, value); | ||
| if (!status_or_rank) { | ||
| return rocksdb::Status::InvalidArgument(status_or_rank.Msg()); | ||
| } | ||
| result->push_back(*status_or_rank); | ||
| } | ||
|
||
| return rocksdb::Status::OK(); | ||
| } | ||
|
|
||
| rocksdb::Status TDigest::Quantile(engine::Context& ctx, const Slice& digest_name, const std::vector<double>& qs, | ||
| TDigestQuantitleResult* result) { | ||
| auto ns_key = AppendNamespacePrefix(digest_name); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -150,3 +150,22 @@ inline StatusOr<double> TDigestQuantile(TD&& td, double q) { | |
| diff /= (lc.weight / 2 + rc.weight / 2); | ||
| return Lerp(lc.mean, rc.mean, diff); | ||
| } | ||
|
|
||
| template <typename TD> | ||
| inline StatusOr<int> TDigestRevRank(TD&& td, double value) { | ||
|
||
| if (value < td.Min()) { | ||
| return static_cast<int>(td.TotalWeight()); | ||
| } | ||
| if (value > td.Max()) { | ||
| return static_cast<int>(-1); | ||
| } | ||
| double rank = 0; | ||
| for (auto iter = td.Begin(); iter->Valid(); iter->Next()) { | ||
| if (auto centroid = GET_OR_RET(iter->GetCentroid()); centroid.mean > value) { | ||
| rank += centroid.weight; | ||
| } else if (centroid.mean == value) { | ||
| rank += centroid.weight / 2; | ||
| } | ||
| } | ||
| return static_cast<int>(rank); | ||
| } | ||
donghao526 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.