Table of Contents

Class SqliteNcResultStorage

Namespace
Hi.SqliteUtils
Assembly
HiNc.dll

Internal Use Only. The entry to a play's result file (the NC play result recording's P2): one SQLite file a recording, holding the records of the plan's P1 – the machining steps, the strip positions, the executed syntax pieces – and the two briefs of every published step, beside the file's Meta, the NC source files and the pool of the program-zero matrices. Create(string, string) opens a new file for the recorder to write (SqliteNcResultWriter), OpenRead(string) opens a recorded file for a review to read (SqliteNcResultReader); the constants are the file's identity (ApplicationId, SchemaVersion), its chunking and its table names. The file is recognised by its SQLite application_id and gated by its user_version; the step-indexed records live in chunks of StepsPerChunk steps (chunk k holds the steps k * 1024 to k * 1024 + 1023: a record's bin is StepIndex / 1024, its slot its place in the bin), the pieces in chunks of up to PiecesPerChunk pieces closed at PieceChunkRawBytes raw bytes, every chunk Brotli-compressed. Since schema version 2 (the plan's P5) a completed file may also hold the node map of its finished stock: for every strip position the native attachment pointer the stock's nodes carry in the finish.wct (NodeAttachChunkTableName, 1,024 positions a chunk, written once at the completion), by which a review binds the stock's nodes to its rebuilt positions. Nothing here is shared across instances: no default storage, no pooled connection.

A file's life: Create(string, string), the writer's Add* calls while the play runs, then Complete(bool), which makes it one self-contained file marked Finalized; a writer disposed without completing abandons the file, which stays, not finalized, for the recorder to delete. A reader opens either. A writer and a reader each take calls from any thread, one at a time, on a lock of their own, and their exceptions follow one rule: an argument the file's content refuses is an ArgumentException, thrown before anything is written; a writer or reader past its end (completed, disposed) throws ObjectDisposedException; a file that is not a result file, or a chunk this build does not read, is an InvalidDataException; a completion another connection holds back is an InvalidOperationException; SQLite's own failures come out as SqliteException, after which a writer is to be disposed. These three types and the three row types (NcResultMeta, NcResultSourceFile, NcResultStepRow) are marked for internal use as the contract between the play's recorder, this storage and the review of a play, not an application's API, until a sample reads a result file.

public static class SqliteNcResultStorage
Inheritance
SqliteNcResultStorage
Inherited Members

Fields

ApplicationId

The SQLite application_id of a result file, the ASCII of HiNR: a file without it is not a result file.

public const uint ApplicationId = 1214860882

Field Value

uint

ClStripPosChunkTableName

The chunks of the strip positions' program CL, 1,024 positions a chunk.

public const string ClStripPosChunkTableName = "ClStripPosChunk"

Field Value

string

LruChunks

The decoded chunks a reader keeps of each kind (steps, briefs, positions, pieces), the least recently used leaving first.

public const int LruChunks = 8

Field Value

int

MachiningStepTableName

The narrow row of every machining step (NcResultStepRow): the queryable scalars and the two matrix ids.

public const string MachiningStepTableName = "MachiningStep"

Field Value

string

MatrixPoolTableName

The pool of the program-zero matrices: one row a distinct 128-byte matrix (told apart byte for byte, so -0.0 is not +0.0), the two legs of every ProgramZeroLegs holder the steps were built on.

public const string MatrixPoolTableName = "MatrixPool"

Field Value

string

MetaTableName

The key-value table of the file's metadata (NcResultMeta).

public const string MetaTableName = "Meta"

Field Value

string

NcFileTableName

The NC source files: a row a file index, with the first path recorded for it (NcResultSourceFile).

public const string NcFileTableName = "NcFile"

Field Value

string

NodeAttachChunkTableName

The chunks of the finished stock's node map (schema version 2): for every strip position, the 8-byte native attachment pointer the stock's nodes carry in the finish.wct (AddNodeAttachments(ReadOnlySpan<long>)), 1,024 positions a chunk, a position without one left empty.

public const string NodeAttachChunkTableName = "NodeAttachChunk"

Field Value

string

PieceChunkRawBytes

The raw bytes at which a syntax piece chunk closes (4 MB): a threshold, not a cap. A chunk that holds a piece closes before a piece that would take it past this, and closes as soon as it reaches it, so a chunk stays within it unless its one piece is larger – such a piece is a chunk of its own.

public const int PieceChunkRawBytes = 4194304

Field Value

int

PiecesPerChunk

The pieces a syntax piece chunk holds at most: the chunk closes at its 256th piece.

public const int PiecesPerChunk = 256

Field Value

int

SchemaVersion

The schema version this build writes, the file's SQLite user_version; a reader accepts the versions 1 to its own. Version 2 added NodeAttachChunkTableName and the NodeAttachCount row of Meta; a version-1 file reads as one without a node map.

public const int SchemaVersion = 2

Field Value

int

StepBriefChunkTableName

The chunks of the steps' two briefs, 1,024 steps a chunk.

public const string StepBriefChunkTableName = "StepBriefChunk"

Field Value

string

StepChunkTableName

The chunks of the steps' other bytes: the motion, the removal scalars, the collided pairs, the measured time and the pair on the workpiece geometry coordinate, 1,024 steps a chunk.

public const string StepChunkTableName = "StepChunk"

Field Value

string

StepsPerChunk

The steps of one step-indexed chunk: chunk k of a kind (steps, briefs, positions, node keys) holds the kind's records whose step index is in [k * 1024, (k + 1) * 1024), the bin StepIndex / 1024.

public const int StepsPerChunk = 1024

Field Value

int

SyntaxPieceChunkTableName

The chunks of the pieces' entries: a sentence snapshot record and the piece's compact JSON each.

public const string SyntaxPieceChunkTableName = "SyntaxPieceChunk"

Field Value

string

SyntaxPieceIndexTableName

The index row of every syntax piece: its address, its sentence's index and text, and where its entry lies in which chunk.

public const string SyntaxPieceIndexTableName = "SyntaxPieceIndex"

Field Value

string

Methods

Create(string, string)

Internal Use Only. Creates a result file and opens it for writing: the file must not exist (its directory is created when it does not, and a stale -wal, -shm or -journal beside a missing file is deleted, so that SQLite cannot replay an old recording's log into the new file). The file gets its identity (ApplicationId, SchemaVersion as its user_version), WAL mode with synchronous=NORMAL, its tables, and the Meta rows of its creation – SchemaVersion, AppVersion (the HiNc assembly's version), NcName, CreatedUtc and Finalized 0 – committed in a transaction of their own, so a recording abandoned before its first chunk still leaves a file the reader opens; the writer's first batch transaction is open when this returns. The writer records until Complete(bool) turns the file into a single artifact; disposing it before that abandons the recording.

public static SqliteNcResultWriter Create(string databasePath, string ncName)

Parameters

databasePath string

The path of the file to create; the writer keeps its full path.

ncName string

The name the recorder gives the play, written to the file's Meta; may be empty, not null.

Returns

SqliteNcResultWriter

The writer, with its first batch transaction open.

Exceptions

ArgumentNullException

databasePath or ncName is null.

IOException

The file exists already, or its directory cannot be created or a stale side file deleted.

SqliteException

SQLite refused to create or set up the file.

OpenRead(string)

Internal Use Only. Opens a result file read-only, on a connection of its own that is never pooled: the file must exist, carry the ApplicationId, a user_version of 1 to SchemaVersion and a Meta table, else it is refused; its Meta and its NC source files are read now, once. A file that was not completed (a crashed or abandoned recording) opens as long as SQLite can create the WAL side files beside it (the read-only connection may leave them there, empty), with Finalized false and, for a crashed or abandoned recording, the counts null; it reads as far as it was committed, a row whose chunk never reached the file reading as no record. A chunk that is in the file but not one this build reads is refused when it is read, with InvalidDataException.

public static SqliteNcResultReader OpenRead(string databasePath)

Parameters

databasePath string

The path of the file to open; the reader keeps its full path.

Returns

SqliteNcResultReader

The reader.

Exceptions

ArgumentNullException

databasePath is null.

FileNotFoundException

The file does not exist.

InvalidDataException

The file is not a database, is truncated or malformed, or carries another application id, a schema version outside 1 to SchemaVersion or no Meta table; the message names the file and, where SQLite refused it, carries SQLite's message.

SqliteException

SQLite could not open the file (a WAL file in a directory where its side files cannot be created, among others).

OpenWrite(string)

Internal Use Only. Opens a completed result file for an amend (SqliteNcResultAmender, the NC play result recording's P3): the checks of OpenRead(string), then the file must be completed (Finalized), else it is refused – an amend rewrites the chunks of a file that will not be written by a writer again. The connection is read-write and never pooled; the file stays in rollback-journal mode and completed.

public static SqliteNcResultAmender OpenWrite(string databasePath)

Parameters

databasePath string

The path of the file to open; the amender keeps its full path.

Returns

SqliteNcResultAmender

The amender.

Exceptions

ArgumentNullException

databasePath is null.

FileNotFoundException

The file does not exist.

InvalidDataException

The file is not a result file this build reads (the cases of OpenRead(string)).

InvalidOperationException

The file is not completed: a recording still open, crashed or abandoned, or one whose completion failed.

SqliteException

SQLite could not open the file.

TryFinalize(string)

Internal Use Only. Runs the tail of a completion again on a file whose completion was refused after its commit – another connection held the file when the writer tried to checkpoint it or take it out of WAL mode, so the records and the counts are in and Finalized stayed 0: the checkpoint, the switch to rollback-journal mode, Finalized 1, the side files deleted. A file that is completed already answers true with nothing done; a file whose recording never completed (no counts) answers false untouched – its records may end anywhere, and it is the orphan the cleanup deletes; a file another connection holds answers false untouched too.

public static bool TryFinalize(string databasePath)

Parameters

databasePath string

The result file.

Returns

bool

True when the file is completed now.

Exceptions

ArgumentNullException

databasePath is null.

FileNotFoundException

The file does not exist.

InvalidDataException

The file is not a result file this build reads.