1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FRAME_RETAINER_H
17 #define FRAME_RETAINER_H
18 
19 #include <map>
20 #include <list>
21 #include <mutex>
22 #include <cstdint>
23 #include "macro_utils.h"
24 #include "runtime_context.h"
25 
26 namespace DistributedDB {
27 class SerialBuffer; // Forward Declarations
28 
29 struct FrameInfo {
30     SerialBuffer *buffer = nullptr;
31     std::string srcTarget;
32     LabelType commLabel;
33     uint32_t frameId = 0u;
34 };
35 
36 struct RetainWork {
37     SerialBuffer *buffer = nullptr;
38     uint32_t frameId = 0u;
39     uint32_t remainTime = 0u; // in second
40 };
41 
42 class FrameRetainer {
43 public:
44     FrameRetainer() = default; // Default constructor must be explicitly provided due to DISABLE_COPY_ASSIGN_MOVE
45     ~FrameRetainer() = default; // Since constructor must be provided, codedex demand deconstructor be provided as well
46     DISABLE_COPY_ASSIGN_MOVE(FrameRetainer);
47 
48     // Start the timer to clear up overtime frames
49     void Initialize();
50 
51     // Stop the timer and clear the RetainWorkPool
52     void Finalize();
53 
54     // Always accept the frame, which may be retained actually or perhaps discarded immediately.
55     void RetainFrame(const FrameInfo &inFrame);
56 
57     // Out frames will be in the order of retention. The retainer no longer in charge of the returned frames.
58     std::list<FrameInfo> FetchFramesForSpecificCommunicator(const LabelType &inCommLabel);
59 
60 private:
61     void DecreaseRemainTimeAndDiscard(const LabelType &label,
62         std::pair<const std::string, std::map<uint64_t, RetainWork>> &eachTarget, std::set<uint64_t> &frameToDiscard);
63 
64     // This methed called from timer, it has overallMutex_ protect itself inside the method
65     void PeriodicalSurveillance();
66 
67     // Following method should be called under protection of overallMutex_ outside the method
68     void DiscardObsoleteFramesIfNeed();
69     void ShrinkRetainWorkPool();
70 
71     mutable std::mutex overallMutex_;
72 
73     TimerId timerId_ = 0; // 0 is invalid timerId
74     bool isTimerWork_ = false;
75 
76     uint32_t totalSizeByByte_ = 0;
77     uint32_t totalRetainFrames_ = 0;
78 
79     uint64_t incRetainOrder_ = 0;
80     std::map<LabelType, std::map<std::string, std::map<uint64_t, RetainWork>>> retainWorkPool_;
81 };
82 } // namespace DistributedDB
83 
84 #endif // FRAME_RETAINER_H
85