184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong/*
284888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * Copyright (C) 2016 The Android Open Source Project
384888d3553c7595ee57dc73023ae94a27895de0dYifan Hong *
484888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * Licensed under the Apache License, Version 2.0 (the "License");
584888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * you may not use this file except in compliance with the License.
684888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * You may obtain a copy of the License at
784888d3553c7595ee57dc73023ae94a27895de0dYifan Hong *
884888d3553c7595ee57dc73023ae94a27895de0dYifan Hong *      http://www.apache.org/licenses/LICENSE-2.0
984888d3553c7595ee57dc73023ae94a27895de0dYifan Hong *
1084888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * Unless required by applicable law or agreed to in writing, software
1184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * distributed under the License is distributed on an "AS IS" BASIS,
1284888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1384888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * See the License for the specific language governing permissions and
1484888d3553c7595ee57dc73023ae94a27895de0dYifan Hong * limitations under the License.
1584888d3553c7595ee57dc73023ae94a27895de0dYifan Hong */
1684888d3553c7595ee57dc73023ae94a27895de0dYifan Hong#ifndef ANDROID_HIDL_CONCURRENT_MAP_H
1784888d3553c7595ee57dc73023ae94a27895de0dYifan Hong#define ANDROID_HIDL_CONCURRENT_MAP_H
1884888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
1984888d3553c7595ee57dc73023ae94a27895de0dYifan Hong#include <mutex>
2084888d3553c7595ee57dc73023ae94a27895de0dYifan Hong#include <map>
2184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
2284888d3553c7595ee57dc73023ae94a27895de0dYifan Hongnamespace android {
2384888d3553c7595ee57dc73023ae94a27895de0dYifan Hongnamespace hardware {
2484888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
2584888d3553c7595ee57dc73023ae94a27895de0dYifan Hongtemplate<typename K, typename V>
2684888d3553c7595ee57dc73023ae94a27895de0dYifan Hongclass ConcurrentMap {
2784888d3553c7595ee57dc73023ae94a27895de0dYifan Hongprivate:
2884888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    using size_type = typename std::map<K, V>::size_type;
2984888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    using iterator = typename std::map<K, V>::iterator;
3084888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    using const_iterator = typename std::map<K, V>::const_iterator;
3184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
3284888d3553c7595ee57dc73023ae94a27895de0dYifan Hongpublic:
3384888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    void set(K &&k, V &&v) {
3484888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        std::unique_lock<std::mutex> _lock(mMutex);
3584888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        mMap[std::forward<K>(k)] = std::forward<V>(v);
3684888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    }
3784888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
3884888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    // get with the given default value.
3984888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    const V &get(const K &k, const V &def) const {
4084888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        std::unique_lock<std::mutex> _lock(mMutex);
4184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        const_iterator iter = mMap.find(k);
4284888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        if (iter == mMap.end()) {
4384888d3553c7595ee57dc73023ae94a27895de0dYifan Hong            return def;
4484888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        }
4584888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        return iter->second;
4684888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    }
4784888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
4884888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    size_type erase(const K &k) {
4984888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        std::unique_lock<std::mutex> _lock(mMutex);
5084888d3553c7595ee57dc73023ae94a27895de0dYifan Hong        return mMap.erase(k);
5184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    }
5284888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
536295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen    size_type eraseIfEqual(const K& k, const V& v) {
546295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        std::unique_lock<std::mutex> _lock(mMutex);
556295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        const_iterator iter = mMap.find(k);
566295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        if (iter == mMap.end()) {
576295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen            return 0;
586295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        }
596295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        if (iter->second == v) {
606295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen            mMap.erase(iter);
616295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen            return 1;
626295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        } else {
636295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen            return 0;
646295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen        }
656295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen    }
666295027eecc583a9a8cd5271ba350422765e58c6Martijn Coenen
67e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland    std::unique_lock<std::mutex> lock() { return std::unique_lock<std::mutex>(mMutex); }
68e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland
69e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland    void setLocked(K&& k, V&& v) { mMap[std::forward<K>(k)] = std::forward<V>(v); }
70e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland
71e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland    const V& getLocked(const K& k, const V& def) const {
72e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland        const_iterator iter = mMap.find(k);
73e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland        if (iter == mMap.end()) {
74e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland            return def;
75e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland        }
76e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland        return iter->second;
77e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland    }
78e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland
79e67a676fdf3f0c565af64e375075e5386e6ab940Steven Moreland   private:
8084888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    mutable std::mutex mMutex;
8184888d3553c7595ee57dc73023ae94a27895de0dYifan Hong    std::map<K, V> mMap;
8284888d3553c7595ee57dc73023ae94a27895de0dYifan Hong};
8384888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
8484888d3553c7595ee57dc73023ae94a27895de0dYifan Hong}  // namespace hardware
8584888d3553c7595ee57dc73023ae94a27895de0dYifan Hong}  // namespace android
8684888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
8784888d3553c7595ee57dc73023ae94a27895de0dYifan Hong
8884888d3553c7595ee57dc73023ae94a27895de0dYifan Hong#endif  // ANDROID_HIDL_CONCURRENT_MAP_H
89