DataMap.hpp

A DataMap links names to arbitrary object types.

A DataMap links data names to arbitrary object types. Each data map is composed of a MemoryImage (that holds a set of values) and a DataLayout (that maps names and other info to those values.)

AddVar<type>(“name”, value, [“desc”], [“notes”]) Includes a new data entry into the DataMap and returns its uniquq ID.

Get<type>(“name”) - retrieve a reference to a value in the DataMap slowly. Get<type>(ID) - retrieve a reference more quickly. GetID(“name”) - convert a name into a unique ID. Set(name|id, value) - change a value in the DataMap (you may also use Get() followed by an assignment.)

New data entries can be added to a DataMap, but never removed (for efficiency purposes). When a DataMap is copied, all data entries are also copied (relatively fast). As long as a DataMaps layout doesn’t change, all copied maps will share the same layout (fast).

A layout can also be locked with LockLayout(), which will throw an error if there is an attempt to modify that layout again. A lock can be checked with IsLocked().

Specialty versions of Get and Set exist if you don’t want to use templates for simple types. They are GetValue(*), SetValue(*), GetString(*), and SetString(*). Values are all represented as doubles.

DEVELOPER NOTES:

  • Each entry can have a one-byte control block immediately proceeding it in memory. Each bit would be associated with additional information about the entry. Options include:

    1. The memory is a POINTER not an instance. This would allow entries to behave like references, potentially eliminating the need to copy larger data structures into the memory image.

    2. The entry has a non-trivial (or user-provided) COPY/MOVE CONSTRUCTOR or DESTRUCTOR

    3. The entry has a function to call for a Get instead of a value in memory. The space reserved is used for the function pointer (incompatible with bit 1…)

    4. The entry has a function to call when it is set. Effectively this can implement SIGNAL monitoring it that should be notified whenever it changes. The signal itself would need to be stored elsewhere (presumably in the memory image, but possibly in the layout.)

    5. The memory is a LOG of values, not a single value. This allows for quick identification of when something special needs to be done. 6-8. Limited type information (7 types that can be handled more effectively?)

  • We should be able to keep a series of values, not just a single one. This can be done with a series of new functions: AddLog() instead of AddVar() when new variable is created. Get() should still work for latest value. Ideally keep latest in first position. Change non-const Get() to GetRef() which cannot be used for a log. Add GetAve() function for logs as well as GetLog() for the full series (as std::span?).

  • Settings for all entries should have more information on how they are dealt with, such as if they should be included in output and how. Perhaps a system of tags for dynamic use?

  • After everything else is working, build a LocalDataMap<size_t> that locks in the size at compile time, providing more localized memory. Otherwise DataMap as a whole can be built on a templated class that takes an IMAGE_T as an argument.

  • Default values should be saved in the layout allowing any MemoryImage to be easily reset to factory settings.

  • A user should be able to override copy constructors (though probably not move constructors or destructors?). Then the copy process can be more customizable, for example having some settings return to the default value or be further processed. It’s also possible to have multiple types of copies, so if we indicate a “Copy birth” we get the above, but if we indicate a “Copy clone” or “Copy inject” we do something different. We also probably need to allow for multiple parents…

  • An OptimizeLayout() function that can reorder entries so that they are somehow more sensible? Does DataMap need to worry about memory alignment?

  • A MemoryImage factory to speed up allocation and deallocation if we’re using the same size images repeatedly.

  • Some way of grouping memory across DataMaps so that a particular entry for many maps has all of its instances consecutive in memory? This seems really tricky to pull off, but if we can do it, the improvement in cache performance could be dramatic.

  • Rename DataLayout and MemoryImage to DataMap_Layout and DataMap_Memory?

Note

Status: ALPHA

class DataMap
#include <DataMap.hpp>

Public Types

using key_type = std::string

Public Functions

inline DataMap()
inline DataMap(const DataMap &in_map)
inline DataMap(DataMap &&in_map)
DataMap &operator=(const DataMap &in_map)
inline ~DataMap()
inline size_t GetSize() const

