# 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"]))