From 13bce5cc766d7f7662ef8b6ef71b2b044675c957 Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 13 Sep 2019 11:21:26 -0300 Subject: [PATCH 1/8] Added mutex to devices to avoid cuncurrency issues --- .gitignore | 4 ++++ CMakeLists.txt | 1 + src/logid/DeviceFinder.cpp | 47 ++++++++++++++++++++------------------ src/logid/DeviceFinder.h | 7 +++--- 4 files changed, 34 insertions(+), 25 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eeff230 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/build +*.swp +*~ +/compile_commands.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 69fbf1e..29fa7c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required(VERSION 3.10) project(logiops) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -Wall -Wextra") diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 268c8f4..1e9e261 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -20,7 +20,6 @@ void DeviceFinder::addDevice(const char *path) // Asynchronously scan device std::thread{[=]() { - std::vector _devs; const int max_tries = 10; const int try_delay = 250000; @@ -50,7 +49,16 @@ void DeviceFinder::addDevice(const char *path) if(major > 1) // HID++ 2.0 devices only { auto dev = new Device(string_path, index); - _devs.push_back(dev); + + this->devicesMutex.lock(); + this->devices.insert({ + dev, + std::thread{[dev]() { + dev->start(); + }} + }); + this->devicesMutex.unlock(); + log_printf(INFO, "%s detected: device %d on %s", d.name().c_str(), index, string_path.c_str()); } break; @@ -93,28 +101,23 @@ void DeviceFinder::addDevice(const char *path) catch(HIDPP::Dispatcher::NoHIDPPReportException &e) { } catch(std::system_error &e) { log_printf(WARN, "Failed to open %s: %s", string_path.c_str(), e.what()); } - for(auto dev : _devs) - devices.insert({dev, std::thread{[dev]() { dev->start(); }}}); - }}.detach(); } void DeviceFinder::removeDevice(const char* path) { - // Iterate through Devices, stop all in path - auto it = devices.begin(); - while (it != devices.end()) - { - if(it->first->path == path) - { - log_printf(INFO, "%s on %s disconnected.", it->first->name.c_str(), path); - it->first->stop(); - it->second.join(); - delete(it->first); - devices.erase(it); - it++; - } - else - it++; - } -} \ No newline at end of file + devicesMutex.lock(); + // Iterate through Devices, stop all in path + for (auto it = devices.begin(); it != devices.end(); it++) + { + if(it->first->path == path) + { + log_printf(INFO, "%s on %s disconnected.", it->first->name.c_str(), path); + it->first->stop(); + it->second.join(); + delete(it->first); + devices.erase(it); + } + } + devicesMutex.unlock(); +} diff --git a/src/logid/DeviceFinder.h b/src/logid/DeviceFinder.h index e64d6c6..2e1e5e2 100644 --- a/src/logid/DeviceFinder.h +++ b/src/logid/DeviceFinder.h @@ -1,5 +1,4 @@ -#ifndef DEVICEFINDER_H -#define DEVICEFINDER_H +#pragma once #include #include @@ -9,6 +8,7 @@ #include #include #include "Device.h" +#include class Device; @@ -19,8 +19,9 @@ public: protected: void addDevice(const char* path); void removeDevice(const char* path); +private: + std::mutex devicesMutex; }; extern DeviceFinder* finder; -#endif //DEVICEFINDER_H \ No newline at end of file From ba0bf93b80ba9b4086a64fd18b459fa7b03b8808 Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 17:20:06 -0300 Subject: [PATCH 2/8] Switched device removal and insertion responsibility to DeviceFinder --- src/logid/Device.cpp | 16 +----- src/logid/DeviceFinder.cpp | 99 ++++++++++++++++++++++++++++---------- src/logid/DeviceFinder.h | 18 +++++-- 3 files changed, 90 insertions(+), 43 deletions(-) diff --git a/src/logid/Device.cpp b/src/logid/Device.cpp index d4b1c3e..fec0e6c 100644 --- a/src/logid/Device.cpp +++ b/src/logid/Device.cpp @@ -248,19 +248,7 @@ void ReceiverHandler::handleEvent(const HIDPP::Report &event) { case HIDPP10::IReceiver::DeviceUnpaired: { - // Find device, stop it, and delete it - auto it = finder->devices.begin(); - while (it != finder->devices.end()) - { - if(it->first->path == dev->path && it->first->index == event.deviceIndex()) - { - log_printf(INFO, "%s (Device %d on %s) unpaired.", it->first->name.c_str(), event.deviceIndex(), dev->path.c_str()); - it->first->stop(); - it->second.join(); - finder->devices.erase(it); - } - else it++; - } + finder->stopAndDeleteDevice(dev->path, event.deviceIndex()); break; } case HIDPP10::IReceiver::DevicePaired: @@ -384,4 +372,4 @@ std::map Device::get_features() _features.insert( {i, ifs.getFeatureID(i) } ); return _features; -} \ No newline at end of file +} diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 1e9e261..31b8fb1 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -14,6 +14,76 @@ #include "util.h" #include "Device.h" +void stopAndDeletePairedDevice (PairedDevice &pairedDevice) +{ + log_printf(INFO, "%s (Device %d on %s) disconnected", pairedDevice.device->name.c_str(), pairedDevice.device->index, pairedDevice.device->path.c_str()); + pairedDevice.device->stop(); + pairedDevice.associatedThread.join(); + delete(pairedDevice.device); +} + +DeviceFinder::~DeviceFinder() +{ + this->devicesMutex.lock(); + for (auto it = this->devices.begin(); it != this->devices.end(); it++) { + for (auto jt = it->second.begin(); jt != it->second.end(); jt++) { + stopAndDeletePairedDevice(jt->second); + } + } + this->devicesMutex.unlock(); +} + +void DeviceFinder::insertNewDevice(const std::string &path, HIDPP::DeviceIndex index) +{ + Device *device = new Device(path, index); + + this->devicesMutex.lock(); + log_printf(INFO, "%s detected: device %d on %s", device->name.c_str(), index, path.c_str()); + auto pathBucket = this->devices.emplace(path, std::map()).first; + pathBucket->second.emplace(index, PairedDevice{ + device, + std::thread([device]() { + device->start(); + }) + }); + this->devicesMutex.unlock(); +} + +void DeviceFinder::stopAndDeleteAllDevicesIn (const std::string &path) +{ + this->devicesMutex.lock(); + auto pathBucket = this->devices.find(path); + if (pathBucket != this->devices.end()) + { + for (auto& indexBucket : pathBucket->second) { + stopAndDeletePairedDevice(indexBucket.second); + } + this->devices.erase(pathBucket); + } + this->devicesMutex.unlock(); + + log_printf(WARN, "Attempted to disconnect not previously connected devices on %s", path.c_str()); +} + +void DeviceFinder::stopAndDeleteDevice (const std::string &path, HIDPP::DeviceIndex index) +{ + this->devicesMutex.lock(); + auto pathBucket = this->devices.find(path); + if (pathBucket != this->devices.end()) + { + auto indexBucket = pathBucket->second.find(index); + if (indexBucket != pathBucket->second.end()) + { + stopAndDeletePairedDevice(indexBucket->second); + pathBucket->second.erase(indexBucket); + } + } + this->devicesMutex.unlock(); + + log_printf(WARN, "Attempted to disconnect not previously connected device %d on %s", index, path.c_str()); +} + + void DeviceFinder::addDevice(const char *path) { std::string string_path(path); @@ -34,6 +104,7 @@ void DeviceFinder::addDevice(const char *path) HIDPP::WirelessDevice3, HIDPP::WirelessDevice4, HIDPP::WirelessDevice5, HIDPP::WirelessDevice6}) { + if(!has_receiver_index && index == HIDPP::WirelessDevice1) break; for(int i = 0; i < max_tries; i++) @@ -48,18 +119,7 @@ void DeviceFinder::addDevice(const char *path) has_receiver_index = true; if(major > 1) // HID++ 2.0 devices only { - auto dev = new Device(string_path, index); - - this->devicesMutex.lock(); - this->devices.insert({ - dev, - std::thread{[dev]() { - dev->start(); - }} - }); - this->devicesMutex.unlock(); - - log_printf(INFO, "%s detected: device %d on %s", d.name().c_str(), index, string_path.c_str()); + this->insertNewDevice(string_path, index); } break; } @@ -106,18 +166,5 @@ void DeviceFinder::addDevice(const char *path) void DeviceFinder::removeDevice(const char* path) { - devicesMutex.lock(); - // Iterate through Devices, stop all in path - for (auto it = devices.begin(); it != devices.end(); it++) - { - if(it->first->path == path) - { - log_printf(INFO, "%s on %s disconnected.", it->first->name.c_str(), path); - it->first->stop(); - it->second.join(); - delete(it->first); - devices.erase(it); - } - } - devicesMutex.unlock(); + this->stopAndDeleteAllDevicesIn(std::string(path)); } diff --git a/src/logid/DeviceFinder.h b/src/logid/DeviceFinder.h index 2e1e5e2..9ca6a5d 100644 --- a/src/logid/DeviceFinder.h +++ b/src/logid/DeviceFinder.h @@ -5,22 +5,34 @@ #include #include #include -#include +#include +#include #include -#include "Device.h" #include +#include "Device.h" + class Device; +struct PairedDevice { + Device *device; + std::thread associatedThread; +}; + class DeviceFinder : public HID::DeviceMonitor { public: - std::map devices; + ~DeviceFinder(); + + void insertNewDevice (const std::string &path, HIDPP::DeviceIndex index); + void stopAndDeleteAllDevicesIn (const std::string &path); + void stopAndDeleteDevice (const std::string &path, HIDPP::DeviceIndex index); protected: void addDevice(const char* path); void removeDevice(const char* path); private: std::mutex devicesMutex; + std::map> devices; }; extern DeviceFinder* finder; From 03560b08df9806f5939eb8c494560ce7a6a1bfab Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 18:03:23 -0300 Subject: [PATCH 3/8] Fixed error that caused logid to stop querying asleep devices --- src/logid/DeviceFinder.cpp | 46 +++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 31b8fb1..8c38c4b 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -9,11 +9,15 @@ #include #include #include +#include #include "DeviceFinder.h" #include "util.h" #include "Device.h" +#define MAX_CONNECTION_TRIES 10 +#define TIME_BETWEEN_CONNECTION_TRIES 1s + void stopAndDeletePairedDevice (PairedDevice &pairedDevice) { log_printf(INFO, "%s (Device %d on %s) disconnected", pairedDevice.device->name.c_str(), pairedDevice.device->index, pairedDevice.device->path.c_str()); @@ -86,12 +90,12 @@ void DeviceFinder::stopAndDeleteDevice (const std::string &path, HIDPP::DeviceIn void DeviceFinder::addDevice(const char *path) { + using namespace std::chrono_literals; + std::string string_path(path); // Asynchronously scan device std::thread{[=]() { - const int max_tries = 10; - const int try_delay = 250000; //Check if device is an HID++ device and handle it accordingly try @@ -107,8 +111,11 @@ void DeviceFinder::addDevice(const char *path) if(!has_receiver_index && index == HIDPP::WirelessDevice1) break; - for(int i = 0; i < max_tries; i++) - { + + bool device_not_connected = true; + bool device_unknown = false; + int remaining_tries = MAX_CONNECTION_TRIES; + do { try { HIDPP::Device d(&dispatcher, index); @@ -121,42 +128,45 @@ void DeviceFinder::addDevice(const char *path) { this->insertNewDevice(string_path, index); } - break; + device_not_connected = false; } catch(HIDPP10::Error &e) { if(e.errorCode() != HIDPP10::Error::UnknownDevice) { - if(i == max_tries - 1) - log_printf(ERROR, "Error while querying %s, wireless device %d: %s", string_path.c_str(), index, e.what()); - else usleep(try_delay); + if(remaining_tries == 1) + { + log_printf(WARN, "While querying %s, wireless device %d: %s", string_path.c_str(), index, e.what()); + remaining_tries += MAX_CONNECTION_TRIES; // asleep wireless devices may raise this error, so warn but do not stop querying device + } } - else break; + else device_unknown = true; } catch(HIDPP20::Error &e) { if(e.errorCode() != HIDPP20::Error::UnknownDevice) { - if(i == max_tries - 1) + if(remaining_tries == 1) log_printf(ERROR, "Error while querying %s, device %d: %s", string_path.c_str(), index, e.what()); - else usleep(try_delay); } - else break; + else device_unknown = true; } catch(HIDPP::Dispatcher::TimeoutError &e) { - if(i == max_tries - 1) + if(remaining_tries == 1) log_printf(ERROR, "Device %s (index %d) timed out.", string_path.c_str(), index); - else usleep(try_delay); } catch(std::runtime_error &e) { - if(i == max_tries - 1) + if(remaining_tries == 1) log_printf(ERROR, "Runtime error on device %d on %s: %s", index, string_path.c_str(), e.what()); - else usleep(try_delay); } - } - } + + remaining_tries--; + std::this_thread::sleep_for(TIME_BETWEEN_CONNECTION_TRIES); + + } while (device_not_connected && !device_unknown && remaining_tries > 0); + } } catch(HIDPP::Dispatcher::NoHIDPPReportException &e) { } catch(std::system_error &e) { log_printf(WARN, "Failed to open %s: %s", string_path.c_str(), e.what()); } From 34509ad6d651d76d86ee1c39dd81eba82dcc5f0a Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 18:15:52 -0300 Subject: [PATCH 4/8] Using error code to check for resource error --- src/logid/DeviceFinder.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 8c38c4b..5c0bc4a 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -132,13 +132,18 @@ void DeviceFinder::addDevice(const char *path) } catch(HIDPP10::Error &e) { - if(e.errorCode() != HIDPP10::Error::UnknownDevice) + if (e.errorCode() == HIDPP10::Error::ResourceError) { if(remaining_tries == 1) { - log_printf(WARN, "While querying %s, wireless device %d: %s", string_path.c_str(), index, e.what()); - remaining_tries += MAX_CONNECTION_TRIES; // asleep wireless devices may raise this error, so warn but do not stop querying device - } + log_printf(WARN, "While querying %s (possibly asleep), wireless device %d: %s", string_path.c_str(), index, e.what()); + remaining_tries += MAX_CONNECTION_TRIES; // asleep devices may raise a resource error, so do not count this try + } + } + else if(e.errorCode() != HIDPP10::Error::UnknownDevice) + { + if(remaining_tries == 1) + log_printf(ERROR, "While querying %s, wireless device %d: %s", string_path.c_str(), index, e.what()); } else device_unknown = true; } From 21b6c2367f2f32d9f708e99629603411e05a5068 Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 18:24:30 -0300 Subject: [PATCH 5/8] Formatted variable names to conform with snail case standard --- src/logid/DeviceFinder.cpp | 52 +++++++++++++++++++------------------- src/logid/DeviceFinder.h | 6 ++--- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 5c0bc4a..1832e46 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -18,71 +18,71 @@ #define MAX_CONNECTION_TRIES 10 #define TIME_BETWEEN_CONNECTION_TRIES 1s -void stopAndDeletePairedDevice (PairedDevice &pairedDevice) +void stopAndDeletePairedDevice (ConnectedDevice &connected_device) { - log_printf(INFO, "%s (Device %d on %s) disconnected", pairedDevice.device->name.c_str(), pairedDevice.device->index, pairedDevice.device->path.c_str()); - pairedDevice.device->stop(); - pairedDevice.associatedThread.join(); - delete(pairedDevice.device); + log_printf(INFO, "%s (Device %d on %s) disconnected", connected_device.device->name.c_str(), connected_device.device->index, connected_device.device->path.c_str()); + connected_device.device->stop(); + connected_device.associatedThread.join(); + delete(connected_device.device); } DeviceFinder::~DeviceFinder() { - this->devicesMutex.lock(); + this->devices_mutex.lock(); for (auto it = this->devices.begin(); it != this->devices.end(); it++) { for (auto jt = it->second.begin(); jt != it->second.end(); jt++) { stopAndDeletePairedDevice(jt->second); } } - this->devicesMutex.unlock(); + this->devices_mutex.unlock(); } void DeviceFinder::insertNewDevice(const std::string &path, HIDPP::DeviceIndex index) { Device *device = new Device(path, index); - this->devicesMutex.lock(); + this->devices_mutex.lock(); log_printf(INFO, "%s detected: device %d on %s", device->name.c_str(), index, path.c_str()); - auto pathBucket = this->devices.emplace(path, std::map()).first; - pathBucket->second.emplace(index, PairedDevice{ + auto path_bucket = this->devices.emplace(path, std::map()).first; + path_bucket->second.emplace(index, ConnectedDevice{ device, std::thread([device]() { device->start(); }) }); - this->devicesMutex.unlock(); + this->devices_mutex.unlock(); } void DeviceFinder::stopAndDeleteAllDevicesIn (const std::string &path) { - this->devicesMutex.lock(); - auto pathBucket = this->devices.find(path); - if (pathBucket != this->devices.end()) + this->devices_mutex.lock(); + auto path_bucket = this->devices.find(path); + if (path_bucket != this->devices.end()) { - for (auto& indexBucket : pathBucket->second) { - stopAndDeletePairedDevice(indexBucket.second); + for (auto& index_bucket : path_bucket->second) { + stopAndDeletePairedDevice(index_bucket.second); } - this->devices.erase(pathBucket); + this->devices.erase(path_bucket); } - this->devicesMutex.unlock(); + this->devices_mutex.unlock(); log_printf(WARN, "Attempted to disconnect not previously connected devices on %s", path.c_str()); } void DeviceFinder::stopAndDeleteDevice (const std::string &path, HIDPP::DeviceIndex index) { - this->devicesMutex.lock(); - auto pathBucket = this->devices.find(path); - if (pathBucket != this->devices.end()) + this->devices_mutex.lock(); + auto path_bucket = this->devices.find(path); + if (path_bucket != this->devices.end()) { - auto indexBucket = pathBucket->second.find(index); - if (indexBucket != pathBucket->second.end()) + auto index_bucket = path_bucket->second.find(index); + if (index_bucket != path_bucket->second.end()) { - stopAndDeletePairedDevice(indexBucket->second); - pathBucket->second.erase(indexBucket); + stopAndDeletePairedDevice(index_bucket->second); + path_bucket->second.erase(index_bucket); } } - this->devicesMutex.unlock(); + this->devices_mutex.unlock(); log_printf(WARN, "Attempted to disconnect not previously connected device %d on %s", index, path.c_str()); } diff --git a/src/logid/DeviceFinder.h b/src/logid/DeviceFinder.h index 9ca6a5d..20af200 100644 --- a/src/logid/DeviceFinder.h +++ b/src/logid/DeviceFinder.h @@ -14,7 +14,7 @@ class Device; -struct PairedDevice { +struct ConnectedDevice { Device *device; std::thread associatedThread; }; @@ -31,8 +31,8 @@ protected: void addDevice(const char* path); void removeDevice(const char* path); private: - std::mutex devicesMutex; - std::map> devices; + std::mutex devices_mutex; + std::map> devices; }; extern DeviceFinder* finder; From cf39d9f680532fb2b716797982587b6af51736f1 Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 18:34:36 -0300 Subject: [PATCH 6/8] Fixed map include in DeviceFinder --- src/logid/DeviceFinder.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logid/DeviceFinder.h b/src/logid/DeviceFinder.h index 20af200..f5ed218 100644 --- a/src/logid/DeviceFinder.h +++ b/src/logid/DeviceFinder.h @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include From 874b9101e525967f9abf6ac7805c2b5bd28069c1 Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 18:36:21 -0300 Subject: [PATCH 7/8] Removed list include in DeviceFinder --- src/logid/DeviceFinder.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/logid/DeviceFinder.h b/src/logid/DeviceFinder.h index f5ed218..8a1d24b 100644 --- a/src/logid/DeviceFinder.h +++ b/src/logid/DeviceFinder.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include From a03e13936c3a6b731a3ae1cf50e0def9b4b12c0c Mon Sep 17 00:00:00 2001 From: rockerbacon Date: Fri, 20 Sep 2019 18:48:44 -0300 Subject: [PATCH 8/8] Renamed method --- src/logid/DeviceFinder.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/logid/DeviceFinder.cpp b/src/logid/DeviceFinder.cpp index 1832e46..857c97d 100644 --- a/src/logid/DeviceFinder.cpp +++ b/src/logid/DeviceFinder.cpp @@ -18,7 +18,7 @@ #define MAX_CONNECTION_TRIES 10 #define TIME_BETWEEN_CONNECTION_TRIES 1s -void stopAndDeletePairedDevice (ConnectedDevice &connected_device) +void stopAndDeleteConnectedDevice (ConnectedDevice &connected_device) { log_printf(INFO, "%s (Device %d on %s) disconnected", connected_device.device->name.c_str(), connected_device.device->index, connected_device.device->path.c_str()); connected_device.device->stop(); @@ -31,7 +31,7 @@ DeviceFinder::~DeviceFinder() this->devices_mutex.lock(); for (auto it = this->devices.begin(); it != this->devices.end(); it++) { for (auto jt = it->second.begin(); jt != it->second.end(); jt++) { - stopAndDeletePairedDevice(jt->second); + stopAndDeleteConnectedDevice(jt->second); } } this->devices_mutex.unlock(); @@ -60,7 +60,7 @@ void DeviceFinder::stopAndDeleteAllDevicesIn (const std::string &path) if (path_bucket != this->devices.end()) { for (auto& index_bucket : path_bucket->second) { - stopAndDeletePairedDevice(index_bucket.second); + stopAndDeleteConnectedDevice(index_bucket.second); } this->devices.erase(path_bucket); } @@ -78,7 +78,7 @@ void DeviceFinder::stopAndDeleteDevice (const std::string &path, HIDPP::DeviceIn auto index_bucket = path_bucket->second.find(index); if (index_bucket != path_bucket->second.end()) { - stopAndDeletePairedDevice(index_bucket->second); + stopAndDeleteConnectedDevice(index_bucket->second); path_bucket->second.erase(index_bucket); } }