Skip to content

Fix/542 compact missing properties - #553

Merged
StevenBtw merged 3 commits into
release/0.6.0from
fix/542-compact-missing-properties
Oct 4, 2026
Merged

StevenBtw merged 3 commits into
release/0.6.0from
fix/542-compact-missing-properties

Conversation

@StevenBtw

@StevenBtw StevenBtw commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

compact() stored a property that a node or edge lacked as the column's empty value ('', 0, 0.0, false): it read back as that value, keys() listed it, IS NULL did not match it and filters such as = 0 did. Compact columns now record which rows have a value, and reads, searches and zone maps skip the others. The CompactStore section moves to v4 to store this; v1 to v3 sections still load, with every row present as before.

Fixes #542

How was it tested?

  • New crates/grafeo-engine/tests/compact_missing_properties.rs: every column type (string, non-negative and negative integer, float, bool, vector) on nodes and edges, after compact(), after a second compact() and after a reopen.
  • Unit tests in column.rs and section.rs: masked reads and zone maps, no bitmap when every row is present, a v4 round trip, and v3 sections still loading.
  • cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, rustdoc with -D warnings, cargo test --all-features --workspace (13,826 passed), and cargo check for the edge, lpg+gql, embedded, full and gql profiles.

AI assistance

AI tools used: Claude Code (implementation and tests)

  • I have read every line of this change, I understand it, and I can explain and defend it in review.

Summary by cubic

Fixes compact() so missing properties stay missing instead of being read as empty values and listed by keys(). Missing properties now remain missing after reopen; databases compacted by 0.5.44 or earlier keep the values they stored.

Written for commit 5b22203. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 132 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/grafeo-engine/src/transaction/manager.rs
Comment thread .github/workflows/update-grafeo-web.yml
Comment thread crates/grafeo-engine/tests/direct_api.rs Outdated
Comment thread .github/workflows/ci.yml
Comment thread crates/grafeo-core/src/graph/lpg/store/tests.rs
Comment thread crates/grafeo-core/src/index/text/inverted_index.rs
Comment thread docs/versioning.md Outdated
Comment thread crates/grafeo-engine/tests/commit_completion.rs Outdated
Comment thread crates/grafeo-core/src/execution/parallel/morsel.rs
@StevenBtw
StevenBtw changed the base branch from main to release/0.6.0 October 4, 2026 17:56

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread CHANGELOG.md
Compact columns record which rows have a value; reads, searches and zone maps
skip the others, and the CompactStore section (v4) stores it. v1 to v3 sections
still load.
The plain-read commit test waits for its read to finish instead of 300 ms, an
assert in a loop names its case, and the pip pinning note gives the exact range.
@StevenBtw
StevenBtw merged commit d392d23 into release/0.6.0 Oct 4, 2026
10 of 13 checks passed
@StevenBtw
StevenBtw deleted the fix/542-compact-missing-properties branch October 4, 2026 18:09
@codspeed

codspeed Bot commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Merging this PR will not alter performance

✅ 70 untouched benchmarks


Comparing fix/542-compact-missing-properties (be79048) with release/0.6.0 (6420374)1

Open in CodSpeed

Footnotes

  1. No successful run was found on release/0.6.0 (be79048) during the generation of this report, so dfd79cf was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Benchmark Comparison (base vs PR)

Measured on the same runner to eliminate hardware variance.

