/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef ANDROID_HIDL_CONCURRENT_MAP_H
#define ANDROID_HIDL_CONCURRENT_MAP_H

#include <mutex>
#include <map>

namespace android {
namespace hardware {

template<typename K, typename V>
class ConcurrentMap {
private:
    using size_type = typename std::map<K, V>::size_type;
    using iterator = typename std::map<K, V>::iterator;
    using const_iterator = typename std::map<K, V>::const_iterator;

public:
    void set(K &&k, V &&v) {
        std::unique_lock<std::mutex> _lock(mMutex);
        mMap[std::forward<K>(k)] = std::forward<V>(v);
    }

    // get with the given default value.
    const V &get(const K &k, const V &def) const {
        std::unique_lock<std::mutex> _lock(mMutex);
        const_iterator iter = mMap.find(k);
        if (iter == mMap.end()) {
            return def;
        }
        return iter->second;
    }

    size_type erase(const K &k) {
        std::unique_lock<std::mutex> _lock(mMutex);
        return mMap.erase(k);
    }

private:
    mutable std::mutex mMutex;
    std::map<K, V> mMap;
};

}  // namespace hardware
}  // namespace android


#endif  // ANDROID_HIDL_CONCURRENT_MAP_H