The loader: a node table's columns, the edges between them, one file - #2
Merged
Merged
Conversation
A statement writes a row at a time, and the first row of a table that does not exist yet has to be written out rather than parameterized, because a value that is worked out says nothing about the column it would go in. A rel table is worse than that: no statement makes one, since an INSERT names the two tables an edge joins only for the edge it is writing. That left the client unable to build the thing the database is for, and left Rel and Path with nothing in the suite to read. zudb.load is the other shape, and it is the one the bulk loader has: a node table's columns whole, an edge list whole, one file written once. Columns hold booleans, integers, floats, strings, dates, times, datetimes or durations, one kind to a column, settled by the first value and checked against every value after it. Edges name rows by position, counting from zero, because at load time a row has no other name, and an edge naming a row the table has not got is refused where it is written rather than invented or dropped. Either half may be left out: a graph with no properties is a graph, and so is one with no edges. The path must not exist, since a load builds a database rather than adding to one. Reading the Python objects needs the GIL and the write does not, so the GIL is released around the sort, the graph and the columns, which is the whole cost of a load. Two hundred thousand nodes and as many edges take about six hundred milliseconds and leave the main thread free the whole time, which is what the new threading test measures. Two things found while writing it. Path.every was inside pymethods, so a helper that exists to write two getters was reachable from Python as a third method nobody documented; it is a plain impl now. And Rel.ord is the edge's place in the load order, which is where its properties sit, not its ordinal among the edges joining that pair, so the class doc says what the engine does. The refusals name the column and the row and read as sentences, and every one of them is a test.
20 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A statement writes a row at a time, and the first row of a table that does not exist yet has to be written out rather than parameterized, because a value that is worked out says nothing about the column it would go in. A rel table is worse than that: no statement makes one, since an
INSERTnames the two tables an edge joins only for the edge it is writing. That left this client unable to build the thing the database is for, and leftRelandPathwith nothing in the suite to read.zudb.loadis the other shape, and it is the one the bulk loader has: a node table's columns whole, an edge list whole, one file written once.Columns hold booleans, integers, floats, strings, dates, times, datetimes or durations, one kind to a column, settled by the first value and checked against every value after it. Edges name rows by position, counting from zero, because at load time a row has no other name, and an edge naming a row the table has not got is refused where it is written rather than invented or dropped. Either half may be left out: a graph with no properties is a graph, and so is one with no edges. The path must not exist, since a load builds a database rather than adding to one, and overwriting would be the worst possible reading of the call.
Reading the Python objects needs the GIL and the write does not, so the GIL is released around the sort, the graph and the columns, which is the whole cost of a load. Two hundred thousand nodes and as many edges take about six hundred milliseconds and leave the main thread free the whole time, which is what the new threading test measures.
Two things found while writing it.
Path.everywas insidepymethods, so a helper that exists to write two getters was reachable from Python as a third method nobody documented; it is a plainimplnow. AndRel.ordis the edge's place in the load order, which is where its properties sit, not its ordinal among the edges joining that pair, so the class doc now says what the engine does.Thirty-four new tests, and the suite is a hundred and eighteen. The interesting ones are the first in this repository to read a real
Reland a realPath, including a two-hop walk whose elements alternate node, edge, node. The refusals name the column and the row and read as sentences, and every one of them is a test.Local gates green:
ruff check,ruff format --check,cargo fmt --all --check,cargo clippy --all-targets -D warnings,pytest.Toward tamnd/zu#168.