bae3e8a6d3
Add function for property sizes
270 lines
7.6 KiB
Python
270 lines
7.6 KiB
Python
# Copyright 2023 Memgraph Ltd.
|
|
#
|
|
# Use of this software is governed by the Business Source License
|
|
# included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
|
# License, and you may not use this file except in compliance with the Business Source License.
|
|
#
|
|
# As of the Change Date specified in that file, in accordance with
|
|
# the Business Source License, use of this software will be governed
|
|
# by the Apache License, Version 2.0, included in the file
|
|
# licenses/APL.txt.
|
|
|
|
import sys
|
|
|
|
import pytest
|
|
from common import get_bytes, memgraph
|
|
|
|
|
|
def test_property_size_on_null_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.null_prop = null;
|
|
"""
|
|
)
|
|
|
|
null_bytes = get_bytes(memgraph, "null_prop")
|
|
|
|
# No property stored, no bytes allocated
|
|
assert null_bytes == 0
|
|
|
|
|
|
def test_property_size_on_bool_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.bool_prop = True;
|
|
"""
|
|
)
|
|
|
|
bool_bytes = get_bytes(memgraph, "bool_prop")
|
|
|
|
# 1 byte metadata, 1 byte prop id, but value is encoded in the metadata
|
|
assert bool_bytes == 2
|
|
|
|
|
|
def test_property_size_on_one_byte_int_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.S_int_prop = 4;
|
|
"""
|
|
)
|
|
|
|
s_int_bytes = get_bytes(memgraph, "S_int_prop")
|
|
|
|
# 1 byte metadata, 1 byte prop id + payload size 1 byte to store the int
|
|
assert s_int_bytes == 3
|
|
|
|
|
|
def test_property_size_on_two_byte_int_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.M_int_prop = 500;
|
|
"""
|
|
)
|
|
|
|
m_int_bytes = get_bytes(memgraph, "M_int_prop")
|
|
|
|
# 1 byte metadata, 1 byte prop id + payload size 2 bytes to store the int
|
|
assert m_int_bytes == 4
|
|
|
|
|
|
def test_property_size_on_four_byte_int_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.L_int_prop = 1000000000;
|
|
"""
|
|
)
|
|
|
|
l_int_bytes = get_bytes(memgraph, "L_int_prop")
|
|
|
|
# 1 byte metadata, 1 byte prop id + payload size 4 bytes to store the int
|
|
assert l_int_bytes == 6
|
|
|
|
|
|
def test_property_size_on_eight_byte_int_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.XL_int_prop = 1000000000000;
|
|
"""
|
|
)
|
|
|
|
xl_int_bytes = get_bytes(memgraph, "XL_int_prop")
|
|
|
|
# 1 byte metadata, 1 byte prop id + payload size 8 bytes to store the int
|
|
assert xl_int_bytes == 10
|
|
|
|
|
|
def test_property_size_on_float_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.float_prop = 4.0;
|
|
"""
|
|
)
|
|
|
|
float_bytes = get_bytes(memgraph, "float_prop")
|
|
|
|
# 1 byte metadata, 1 byte prop id + payload size 8 bytes to store the float
|
|
assert float_bytes == 10
|
|
|
|
|
|
def test_property_size_on_string_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.str_prop = 'str_value';
|
|
"""
|
|
)
|
|
|
|
str_bytes = get_bytes(memgraph, "str_prop")
|
|
|
|
# 1 byte metadata
|
|
# 1 byte prop id
|
|
# - the payload size contains the amount of bytes stored for the size in the next sequence
|
|
# X bytes for the length of the string (1, 2, 4 or 8 bytes) -> "str_value" has 1 byte for the length of 9
|
|
# Y bytes for the string content -> 9 bytes for "str_value"
|
|
assert str_bytes == 12
|
|
|
|
|
|
def test_property_size_on_list_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.list_prop = [1, 2, 3];
|
|
"""
|
|
)
|
|
|
|
list_bytes = get_bytes(memgraph, "list_prop")
|
|
|
|
# 1 byte metadata
|
|
# 1 byte prop id
|
|
# - the payload size contains the amount of bytes stored for the size of the list
|
|
# X bytes for the size of the list (1, 2, 4 or 8 bytes)
|
|
# for each list element:
|
|
# - 1 byte for the metadata
|
|
# - the amount of bytes for the payload of the type (a small int is 1 additional byte)
|
|
# in this case 1 + 1 + 3 * (1 + 1)
|
|
assert list_bytes == 9
|
|
|
|
|
|
def test_property_size_on_map_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.map_prop = {key1: 'value', key2: 4};
|
|
"""
|
|
)
|
|
|
|
map_bytes = get_bytes(memgraph, "map_prop")
|
|
|
|
# 1 byte metadata
|
|
# 1 byte prop id
|
|
# - the payload size contains the amount of bytes stored for the size of the map
|
|
# X bytes for the size of the map (1, 2, 4 or 8 bytes - in this case 1)
|
|
# for every map element:
|
|
# - 1 byte for metadata
|
|
# - 1, 2, 4 or 8 bytes for the key length (read from the metadata payload) -> this case 1
|
|
# - Y bytes for the key content -> this case 4
|
|
# - Z amount of bytes for the type
|
|
# - for 'value' -> 1 byte for size and 5 for length
|
|
# - for 4 -> 1 byte for content read from payload
|
|
# total: 1 + 1 + (1 + 1 + 4 + (1 + 5)) + (1 + 1 + 4 + (1))
|
|
assert map_bytes == 22
|
|
|
|
|
|
def test_property_size_on_date_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.date_prop = date('2023-01-01');
|
|
"""
|
|
)
|
|
|
|
date_bytes = get_bytes(memgraph, "date_prop")
|
|
|
|
# 1 byte metadata (to see that it's temporal data)
|
|
# 1 byte prop id
|
|
# 1 byte metadata
|
|
# - type is again the same
|
|
# - id field contains the length of the specific temporal type (1, 2, 4 or 8 bytes) -> probably always 1
|
|
# - payload field contains the length of the microseconds (1, 2, 4, or 8 bytes) -> probably always 8
|
|
assert date_bytes == 12
|
|
|
|
|
|
def test_property_size_on_local_time_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.localtime_prop = localtime('23:00:00');
|
|
"""
|
|
)
|
|
|
|
local_time_bytes = get_bytes(memgraph, "localtime_prop")
|
|
|
|
# 1 byte metadata (to see that it's temporal data)
|
|
# 1 byte prop id
|
|
# 1 byte metadata
|
|
# - type is again the same
|
|
# - id field contains the length of the specific temporal type (1, 2, 4 or 8 bytes) -> probably always 1
|
|
# - payload field contains the length of the microseconds (1, 2, 4, or 8 bytes) -> probably always 8
|
|
assert local_time_bytes == 12
|
|
|
|
|
|
def test_property_size_on_local_date_time_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.localdatetime_prop = localdatetime('2022-01-01T23:00:00');
|
|
"""
|
|
)
|
|
|
|
local_date_time_bytes = get_bytes(memgraph, "localdatetime_prop")
|
|
|
|
# 1 byte metadata (to see that it's temporal data)
|
|
# 1 byte prop id
|
|
# 1 byte metadata
|
|
# - type is again the same
|
|
# - id field contains the length of the specific temporal type (1, 2, 4 or 8 bytes) -> probably always 1
|
|
# - payload field contains the length of the microseconds (1, 2, 4, or 8 bytes) -> probably always 8
|
|
assert local_date_time_bytes == 12
|
|
|
|
|
|
def test_property_size_on_duration_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node)
|
|
SET n.duration_prop = duration('P5DT2M2.33S');
|
|
"""
|
|
)
|
|
|
|
duration_bytes = get_bytes(memgraph, "duration_prop")
|
|
|
|
# 1 byte metadata (to see that it's temporal data)
|
|
# 1 byte prop id
|
|
# 1 byte metadata
|
|
# - type is again the same
|
|
# - id field contains the length of the specific temporal type (1, 2, 4 or 8 bytes) -> probably always 1
|
|
# - payload field contains the length of the microseconds (1, 2, 4, or 8 bytes) -> probably always 8
|
|
assert duration_bytes == 12
|
|
|
|
|
|
def test_property_size_on_nonexistent_prop(memgraph):
|
|
memgraph.execute(
|
|
"""
|
|
CREATE (n:Node);
|
|
"""
|
|
)
|
|
|
|
nonexistent_bytes = get_bytes(memgraph, "nonexistent_prop")
|
|
|
|
assert nonexistent_bytes == 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(pytest.main([__file__, "-rA"]))
|