2016-05-12 23:43:17 +03:00
|
|
|
/*
|
2019-06-20 02:58:25 +03:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2016-05-12 23:43:17 +03:00
|
|
|
*
|
2019-06-20 02:58:25 +03:00
|
|
|
* This software may be used and distributed according to the terms of the
|
|
|
|
* GNU General Public License version 2.
|
2016-05-12 23:43:17 +03:00
|
|
|
*/
|
2019-10-11 15:26:59 +03:00
|
|
|
|
2016-05-12 23:43:17 +03:00
|
|
|
#pragma once
|
2017-10-23 22:19:27 +03:00
|
|
|
#include <folly/container/EvictingCacheMap.h>
|
2016-05-12 23:43:17 +03:00
|
|
|
#include <folly/futures/Future.h>
|
|
|
|
#include <folly/futures/SharedPromise.h>
|
|
|
|
|
|
|
|
namespace facebook {
|
|
|
|
namespace eden {
|
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
template <typename KEY, typename VAL, typename HASH = std::hash<KEY>>
|
2016-05-12 23:43:17 +03:00
|
|
|
class LeaseCache {
|
|
|
|
public:
|
|
|
|
using ValuePtr = std::shared_ptr<VAL>;
|
|
|
|
using FutureType = folly::Future<ValuePtr>;
|
|
|
|
using SharedPromiseType = std::shared_ptr<folly::SharedPromise<ValuePtr>>;
|
2017-11-04 01:58:04 +03:00
|
|
|
using FetchFunc = std::function<FutureType(const KEY& key)>;
|
2016-05-12 23:43:17 +03:00
|
|
|
|
|
|
|
private:
|
|
|
|
std::mutex lock_;
|
|
|
|
folly::EvictingCacheMap<KEY, SharedPromiseType, HASH> cache_;
|
|
|
|
FetchFunc fetcher_;
|
|
|
|
|
|
|
|
public:
|
2017-11-04 01:58:04 +03:00
|
|
|
LeaseCache(size_t maxSize, FetchFunc fetcher, size_t clearSize = 1)
|
|
|
|
: cache_(maxSize, clearSize), fetcher_(fetcher) {}
|
2016-05-12 23:43:17 +03:00
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
void set(const KEY& key, ValuePtr val) {
|
2016-05-12 23:43:17 +03:00
|
|
|
std::lock_guard<std::mutex> g(lock_);
|
|
|
|
auto entry = std::make_shared<typename SharedPromiseType::element_type>();
|
|
|
|
entry->setValue(val);
|
|
|
|
cache_.set(key, entry);
|
|
|
|
}
|
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
void erase(const KEY& key) {
|
2016-05-12 23:43:17 +03:00
|
|
|
std::lock_guard<std::mutex> g(lock_);
|
|
|
|
cache_.erase(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
void setMaxSize(size_t size) {
|
|
|
|
cache_.setMaxSize(size);
|
|
|
|
}
|
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
FutureType get(const KEY& key) {
|
2016-05-12 23:43:17 +03:00
|
|
|
SharedPromiseType entry;
|
|
|
|
|
|
|
|
{
|
|
|
|
std::lock_guard<std::mutex> g(lock_);
|
|
|
|
|
|
|
|
auto it = cache_.find(key);
|
|
|
|
if (it != cache_.end()) {
|
|
|
|
entry = it->second;
|
|
|
|
return entry->getFuture();
|
|
|
|
}
|
|
|
|
|
|
|
|
entry = std::make_shared<typename SharedPromiseType::element_type>();
|
|
|
|
cache_.set(key, entry);
|
|
|
|
}
|
|
|
|
|
|
|
|
auto future = entry->getFuture();
|
|
|
|
|
2018-10-23 23:39:59 +03:00
|
|
|
fetcher_(key).thenTry(
|
2018-06-01 20:55:42 +03:00
|
|
|
[entry](folly::Try<ValuePtr>&& t) { entry->setTry(std::move(t)); });
|
2016-05-12 23:43:17 +03:00
|
|
|
|
|
|
|
return future;
|
|
|
|
}
|
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
bool exists(const KEY& key) {
|
|
|
|
return cache_.exists(key);
|
|
|
|
}
|
2016-05-12 23:43:17 +03:00
|
|
|
};
|
|
|
|
|
2017-11-04 01:58:04 +03:00
|
|
|
} // namespace eden
|
|
|
|
} // namespace facebook
|