Although the reader is probably familiar with properties in Memgraph, let’s briefly recap. Both vertices and edges can store an arbitrary number of properties. Properties are, in essence, ordered pairs of property names and property values. Each property name within a single graph element (edge/node) can store a single property value. Property names are represented as strings, while property values must be one of the following types:
Property values are modeled in a class conveniently called PropertyValue
.
Although users think of property names in terms of descriptive strings (e.g. “location” or “department”), Memgraph internally converts those names into property keys which are, essentially, unsigned 16-bit integers.
Property keys are modelled by a not-so-conveniently named class called Property
which can be found in storage/types.hpp
. The actual conversion between property names and property keys is done within the ConcurrentIdMapper
but the internals of that implementation are out of scope for understanding property storage.
Both Edge
and Vertex
objects contain an instance of PropertyValueStore
object which is responsible for storing properties of a corresponding graph element.
An interface of PropertyValueStore
is as follows:
By default, Memgraph is an in-memory database and all properties are therefore stored in working memory unless specified otherwise by the user. User has an option to specify via the command line which properties they wish to be stored on disk.
Storage location of each property is encapsulated within a Property
object which is ensured by the ConcurrentIdMapper
. More precisely, the unsigned 16-bit property key has the following format:
|---location--|------id------|
|-Memory|Disk-|-----2^15-----|
In other words, the most significant bit determines the location where the property will be stored.
The underlying implementation of in-memory storage for the time being is std::vector<std::pair<Property, PropertyValue>>
. Implementations ofat
, set
and erase
are linear in time. This implementation is arguably more efficient than std::map
or std::unordered_map
when the average number of properties of a record is relatively small (up to 10) which seems to be the case.
Disk storage is modeled by an abstraction of key-value storage as implemented in `storage/kvstore.hpp’. An interface of this abstraction is as follows: