1 /*
2  * Copyright (C) 2024 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 DISTRIBUTEDDATAMGR_PASTEBOARD_DEDUPLICATE_MEMORY_H
17 #define DISTRIBUTEDDATAMGR_PASTEBOARD_DEDUPLICATE_MEMORY_H
18 
19 #include <cstdint>
20 
21 #include "pasteboard_linked_list.h"
22 
23 namespace OHOS {
24 namespace MiscServices {
25 
26 template <typename T>
27 class DeduplicateMemory {
28 public:
29     explicit DeduplicateMemory(int64_t expirationMilliSeconds);
30     ~DeduplicateMemory();
31     bool IsDuplicate(const T &data);
32 
33 private:
34     int64_t GetTimestamp();
35     void ClearExpiration();
36     bool FindExist(const T &data);
37 
38     struct MemoryIdentity {
39         int64_t timestamp;
40         const T data;
41     };
42 
43     LinkedList<MemoryIdentity> memory_;
44     int64_t expirationMS_;
45 };
46 
47 template <typename T>
DeduplicateMemory(int64_t expirationMilliSeconds)48 DeduplicateMemory<T>::DeduplicateMemory(int64_t expirationMilliSeconds) : expirationMS_(expirationMilliSeconds)
49 {
50 }
51 
52 template <typename T>
~DeduplicateMemory()53 DeduplicateMemory<T>::~DeduplicateMemory()
54 {
55     memory_.Clear();
56 }
57 
58 template <typename T>
IsDuplicate(const T & data)59 bool DeduplicateMemory<T>::IsDuplicate(const T &data)
60 {
61     ClearExpiration();
62     if (FindExist(data)) {
63         return true;
64     }
65     int64_t timestamp = GetTimestamp();
66     memory_.InsertFront(MemoryIdentity({.timestamp = timestamp, .data = data}));
67     return false;
68 }
69 
70 template <typename T>
FindExist(const T & data)71 bool DeduplicateMemory<T>::FindExist(const T &data)
72 {
73     return memory_.FindExist([data](const MemoryIdentity &identity) {
74         return identity.data == data;
75     });
76 }
77 
78 template <typename T>
GetTimestamp()79 int64_t DeduplicateMemory<T>::GetTimestamp()
80 {
81     return std::chrono::duration_cast<std::chrono::milliseconds>(
82         std::chrono::steady_clock::now().time_since_epoch()).count();
83 }
84 
85 template <typename T>
ClearExpiration()86 void DeduplicateMemory<T>::ClearExpiration()
87 {
88     int64_t timestamp = GetTimestamp();
89     if (timestamp < expirationMS_) {
90         return;
91     }
92     int64_t expirationTimestamp = timestamp - expirationMS_;
93     memory_.RemoveIf([expirationTimestamp](const MemoryIdentity &identity) {
94         return expirationTimestamp > identity.timestamp;
95     });
96 }
97 } // namespace MiscServices
98 } // namespace OHOS
99 
100 #endif // DISTRIBUTEDDATAMGR_PASTEBOARD_DEDUPLICATE_MEMORY_H
101