Full results
group                                                 base                                   pr
-----                                                 ----                                   --
_memory_flush                                         1.00      0.6±0.01ns        ? ?/sec    1.00      0.6±0.00ns        ? ?/sec
adjacency_insert_1000                                 1.02     31.0±0.62µs        ? ?/sec    1.00     30.4±0.22µs        ? ?/sec
adjacency_lookup                                      1.04     68.9±1.47µs        ? ?/sec    1.00     66.6±0.54µs        ? ?/sec
brute_force_knn_1k_k10                                1.02     35.3±0.37µs        ? ?/sec    1.00     34.5±0.47µs        ? ?/sec
bump_allocate_1000                                    1.00   968.4±14.75ns        ? ?/sec    1.03  1000.1±13.58ns        ? ?/sec
compact/edges_from_outgoing_10K                       1.00    671.5±8.04µs        ? ?/sec    1.02    682.8±5.45µs        ? ?/sec
compact/find_nodes_by_property/dict_eq/1000           1.15  1623.9±31.54ns        ? ?/sec    1.00  1411.6±10.83ns        ? ?/sec
compact/find_nodes_by_property/dict_eq/10000          1.30     10.7±0.27µs        ? ?/sec    1.00      8.2±0.14µs        ? ?/sec
compact/find_nodes_by_property/dict_eq/100000         1.31    107.3±0.92µs        ? ?/sec    1.00     82.2±1.21µs        ? ?/sec
compact/find_nodes_by_property/int_eq/1000            1.00      2.5±0.03µs        ? ?/sec    1.02      2.5±0.04µs        ? ?/sec
compact/find_nodes_by_property/int_eq/10000           1.01     20.8±0.18µs        ? ?/sec    1.00     20.7±0.11µs        ? ?/sec
compact/find_nodes_by_property/int_eq/100000          1.00    202.8±1.20µs        ? ?/sec    1.00    202.6±1.07µs        ? ?/sec
compact/find_nodes_in_range/score_gt_7/1000           1.00      5.1±0.08µs        ? ?/sec    1.02      5.2±0.08µs        ? ?/sec
compact/find_nodes_in_range/score_gt_7/10000          1.00     45.2±0.66µs        ? ?/sec    1.00     45.5±0.57µs        ? ?/sec
compact/find_nodes_in_range/score_gt_7/100000         1.00    443.0±9.06µs        ? ?/sec    1.00    443.1±8.85µs        ? ?/sec
compact/get_node_property_10K                         1.00    251.5±2.54µs        ? ?/sec    1.05    263.6±5.46µs        ? ?/sec
compact/nodes_by_label_100K                           1.01     16.2±0.32µs        ? ?/sec    1.00     16.1±0.33µs        ? ?/sec
distance/cosine_384d                                  1.00     58.1±2.95ns        ? ?/sec    1.04     60.6±0.52ns        ? ?/sec
distance/dot_product_384d                             1.00     40.5±0.14ns        ? ?/sec    1.27     51.5±0.33ns        ? ?/sec
distance/euclidean_384d                               1.00     44.5±0.27ns        ? ?/sec    1.27     56.6±0.78ns        ? ?/sec
edge_filter/regression_edge_filter_any                1.00    751.6±2.59µs        ? ?/sec    1.00    749.9±3.33µs        ? ?/sec
edge_filter/regression_edge_filter_follows            1.01    753.5±1.97µs        ? ?/sec    1.00    746.4±3.02µs        ? ?/sec
edge_filter/regression_edge_filter_single             1.00    751.1±4.43µs        ? ?/sec    1.01    754.9±2.66µs        ? ?/sec
epoch_arena_allocate_1000                             1.00      7.5±0.09µs        ? ?/sec    1.00      7.5±0.04µs        ? ?/sec
hash_index_insert_1000                                1.00     52.0±1.20µs        ? ?/sec    1.00     52.1±0.34µs        ? ?/sec
hash_index_lookup                                     1.00     12.9±0.17µs        ? ?/sec    1.03     13.2±0.15µs        ? ?/sec
hnsw_insert_500                                       1.01     38.8±0.78ms        ? ?/sec    1.00     38.4±0.99ms        ? ?/sec
hnsw_search_2k_k10                                    1.01    142.1±3.39µs        ? ?/sec    1.00    141.3±1.45µs        ? ?/sec
memory_10k_nodes_50k_edges                            1.00     51.5±1.88ms        ? ?/sec    1.14     58.8±1.28ms        ? ?/sec
memory_1k_nodes_5k_edges                              1.01      3.7±0.03ms        ? ?/sec    1.00      3.6±0.01ms        ? ?/sec
memory_after_100_queries                              1.01     44.2±0.29ms        ? ?/sec    1.00     43.6±0.38ms        ? ?/sec
memory_empty_db                                       1.00     72.5±0.24µs        ? ?/sec    1.00     72.8±0.60µs        ? ?/sec
memory_vector_index_1k                                1.00     96.0±0.20ms        ? ?/sec    1.00     96.2±0.35ms        ? ?/sec
multihop/regression_1hop_1k                           1.00    404.1±4.26µs        ? ?/sec    1.10    444.2±1.41µs        ? ?/sec
multihop/regression_1hop_5k                           1.00      2.2±0.03ms        ? ?/sec    1.13      2.5±0.04ms        ? ?/sec
multihop/regression_2hop_1k                           1.00    427.7±2.04µs        ? ?/sec    1.02    434.2±1.61µs        ? ?/sec
multihop/regression_3hop_1k                           1.00    475.3±1.75µs        ? ?/sec    1.03    487.3±3.58µs        ? ?/sec
multihop/regression_fan_out_5k                        1.01      4.2±0.22ms        ? ?/sec    1.00      4.2±0.20ms        ? ?/sec
object_pool_get_put_1000                              1.12      2.4±0.08µs        ? ?/sec    1.00      2.2±0.01µs        ? ?/sec
product_quantization/asymmetric_distance_128d_pq8     1.00     51.9±0.65µs        ? ?/sec    1.00     52.1±0.78µs        ? ?/sec
product_quantization/build_distance_table_128d_pq8    1.00     51.9±0.61µs        ? ?/sec    1.00     52.0±0.75µs        ? ?/sec
product_quantization/distance_with_table_pq8          1.00      6.2±0.05ns        ? ?/sec    1.00      6.1±0.05ns        ? ?/sec
product_quantization/quantize_128d_pq8                1.00     20.9±0.42µs        ? ?/sec    1.00     20.8±0.17µs        ? ?/sec
product_quantization/train_500x128_pq8                1.00     49.8±0.45ms        ? ?/sec    1.00     49.6±0.15ms        ? ?/sec
query_1hop_pattern                                    1.03    411.2±4.96µs        ? ?/sec    1.00    400.9±8.13µs        ? ?/sec
query_2hop_pattern                                    1.04    441.0±2.77µs        ? ?/sec    1.00   424.7±12.71µs        ? ?/sec
query_count_all                                       1.00     53.0±0.83µs        ? ?/sec    1.03     54.7±1.17µs        ? ?/sec
query_fan_out_expand_1k                               1.00    822.5±8.84µs        ? ?/sec    1.00    822.8±8.08µs        ? ?/sec
query_filter_range                                    1.00    379.8±2.67µs        ? ?/sec    1.03    391.1±2.74µs        ? ?/sec
query_insert_single_node                              1.00     14.3±0.93µs        ? ?/sec    1.00     14.3±0.64µs        ? ?/sec
query_node_lookup_by_property                         1.01    411.3±5.57µs        ? ?/sec    1.00    407.3±4.12µs        ? ?/sec
rdf_chain_join                                        1.00    392.3±8.74µs        ? ?/sec    1.01    395.7±7.39µs        ? ?/sec
rdf_count_all                                         1.01    179.8±2.27µs        ? ?/sec    1.00    177.7±3.72µs        ? ?/sec
rdf_filter_string                                     1.02    304.7±5.92µs        ? ?/sec    1.00    299.6±2.57µs        ? ?/sec
rdf_insert_single_triple                              1.03      4.1±1.04ms        ? ?/sec    1.00      4.0±1.12ms        ? ?/sec
rdf_join_chain_10k                                    1.00      4.8±0.18ms        ? ?/sec    1.11      5.3±0.27ms        ? ?/sec
rdf_join_chain_2hop_10k                               1.04     11.9±0.75ms        ? ?/sec    1.00     11.5±0.45ms        ? ?/sec
rdf_join_optional_10k                                 1.06     12.1±0.77ms        ? ?/sec    1.00     11.4±0.80ms        ? ?/sec
rdf_join_star_2_10k                                   1.00     14.3±0.45ms        ? ?/sec    1.10     15.7±0.75ms        ? ?/sec
rdf_join_star_3_10k                                   1.00     27.0±0.64ms        ? ?/sec    1.08     29.0±1.21ms        ? ?/sec
rdf_join_star_4_10k                                   1.00     35.2±1.34ms        ? ?/sec    1.07     37.8±1.90ms        ? ?/sec
rdf_optional_pattern                                  1.00    855.0±8.59µs        ? ?/sec    1.00    856.0±8.73µs        ? ?/sec
rdf_single_pattern_lookup                             1.02      4.7±0.20µs        ? ?/sec    1.00      4.7±0.04µs        ? ?/sec
rdf_star_join_2pattern                                1.00   1106.0±9.31µs        ? ?/sec    1.00  1106.7±18.47µs        ? ?/sec
rdf_star_join_3pattern                                1.00      2.0±0.01ms        ? ?/sec    1.01      2.0±0.11ms        ? ?/sec
repeated/regression_repeat_cached_500                 1.00    191.4±0.47ms        ? ?/sec    1.10    211.3±3.80ms        ? ?/sec
repeated/regression_repeat_unique_100                 1.00     38.5±0.17ms        ? ?/sec    1.07     41.1±0.16ms        ? ?/sec
repeated/regression_repeat_unique_500                 1.00    197.4±0.39ms        ? ?/sec    1.08    213.7±0.65ms        ? ?/sec
scalar_quantization/distance_u8_384d                  1.00   532.5±10.49ns        ? ?/sec    1.00    530.6±4.52ns        ? ?/sec
scalar_quantization/quantize_384d                     1.00    323.1±2.39ns        ? ?/sec    1.00    323.6±1.69ns        ? ?/sec
scalar_quantization/train_1000x384                    1.00    110.6±0.55µs        ? ?/sec    1.04    115.5±2.05µs        ? ?/sec
snapshot_export_50n_100e                              1.00     92.7±0.66µs        ? ?/sec    1.00     92.5±2.10µs        ? ?/sec
snapshot_import_50n_100e                              1.01    216.4±3.08µs        ? ?/sec    1.00    213.9±3.15µs        ? ?/sec
snapshot_roundtrip_50n_100e                           1.02    328.6±4.03µs        ? ?/sec    1.00    322.3±3.89µs        ? ?/sec
value_decode_mixed_6                                  1.00    260.7±3.32ns        ? ?/sec    1.05    272.8±2.21ns        ? ?/sec
value_encode_mixed_6                                  1.00    173.8±1.13ns        ? ?/sec    1.00    173.4±2.81ns        ? ?/sec

No performance regressions above configured thresholds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant