1/*
2 * Copyright (c) 2022 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#ifndef ATOMIC_MAP_H
16#define ATOMIC_MAP_H
17
18#include <atomic>
19#include <map>
20#include "nocopyable.h"
21
22namespace OHOS {
23namespace Rosen {
24template<class Key, class Value>
25class AtomicMap {
26public:
27    void insert(const std::pair<Key, Value>& kv)
28    {
29        locked();
30        data_.insert(kv);
31        unlocked();
32    }
33
34    void erase(const Key& key)
35    {
36        locked();
37        data_.erase(key);
38        unlocked();
39    }
40
41    auto find(Key k)
42    {
43        locked();
44        auto key = data_.find(k);
45        unlocked();
46        return key;
47    }
48
49    int count(Key k)
50    {
51        locked();
52        int size = data_.count(k);
53        unlocked();
54        return size;
55    }
56
57    bool isExistAndRemove(Key k, uint32_t value)
58    {
59        locked();
60        if (data_.count(k) <= 0) {
61            unlocked();
62            return false;
63        }
64        if (data_[k] == value) {
65            data_.erase(k);
66            unlocked();
67            return true;
68        }
69        unlocked();
70        return false;
71    }
72
73    bool isExist(Key k, uint32_t value)
74    {
75        locked();
76        if (data_.count(k) <= 0) {
77            unlocked();
78            return false;
79        }
80        if (data_[k] == value) {
81            unlocked();
82            return true;
83        }
84        unlocked();
85        return false;
86    }
87private:
88    void locked()
89    {
90        bool expect = false;
91        while (!isWritingOrReading_.compare_exchange_weak(expect, true, std::memory_order_relaxed)) {
92            expect = false;
93        }
94    }
95
96    void unlocked()
97    {
98        isWritingOrReading_.store(false);
99    }
100
101    std::map<Key, Value> data_;
102    std::atomic<bool> isWritingOrReading_ { false };
103};
104} // Rosen
105} // OHOS
106#endif // ATOMIC_MAP_H