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 RENDERLRUCACHE_H
17 #define RENDERLRUCACHE_H
18 
19 #include "base/render_base.h"
20 
21 namespace OHOS {
22 namespace Media {
23 namespace Effect {
24 template <typename KEY_TYPE, typename VALUE_TYPE, typename SIZE_MEASURER> class RenderFifoCache {
25 public:
26     typedef typename std::pair<KEY_TYPE, VALUE_TYPE> PAIR_TYPE;
27     typedef typename std::list<PAIR_TYPE>::iterator ITERATOR_TYPE;
28 
RenderFifoCache(size_t cacheCapacity)29     explicit RenderFifoCache(size_t cacheCapacity) : capacity_(cacheCapacity)
30     {
31         sizeMeasurer_ = SIZE_MEASURER();
32     }
33 
Put(const KEY_TYPE & key,const VALUE_TYPE & value)34     void Put(const KEY_TYPE &key, const VALUE_TYPE &value)
35     {
36         valueList_.push_front(PAIR_TYPE(key, value));
37         currentSize_ += sizeMeasurer_(value);
38         while ((currentSize_ > capacity_) && (valueList_.size() > 1)) {
39             auto &last = valueList_.back();
40             currentSize_ -= sizeMeasurer_(last.second);
41             valueList_.pop_back();
42         }
43     }
44 
Take(const KEY_TYPE & key,VALUE_TYPE & value)45     bool Take(const KEY_TYPE &key, VALUE_TYPE &value)
46     {
47         auto it =
48             std::find_if(valueList_.begin(), valueList_.end(), [key](const PAIR_TYPE &v) { return v.first == key; });
49         if (it != valueList_.end()) {
50             value = (*it).second;
51             valueList_.erase(it);
52             currentSize_ -= sizeMeasurer_(value);
53             return true;
54         }
55         return false;
56     }
57 
Size()58     size_t Size() const
59     {
60         return currentSize_;
61     }
62 
63     size_t ReSize(size_t size, bool biasMore = true)
64     {
65         while (currentSize_ > size) {
66             auto &last = valueList_.back();
67             size_t ss = sizeMeasurer_(last.second);
68             if ((currentSize_ - ss) < size && biasMore) {
69                 break;
70             }
71             valueList_.pop_back();
72             currentSize_ -= ss;
73         }
74         return currentSize_;
75     }
76 
77 private:
78     std::list<PAIR_TYPE> valueList_;
79     size_t capacity_;
80     size_t currentSize_ { 0 };
81     std::function<size_t(const VALUE_TYPE &v)> sizeMeasurer_;
82 };
83 } // namespace Effect
84 } // namespace Media
85 } // namespace OHOS
86 #endif // RENDERLRUCACHE_H