Skip to content

Commit 68c1063

Browse files
committed
Add ObjectMultimapCmp functor to sort ObjectMap entries numerically when possible
1 parent d896528 commit 68c1063

File tree

3 files changed

+43
-19
lines changed

3 files changed

+43
-19
lines changed

src/sst/core/serialization/objectMap.cc

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919

2020
namespace SST::Core::Serialization {
2121

22-
// Static variable instantiation
23-
const std::multimap<std::string, ObjectMap*> ObjectMap::emptyVars;
24-
2522
std::string
2623
ObjectMap::getName()
2724
{

src/sst/core/serialization/objectMap.h

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,20 @@
1515
#include "sst/core/from_string.h"
1616
#include "sst/core/warnmacros.h"
1717

18+
#include <bitset>
1819
#include <cassert>
20+
#include <cerrno>
1921
#include <cstddef>
2022
#include <cstdint>
2123
#include <cstdio>
24+
#include <cstdlib>
25+
#include <exception>
26+
#include <functional>
2227
#include <iostream>
2328
#include <map>
29+
#include <memory>
2430
#include <ostream>
31+
#include <stdexcept>
2532
#include <string>
2633
#include <type_traits>
2734
#include <typeinfo>
@@ -32,12 +39,31 @@
3239

3340
namespace SST::Core::Serialization {
3441

42+
// Comparison of two keys: If both keys are integers, use numeric comparison, else lexicographic
43+
struct ObjectMultimapCmp
44+
{
45+
bool operator()(const std::string& a, const std::string& b) const
46+
{
47+
errno = 0;
48+
char* ea;
49+
long long na = strtoll(a.c_str(), &ea, 10);
50+
// *ea and *eb are 0 after strtol() if there are no invalid characters for integers left in the string
51+
// errno is nonzero if either value is out of range; we fall back on string comparison then
52+
if ( !*ea && !errno ) {
53+
char* eb;
54+
long long nb = strtoll(b.c_str(), &eb, 10);
55+
if ( !*eb && !errno ) return na < nb;
56+
}
57+
return std::less<>()(a, b);
58+
}
59+
};
60+
3561
class ObjectMap;
3662
class TraceBuffer;
3763
class ObjectBuffer;
3864

65+
using ObjectMultimap = std::multimap<std::string, ObjectMap*, ObjectMultimapCmp>;
3966

40-
// class ObjectMapComparison_impl<T>;
4167
/**
4268
Metadata object that each ObjectMap has a pointer to in order to
4369
track the hierarchy information while traversing the data
@@ -158,14 +184,6 @@ class ObjectMapComparison
158184
class ObjectMap
159185
{
160186
protected:
161-
/**
162-
Static empty variable map for use by versions that don't have
163-
variables (i.e. are fundamentals or classes treated as
164-
fundamentals. This is needed because getVariables() returns a
165-
reference to the map.
166-
*/
167-
static const std::multimap<std::string, ObjectMap*> emptyVars;
168-
169187
/**
170188
Metadata object for walking the object hierarchy. When this
171189
object is selected by a parent object, a metadata object will
@@ -184,7 +202,6 @@ class ObjectMap
184202
*/
185203
ObjectMapMetaData* mdata_ = nullptr;
186204

187-
188205
/**
189206
Indicates whether or not the variable is read-only
190207
*/
@@ -218,7 +235,7 @@ class ObjectMap
218235
longer needed and the object will delete itself if refCount_
219236
reaches 0.
220237
*/
221-
int32_t refCount_ = 1;
238+
size_t refCount_ = 1;
222239

223240
public:
224241
/**
@@ -297,7 +314,17 @@ class ObjectMap
297314
ObjectMap's child variables. Fundamental types will return the
298315
same empty map.
299316
*/
300-
virtual const std::multimap<std::string, ObjectMap*>& getVariables() { return emptyVars; }
317+
virtual const ObjectMultimap& getVariables()
318+
{
319+
/**
320+
Static empty variable map for use by versions that don't have
321+
variables (i.e. are fundamentals or classes treated as
322+
fundamentals. This is needed because getVariables() returns a
323+
reference to the map.
324+
*/
325+
static ObjectMultimap emptyVars;
326+
return emptyVars;
327+
}
301328

302329
/**
303330
Increment the reference counter for this ObjectMap. When
@@ -577,7 +604,7 @@ class ObjectMapWithChildren : public ObjectMap
577604
/**
578605
Map that child ObjectMaps are stored in
579606
*/
580-
std::multimap<std::string, ObjectMap*> variables_;
607+
ObjectMultimap variables_;
581608

582609
/**
583610
Default constructor
@@ -623,8 +650,8 @@ class ObjectMapWithChildren : public ObjectMap
623650
child variables. pair.first is the name of the variable in the
624651
context of this object. pair.second is a pointer to the ObjectMap.
625652
*/
626-
const std::multimap<std::string, ObjectMap*>& getVariables() override { return variables_; }
627-
};
653+
const ObjectMultimap& getVariables() override { return variables_; }
654+
}; // class ObjectMapWithChildren
628655

629656
/**
630657
ObjectMap object to create a level of hierarchy that doesn't

src/sst/core/serialization/objectMapDeferred.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class ObjectMapDeferred : public ObjectMap
5252
ObjectMap's child variables. pair.first is the name of the
5353
variable in the context of this object.
5454
*/
55-
const std::multimap<std::string, ObjectMap*>& getVariables() override { return obj_->getVariables(); }
55+
const ObjectMultimap& getVariables() override { return obj_->getVariables(); }
5656

5757
/**
5858
For the Deferred Build, the only variable that gets added will

0 commit comments

Comments
 (0)