Determine how many Bytes large this image is.

inline size_t GetID(const std::string &name) const

Translate a name into an ID.

inline bool HasID(size_t id) const

Test if this map has a setting ID.

inline bool HasName(const std::string &name) const

Test is this map has a variable by a given name.

template<typename T>
inline bool IsType(size_t id) const

Test if a variable is of a given type.

template<typename T>
inline bool IsType(const std::string &name) const
template<typename T, typename ...ARGS>
inline bool Has(ARGS&&... args) const

Verify settings.

template<typename T>
inline T &Get(size_t id)

Retrieve a variable by its type and position.

template<typename T>
inline const T &Get(size_t id) const

Retrieve a const variable by its type and position.

template<typename T>
inline T &Get(const std::string &name)

Retrieve a variable by its type and name. (Slower!)

template<typename T>
inline const T &Get(const std::string &name) const

Retrieve a const variable by its type and name. (Slower!)

template<typename T>
inline std::span<T> Get(size_t id, size_t count)
template<typename T>
inline std::span<const T> Get(size_t id, size_t count) const
template<typename T>
inline std::span<T> Get(const std::string &name, size_t count)
template<typename T>
inline std::span<const T> Get(const std::string &name, size_t count) const
template<typename T>
inline T &Set(size_t id, const T &value)

Set a variable by ID.

template<typename T>
inline T &Set(const std::string &name, const T &value)

Set a variable by name.

inline TypeID GetType(size_t id) const

Look up the type of a variable by ID.

inline TypeID GetType(const std::string &name) const

Look up the type of a variable by name.

inline bool IsNumeric(size_t id) const
inline bool IsNumeric(const std::string &name) const
inline double GetAsDouble(size_t id, TypeID type_id) const

Get the memory at the target position, assume it is the provided type, and convert the value found there to double.

inline double GetAsDouble(size_t id) const

Get the memory at the target position, lookup it’s type, and convert the value to double.

inline std::string GetAsString(size_t id, TypeID type_id, size_t count = 1) const

Get the memory at the target position, assume it is the provided type, and convert the value found there to string.

inline std::string GetAsString(size_t id) const

Get the memory at the target position, lookup it’s type, and convert the value to string.

template<typename T>
inline size_t AddVar(const std::string &name, const T &default_value, const std::string &desc = "", const std::string &notes = "", size_t count = 1)

Add a new variable with a specified type, name and value.

template<typename T>
inline size_t AddVar(const std::string &name)

Add a new variable with just a specified type and name; must be able to default.

inline bool HasLayout(const DataLayout &in_layout) const

Test if this DataMap uses the specified layout.

inline bool HasLayout() const

Test if this DataMap has ANY layout.

inline bool SameLayout(const DataMap &in_dm) const

Test if this DataMap is using the identical layout as another DataMap.

inline DataLayout &GetLayout()

Get the DataLayout so that it can be used elsewhere.

inline const DataLayout &GetLayout() const

Get the DataLayout so that it can be used elsewhere.

inline bool IsLocked() const

Test if this layout is locked (i.e., it cannot be changed.)

inline void LockLayout()

Prevent this DataMap’s layout from having any additional changed made to it.

Public Static Functions

static inline std::function<Datum(const DataMap&)> MakeDatumAccessor(const DataLayout &layout, size_t id)

Return a function that takes in a data map and (efficiently) returns a Datum using the specified entry.

static inline auto MakeDatumAccessor(const DataLayout &layout, const std::string &name)

Return a function that takes in a data map and (efficiently) returns a Datum using the specified name.

Protected Functions

inline DataMap(Ptr<DataLayout> in_layout_ptr, size_t in_size)
inline void MakeLayoutUnique()

If the current layout is shared, make a copy of it.

Protected Attributes

MemoryImage memory

Memory contents for this Map.

Ptr<DataLayout> layout_ptr

Layout we are using (shared across maps w/ same format)