Redesigned the enumerator

This commit is contained in:
Andrea Cavalli 2020-08-05 16:18:33 +02:00
parent f5418f07c6
commit 17b82c8bd1
2 changed files with 78 additions and 37 deletions

View File

@ -1243,8 +1243,8 @@ Result<FileId> FileManager::register_file(FileData &&data, FileLocationSource fi
int32 remote_key = 0; int32 remote_key = 0;
if (file_view.has_remote_location()) { if (file_view.has_remote_location()) {
RemoteInfo info{file_view.remote_location(), file_location_source, file_id}; RemoteInfo info{file_view.remote_location(), file_location_source, file_id};
remote_key = remote_location_info_.add(info); RemoteInfo stored_info;
auto &stored_info = remote_location_info_.get(remote_key); std::tie(remote_key, stored_info) = remote_location_info_.add_and_get(info);
if (stored_info.file_id_ == file_id) { if (stored_info.file_id_ == file_id) {
get_file_id_info(file_id)->pin_flag_ = true; get_file_id_info(file_id)->pin_flag_ = true;
new_remote = true; new_remote = true;
@ -3068,8 +3068,9 @@ Result<FileId> FileManager::check_input_file_id(FileType type, Result<FileId> re
int32 remote_id = file_id.get_remote(); int32 remote_id = file_id.get_remote();
if (remote_id == 0) { if (remote_id == 0) {
RemoteInfo info{file_view.remote_location(), FileLocationSource::FromUser, file_id}; RemoteInfo info{file_view.remote_location(), FileLocationSource::FromUser, file_id};
remote_id = remote_location_info_.add(info); RemoteInfo stored_info;
if (remote_location_info_.get(remote_id).file_id_ == file_id) { std::tie(remote_id, stored_info) = remote_location_info_.add_and_get(info);
if (stored_info.file_id_ == file_id) {
get_file_id_info(file_id)->pin_flag_ = true; get_file_id_info(file_id)->pin_flag_ = true;
} }
} }
@ -4059,20 +4060,27 @@ void FileManager::memory_cleanup() {
/* DESTROY INVALID remote_location_info_ */ /* DESTROY INVALID remote_location_info_ */
if (true) { if (true) {
std::set<int32> empty_remote_ids = {}; remote_location_info_.lock_access_mutex();
for (auto empty_remote_id : remote_location_info_.get_empty_id()) {
empty_remote_ids.insert(empty_remote_id); std::unordered_map<int32, RemoteInfo> old_remote_info = {};
} {
auto map = remote_location_info_.get_map(); auto map = remote_location_info_.get_map();
auto emptyIdsSize = empty_remote_ids.size();
auto mapSize = map.size(); auto mapSize = map.size();
auto mapMaxSize = map.max_size();
auto it = map.begin(); auto it = map.begin();
while (it != map.end() && (empty_remote_ids.find(it->second) == empty_remote_ids.end())) { while (it != map.end()) {
old_remote_info[it->second] = it->first;
it++;
}
}
auto it = old_remote_info.begin();
while (it != old_remote_info.end()) {
auto is_invalid = false; auto is_invalid = false;
auto find_file = file_id_info_.find(it->first.file_id_.fast_get()); auto find_file = file_id_info_.find(it->second.file_id_.fast_get());
if (find_file != file_id_info_.end()) { if (find_file != file_id_info_.end()) {
auto &file = find_file->second; auto &file = find_file->second;
auto find_file_node = file_nodes_.find(file.node_id_); auto find_file_node = file_nodes_.find(file.node_id_);
@ -4085,10 +4093,12 @@ void FileManager::memory_cleanup() {
} }
if (is_invalid) { if (is_invalid) {
remote_location_info_.erase(it->second); remote_location_info_.erase_unsafe(it->first);
} }
it++; it++;
} }
remote_location_info_.unlock_access_mutex();
} }
/* DESTROY NULL file_id_info_ */ /* DESTROY NULL file_id_info_ */

View File

@ -11,6 +11,7 @@
#include <limits> #include <limits>
#include <map> #include <map>
#include <tuple> #include <tuple>
#include <shared_mutex>
namespace td { namespace td {
@ -23,44 +24,74 @@ class Enumerator {
return map_; return map_;
} }
std::pair<Key, bool> next() { void lock_access_mutex() const {
if (!empty_id_.empty()) { access_mutex.lock();
auto res = empty_id_.back();
empty_id_.pop_back();
return std::make_pair(res, true);
} }
return std::make_pair((Key) (arr_.size() + 1), false); void unlock_access_mutex() const {
access_mutex.unlock();
} }
void erase(Key key_y) { /**
empty_id_.push_back(key_y); *
* @return true if the key is new
*/
Key next() {
auto id = next_id++;
return id;
}
void erase_unsafe(Key key_y) {
auto find_val = arr_.find(key_y);
if (find_val != arr_.end()) {
// Erase this
map_.erase(find_val->second);
// TODO: Not sure about erasing this, instead
arr_.erase(key_y);
}
} }
Key add(ValueT v) { Key add(ValueT v) {
auto next_id = next(); std::lock_guard<std::shared_timed_mutex> writerLock(access_mutex);
return add_internal(v);
}
Key add_internal(ValueT v) {
auto id = next();
bool was_inserted; bool was_inserted;
decltype(map_.begin()) it; decltype(map_.begin()) it;
std::tie(it, was_inserted) = map_.emplace(std::move(v), next_id.first); std::tie(it, was_inserted) = map_.emplace(std::move(v), id);
if (was_inserted && next_id.second) { if (was_inserted) {
arr_[next_id.first - 1] = &it->first; arr_[id] = it->first;
} else if (was_inserted) {
arr_.push_back(&it->first);
} else if (next_id.second) {
empty_id_.push_back(next_id.first);
} }
return it->second; return it->second;
} }
const ValueT &get(Key key) const { const ValueT &get(Key key) const {
auto pos = static_cast<Key>(key - 1); std::shared_lock<std::shared_timed_mutex> readerLock(access_mutex);
return *arr_[pos];
return get_internal(key);
}
const ValueT &get_internal(Key key) const {
return arr_.at(key);
}
std::pair<Key,ValueT> add_and_get(ValueT v) {
std::lock_guard<std::shared_timed_mutex> writerLock(access_mutex);
auto remote_key = add_internal(v);
auto &stored_info = get_internal(remote_key);
return std::make_pair(remote_key, stored_info);
} }
private: private:
std::vector<Key> empty_id_; mutable int32 next_id = 1;
std::map<ValueT, int32> map_; std::map<ValueT, int32> map_;
std::vector<const ValueT *> arr_; std::unordered_map<int32, ValueT> arr_;
mutable std::shared_timed_mutex access_mutex;
}; };
} // namespace td } // namespace td