Skip to content

Commit 044b4f5

Browse files
committed
updated to use unordered_map closes #611
1 parent 35eebba commit 044b4f5

File tree

3 files changed

+48
-37
lines changed

3 files changed

+48
-37
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
### Updates
55
- Dispatcher now passes in pointer to log message instead of creating on the fly
66
- Introduced new constructor for `Writer` for advanced usage (see muflihun/residue)
7+
- Use `std::unordered_map` for memory management instead of `std::map` issue #611
78

89
## [9.96.1] - 23-02-2018
910
### Fixes

src/easylogging++.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@ void Logger::flush(Level level, base::type::fstream_t* fs) {
614614
}
615615
if (fs != nullptr) {
616616
fs->flush();
617-
std::map<Level, unsigned int>::iterator iter = m_unflushedCount.find(level);
617+
std::unordered_map<Level, unsigned int>::iterator iter = m_unflushedCount.find(level);
618618
if (iter != m_unflushedCount.end()) {
619619
iter->second = 0;
620620
}
@@ -1274,7 +1274,7 @@ bool CommandLineArgs::hasParamWithValue(const char* paramKey) const {
12741274
}
12751275

12761276
const char* CommandLineArgs::getParamValue(const char* paramKey) const {
1277-
std::map<std::string, std::string>::const_iterator iter = m_paramsWithValue.find(std::string(paramKey));
1277+
std::unordered_map<std::string, std::string>::const_iterator iter = m_paramsWithValue.find(std::string(paramKey));
12781278
return iter != m_paramsWithValue.end() ? iter->second.c_str() : "";
12791279
}
12801280

@@ -1947,7 +1947,7 @@ bool VRegistry::allowed(base::type::VerboseLevel vlevel, const char* file) {
19471947
} else {
19481948
char baseFilename[base::consts::kSourceFilenameMaxLength] = "";
19491949
base::utils::File::buildBaseFilename(file, baseFilename);
1950-
std::map<std::string, base::type::VerboseLevel>::iterator it = m_modules.begin();
1950+
std::unordered_map<std::string, base::type::VerboseLevel>::iterator it = m_modules.begin();
19511951
for (; it != m_modules.end(); ++it) {
19521952
if (base::utils::Str::wildCardMatch(baseFilename, it->first.c_str())) {
19531953
return vlevel <= it->second;

src/easylogging++.h

+44-34
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,16 @@ enum class Level : base::type::EnumType {
585585
/// @brief Represents unknown level
586586
Unknown = 1010
587587
};
588+
} // namespace el
589+
namespace std {
590+
template<> struct hash<el::Level> {
591+
public:
592+
std::size_t operator()(const el::Level& l) const {
593+
return hash<el::base::type::EnumType>{}(static_cast<el::base::type::EnumType>(l));
594+
}
595+
};
596+
}
597+
namespace el {
588598
/// @brief Static class that contains helper functions for el::Level
589599
class LevelHelper : base::StaticClass {
590600
public:
@@ -1302,7 +1312,7 @@ class CommandLineArgs {
13021312
private:
13031313
int m_argc;
13041314
char** m_argv;
1305-
std::map<std::string, std::string> m_paramsWithValue;
1315+
std::unordered_map<std::string, std::string> m_paramsWithValue;
13061316
std::vector<std::string> m_params;
13071317
};
13081318
/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type.
@@ -1427,7 +1437,7 @@ class AbstractRegistry : public base::threading::ThreadSafe {
14271437
/// of AbstractRegistry<T_Ptr, Container>. Any implementation of this class should be
14281438
/// explicitly (by using lock functions)
14291439
template <typename T_Ptr, typename T_Key = const char*>
1430-
class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
1440+
class Registry : public AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>> {
14311441
public:
14321442
typedef typename Registry<T_Ptr, T_Key>::iterator iterator;
14331443
typedef typename Registry<T_Ptr, T_Key>::const_iterator const_iterator;
@@ -1491,7 +1501,7 @@ class Registry : public AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>> {
14911501
}
14921502

14931503
private:
1494-
virtual void deepCopy(const AbstractRegistry<T_Ptr, std::map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
1504+
virtual void deepCopy(const AbstractRegistry<T_Ptr, std::unordered_map<T_Key, T_Ptr*>>& sr) ELPP_FINAL {
14951505
for (const_iterator it = sr.cbegin(); it != sr.cend(); ++it) {
14961506
registerNew(it->first, new T_Ptr(*it->second));
14971507
}
@@ -1591,7 +1601,7 @@ class RegistryWithPred : public AbstractRegistry<T_Ptr, std::vector<T_Ptr*>> {
15911601
class Utils {
15921602
public:
15931603
template <typename T, typename TPtr>
1594-
static bool installCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
1604+
static bool installCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
15951605
if (mapT->find(id) == mapT->end()) {
15961606
mapT->insert(std::make_pair(id, TPtr(new T())));
15971607
return true;
@@ -1600,15 +1610,15 @@ class Utils {
16001610
}
16011611

16021612
template <typename T, typename TPtr>
1603-
static void uninstallCallback(const std::string& id, std::map<std::string, TPtr>* mapT) {
1613+
static void uninstallCallback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
16041614
if (mapT->find(id) != mapT->end()) {
16051615
mapT->erase(id);
16061616
}
16071617
}
16081618

16091619
template <typename T, typename TPtr>
1610-
static T* callback(const std::string& id, std::map<std::string, TPtr>* mapT) {
1611-
typename std::map<std::string, TPtr>::iterator iter = mapT->find(id);
1620+
static T* callback(const std::string& id, std::unordered_map<std::string, TPtr>* mapT) {
1621+
typename std::unordered_map<std::string, TPtr>::iterator iter = mapT->find(id);
16121622
if (iter != mapT->end()) {
16131623
return static_cast<T*>(iter->second.get());
16141624
}
@@ -1953,7 +1963,7 @@ class Configurations : public base::utils::RegistryWithPred<Configuration, Confi
19531963

19541964
namespace base {
19551965
typedef std::shared_ptr<base::type::fstream_t> FileStreamPtr;
1956-
typedef std::map<std::string, FileStreamPtr> LogStreamsReferenceMap;
1966+
typedef std::unordered_map<std::string, FileStreamPtr> LogStreamsReferenceMap;
19571967
/// @brief Configurations with data types.
19581968
///
19591969
/// @detail el::Configurations have string based values. This is whats used internally in order to read correct configurations.
@@ -1990,16 +2000,16 @@ class TypedConfigurations : public base::threading::ThreadSafe {
19902000

19912001
private:
19922002
Configurations* m_configurations;
1993-
std::map<Level, bool> m_enabledMap;
1994-
std::map<Level, bool> m_toFileMap;
1995-
std::map<Level, std::string> m_filenameMap;
1996-
std::map<Level, bool> m_toStandardOutputMap;
1997-
std::map<Level, base::LogFormat> m_logFormatMap;
1998-
std::map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
1999-
std::map<Level, bool> m_performanceTrackingMap;
2000-
std::map<Level, base::FileStreamPtr> m_fileStreamMap;
2001-
std::map<Level, std::size_t> m_maxLogFileSizeMap;
2002-
std::map<Level, std::size_t> m_logFlushThresholdMap;
2003+
std::unordered_map<Level, bool> m_enabledMap;
2004+
std::unordered_map<Level, bool> m_toFileMap;
2005+
std::unordered_map<Level, std::string> m_filenameMap;
2006+
std::unordered_map<Level, bool> m_toStandardOutputMap;
2007+
std::unordered_map<Level, base::LogFormat> m_logFormatMap;
2008+
std::unordered_map<Level, base::SubsecondPrecision> m_subsecondPrecisionMap;
2009+
std::unordered_map<Level, bool> m_performanceTrackingMap;
2010+
std::unordered_map<Level, base::FileStreamPtr> m_fileStreamMap;
2011+
std::unordered_map<Level, std::size_t> m_maxLogFileSizeMap;
2012+
std::unordered_map<Level, std::size_t> m_logFlushThresholdMap;
20032013
base::LogStreamsReferenceMap* m_logStreamsReference;
20042014

20052015
friend class el::Helpers;
@@ -2009,21 +2019,21 @@ class TypedConfigurations : public base::threading::ThreadSafe {
20092019
friend class el::base::LogDispatcher;
20102020

20112021
template <typename Conf_T>
2012-
inline Conf_T getConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
2022+
inline Conf_T getConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
20132023
base::threading::ScopedLock scopedLock(lock());
20142024
return unsafeGetConfigByVal(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
20152025
}
20162026

20172027
template <typename Conf_T>
2018-
inline Conf_T& getConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
2028+
inline Conf_T& getConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
20192029
base::threading::ScopedLock scopedLock(lock());
20202030
return unsafeGetConfigByRef(level, confMap, confName); // This is not unsafe anymore - mutex locked in scope
20212031
}
20222032

20232033
template <typename Conf_T>
2024-
Conf_T unsafeGetConfigByVal(Level level, const std::map<Level, Conf_T>* confMap, const char* confName) {
2034+
Conf_T unsafeGetConfigByVal(Level level, const std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
20252035
ELPP_UNUSED(confName);
2026-
typename std::map<Level, Conf_T>::const_iterator it = confMap->find(level);
2036+
typename std::unordered_map<Level, Conf_T>::const_iterator it = confMap->find(level);
20272037
if (it == confMap->end()) {
20282038
try {
20292039
return confMap->at(Level::Global);
@@ -2038,9 +2048,9 @@ class TypedConfigurations : public base::threading::ThreadSafe {
20382048
}
20392049

20402050
template <typename Conf_T>
2041-
Conf_T& unsafeGetConfigByRef(Level level, std::map<Level, Conf_T>* confMap, const char* confName) {
2051+
Conf_T& unsafeGetConfigByRef(Level level, std::unordered_map<Level, Conf_T>* confMap, const char* confName) {
20422052
ELPP_UNUSED(confName);
2043-
typename std::map<Level, Conf_T>::iterator it = confMap->find(level);
2053+
typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(level);
20442054
if (it == confMap->end()) {
20452055
try {
20462056
return confMap->at(Level::Global);
@@ -2054,14 +2064,14 @@ class TypedConfigurations : public base::threading::ThreadSafe {
20542064
}
20552065

20562066
template <typename Conf_T>
2057-
void setValue(Level level, const Conf_T& value, std::map<Level, Conf_T>* confMap, bool includeGlobalLevel = true) {
2067+
void setValue(Level level, const Conf_T& value, std::unordered_map<Level, Conf_T>* confMap, bool includeGlobalLevel = true) {
20582068
// If map is empty and we are allowed to add into generic level (Level::Global), do it!
20592069
if (confMap->empty() && includeGlobalLevel) {
20602070
confMap->insert(std::make_pair(Level::Global, value));
20612071
return;
20622072
}
20632073
// If same value exist in generic level already, dont add it to explicit level
2064-
typename std::map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
2074+
typename std::unordered_map<Level, Conf_T>::iterator it = confMap->find(Level::Global);
20652075
if (it != confMap->end() && it->second == value) {
20662076
return;
20672077
}
@@ -2360,7 +2370,7 @@ inline void FUNCTION_NAME(const T&);
23602370
std::string m_parentApplicationName;
23612371
bool m_isConfigured;
23622372
Configurations m_configurations;
2363-
std::map<Level, unsigned int> m_unflushedCount;
2373+
std::unordered_map<Level, unsigned int> m_unflushedCount;
23642374
base::LogStreamsReferenceMap* m_logStreamsReference;
23652375
LogBuilderPtr m_logBuilder;
23662376

@@ -2466,7 +2476,7 @@ class RegisteredLoggers : public base::utils::Registry<Logger, std::string> {
24662476
LogBuilderPtr m_defaultLogBuilder;
24672477
Configurations m_defaultConfigurations;
24682478
base::LogStreamsReferenceMap m_logStreamsReference;
2469-
std::map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
2479+
std::unordered_map<std::string, base::type::LoggerRegistrationCallbackPtr> m_loggerRegistrationCallbacks;
24702480
friend class el::base::Storage;
24712481

24722482
void unsafeFlushAll(void);
@@ -2492,7 +2502,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe {
24922502

24932503
bool allowed(base::type::VerboseLevel vlevel, const char* file);
24942504

2495-
inline const std::map<std::string, base::type::VerboseLevel>& modules(void) const {
2505+
inline const std::unordered_map<std::string, base::type::VerboseLevel>& modules(void) const {
24962506
return m_modules;
24972507
}
24982508

@@ -2506,7 +2516,7 @@ class VRegistry : base::NoCopy, public base::threading::ThreadSafe {
25062516
private:
25072517
base::type::VerboseLevel m_level;
25082518
base::type::EnumType* m_pFlags;
2509-
std::map<std::string, base::type::VerboseLevel> m_modules;
2519+
std::unordered_map<std::string, base::type::VerboseLevel> m_modules;
25102520
};
25112521
} // namespace base
25122522
class LogMessage {
@@ -2740,7 +2750,7 @@ class Storage : base::NoCopy {
27402750

27412751
inline std::string getThreadName(const std::string& threadId) {
27422752
base::threading::ScopedLock scopedLock(m_threadNamesLock);
2743-
std::map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
2753+
std::unordered_map<std::string, std::string>::const_iterator it = m_threadNames.find(threadId);
27442754
if (it == m_threadNames.end()) {
27452755
return threadId;
27462756
}
@@ -2757,9 +2767,9 @@ class Storage : base::NoCopy {
27572767
#endif // ELPP_ASYNC_LOGGING
27582768
base::utils::CommandLineArgs m_commandLineArgs;
27592769
PreRollOutCallback m_preRollOutCallback;
2760-
std::map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
2761-
std::map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
2762-
std::map<std::string, std::string> m_threadNames;
2770+
std::unordered_map<std::string, base::type::LogDispatchCallbackPtr> m_logDispatchCallbacks;
2771+
std::unordered_map<std::string, base::type::PerformanceTrackingCallbackPtr> m_performanceTrackingCallbacks;
2772+
std::unordered_map<std::string, std::string> m_threadNames;
27632773
std::vector<CustomFormatSpecifier> m_customFormatSpecifiers;
27642774
base::threading::Mutex m_customFormatSpecifiersLock;
27652775
base::threading::Mutex m_threadNamesLock;

0 commit comments

Comments
 (0)