| // Copyright 2020 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/local_aggregation_1_1/aggregation_procedures/string_histogram_aggregation_procedure.h" |
| |
| #include <tuple> |
| |
| #include "src/lib/util/datetime_util.h" |
| #include "src/lib/util/hash.h" |
| #include "src/local_aggregation_1_1/aggregation_procedures/aggregation_procedure.h" |
| #include "src/logger/encoder.h" |
| #include "src/pb/observation.pb.h" |
| #include "src/public/lib/statusor/status_macros.h" |
| |
| namespace cobalt::local_aggregation { |
| |
| void StringHistogramAggregationProcedure::UpdateAggregateData( |
| const logger::EventRecord &event_record, AggregateData *aggregate_data, |
| AggregationPeriodBucket *bucket) { |
| StringHistogram *histogram = aggregate_data->mutable_string_histogram(); |
| |
| std::string bytes = |
| util::FarmhashFingerprint(event_record.event()->string_event().string_value()); |
| |
| for (int i = 0; i < bucket->string_hashes_size(); i++) { |
| if (bucket->string_hashes(i) == bytes) { |
| (*histogram->mutable_histogram())[i] += 1; |
| return; |
| } |
| } |
| |
| if (bucket->string_hashes_size() < string_buffer_max_) { |
| // Add new entry |
| (*histogram->mutable_histogram())[bucket->string_hashes_size()] += 1; |
| bucket->add_string_hashes(bytes); |
| } |
| } |
| |
| lib::statusor::StatusOr<std::unique_ptr<Observation>> |
| StringHistogramAggregationProcedure::GenerateHourlyObservation( |
| const AggregateDataToGenerate &bucket) { |
| std::vector<std::tuple<std::vector<uint32_t>, std::vector<std::tuple<uint32_t, int64_t>>>> data; |
| data.reserve(bucket.aggregate_data.size()); |
| |
| for (const EventCodesAggregateData *aggregate_data : bucket.aggregate_data) { |
| const StringHistogram &histogram = aggregate_data->data().string_histogram(); |
| std::vector<uint32_t> event_codes(aggregate_data->event_codes().begin(), |
| aggregate_data->event_codes().end()); |
| std::vector<std::tuple<uint32_t, int64_t>> event_code_histogram; |
| for (const auto &[index, count] : histogram.histogram()) { |
| event_code_histogram.emplace_back(index, count); |
| } |
| |
| data.emplace_back(event_codes, event_code_histogram); |
| } |
| |
| if (data.empty()) { |
| return {nullptr}; |
| } |
| |
| std::vector<std::string> hashes; |
| for (const std::string &hash : bucket.string_hashes) { |
| hashes.push_back(hash); |
| } |
| |
| return logger::Encoder::EncodeStringHistogramObservation(hashes, data); |
| } |
| |
| std::string StringHistogramAggregationProcedure::DebugString() const { return "STRING_HISTOGRAM"; } |
| |
| } // namespace cobalt::local_aggregation |