xref: /aosp_15_r20/external/federated-compute/fcp/aggregation/core/aggregator.h (revision 14675a029014e728ec732f129a32e299b2da0601)
1 /*
2  * Copyright 2022 Google LLC
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FCP_AGGREGATION_CORE_AGGREGATOR_H_
18 #define FCP_AGGREGATION_CORE_AGGREGATOR_H_
19 
20 #include "fcp/base/monitoring.h"
21 
22 namespace fcp {
23 namespace aggregation {
24 
25 // Abstract base for aggregators that compute an aggregate of input items of
26 // type T into a final aggregate of type R using a multi-stage process in which
27 // items are first partially aggregated at an intermediate layer, then the
28 // partial aggregates are further combined, and finally projected into the
29 // result. This multi-stage process consists of the following:
30 // a) The aggregator is created with a zero value of an arbitrary intermediate
31 //    type U. Please note that the type U is never surfaced and considered an
32 //    implementation detail, so it doesn't need to be explicitlty parameterized.
33 // b) The method Accumulate is used to accumulate T-typed client items into the
34 //    U-typed partial aggregate.
35 // c) The method Merge is used to merge the intermediate U-typed aggregates of
36 //    the two aggregator instances producing a merged U-typed aggregate.
37 // d) The method Report is used to project the top-level U-typed aggregate into
38 //    the final R-typed result.
39 // The typename Self is used to specify the actual derived class.
40 template <typename T, typename R, typename Self>
41 class Aggregator {
42  public:
43   Aggregator() = default;
44   virtual ~Aggregator() = default;
45 
46   // Aggregator derived classes are not copyable.
47   Aggregator(const Aggregator&) = delete;
48 
49   // Accumulates an input into the intermediate aggregate.
50   // The method may fail if the input isn't compatible with the current
51   // Aggregator or if the Aggregator instance has already been 'consumed'.
52   virtual Status Accumulate(T input) = 0;
53 
54   // Merges intermediate aggregates from the other Aggregator instance into the
55   // current Aggregator instance. Doing so 'consumes' the other Aggregator
56   // instance.
57   // The method may fail if the two Aggregator instances aren't compatible.
58   virtual Status MergeWith(Self&& other) = 0;
59 
60   // Returns true if the current Aggregator instance can produce a report, for
61   // example if a sufficient number of inputs has been accumulated.
62   virtual bool CanReport() const = 0;
63 
64   // Produces the final report, 'consuming' the current Aggregator instance.
65   // Once the current instance is consumed it can no longer perform any
66   // operations.
67   // This method fails when CanReport method returns false.
68   virtual StatusOr<R> Report() && = 0;
69 };
70 
71 }  // namespace aggregation
72 }  // namespace fcp
73 
74 #endif  // FCP_AGGREGATION_CORE_AGGREGATOR_H_
75