===============================================================================
 ISQL VLR SUBSYSTEM - API NAMES  (task #72, step 2 of 3)            rev 0, draft
 Companion to VLR_ARCHITECTURE.txt. Signatures are the contract; bodies come
 in step 3 (implementation). Conventions follow the existing engine: KINT64 for
 offsets/handles, INTERNET_SQL_OBJECT *obj threaded through, 0/NULL = failure,
 return values RELAYED by the legacy layer (vlrlib owns all VLR internals).
===============================================================================

FILES
 - vlrlib/vlr.h        public header (types + prototypes below)
 - vlrlib/vlr.c        lifecycle + record ops + field access
 - vlrlib/vlrfree.c    free-list allocator + compaction
 - vlrlib/vlrindex.c   .vlx persisted recno->offset B-tree
 - vlrlib/vlrcrypt.c   key hierarchy + record payload encrypt/decrypt
 - vlrlib/vlrdispatch.c the legacy<->vlrlib redirection glue (section 7)


1. CORE TYPES  (vlr.h)
-------------------------------------------------------------------------------
 #define VLR_RECFMT_FIXED  'F'
 #define VLR_RECFMT_VLR    'V'          /* tabletype record-format marker      */

 #define VLR_FLAG_NULL     0x01         /* per-field flags byte                */

 typedef struct VLR_HDR_EXT {           /* fixed region appended to TABLE_HEADER*/
     KINT64  freelist_head;             /* first free extent, 0 = none         */
     KINT64  highwater;                 /* append point (EOF of live area)     */
     KINT64  record_count;              /* live records                        */
     KINT64  free_bytes;                /* sum of free extents (compaction gate)*/
     KINT64  next_recno;                /* recno sequence                      */
     char    vlx_name[64];              /* companion index filename            */
     char    encrypted;                 /* payload encryption on/off           */
     char    vlx_encrypted;             /* .vlx encryption on/off              */
 } VLR_HDR_EXT;

 typedef struct VLR_TABLE  VLR_TABLE;   /* opaque handle (open table)          */
 typedef struct VLR_CURSOR VLR_CURSOR;  /* opaque scan cursor                  */

 typedef struct VLR_RECBUF {            /* an in-memory record being built/read*/
     char   *buf;                       /* packed field area                   */
     KINT64  len;                       /* used bytes                          */
     KINT64  cap;                       /* allocated bytes                     */
     KINT64  recno;                     /* set after insert / on fetch         */
     int    *field_off;                 /* per-field offset cache (O(1) access)*/
     int     nfields;
 } VLR_RECBUF;

 typedef struct VLR_FREE_EXTENT { KINT64 offset; KINT64 len; KINT64 next; }
     VLR_FREE_EXTENT;

 typedef struct VLR_STATS {             /* vlr_freespace_stats output          */
     KINT64 file_bytes, live_bytes, free_bytes, record_count, free_extents;
     double frag_ratio;                 /* free_bytes / file_bytes             */
 } VLR_STATS;


2. LIFECYCLE  (vlr.c)
-------------------------------------------------------------------------------
 VLR_TABLE *vlr_create (INTERNET_SQL_OBJECT *obj, const char *tablepath,
                        FIELDOBJECT *fields, int nfields, int encrypted);
 VLR_TABLE *vlr_open   (INTERNET_SQL_OBJECT *obj, const char *tablepath);
 int        vlr_close  (VLR_TABLE *t);
 int        vlr_drop   (INTERNET_SQL_OBJECT *obj, const char *tablepath);
 int        vlr_is_vlr (const char *tablepath);   /* peek header tabletype     */


3. RECORD OPERATIONS  (vlr.c)
-------------------------------------------------------------------------------
 KINT64 vlr_insert (VLR_TABLE *t, VLR_RECBUF *rec);       /* -> recno, 0 = fail */
 int    vlr_fetch  (VLR_TABLE *t, KINT64 recno, VLR_RECBUF *out);
 int    vlr_update (VLR_TABLE *t, KINT64 recno, VLR_RECBUF *rec); /* in-place|relocate*/
 int    vlr_delete (VLR_TABLE *t, KINT64 recno);
 /* internal on-disk record helpers */
 static int    vlr_read_prologue (VLR_TABLE*, KINT64 off, KINT64 *reclen, KINT64 *next);
 static KINT64 vlr_write_record  (VLR_TABLE*, VLR_RECBUF*, KINT64 at_off);


4. CURSOR / SCAN  (vlr.c) - follows next_record_offset chain
-------------------------------------------------------------------------------
 VLR_CURSOR *vlr_scan_open  (VLR_TABLE *t);
 int         vlr_scan_next  (VLR_CURSOR *c, VLR_RECBUF *out);  /* 1=row,0=end   */
 int         vlr_scan_close (VLR_CURSOR *c);


5. FIELD ACCESS  (vlr.c) - packs/unpacks the length-prefixed field area
-------------------------------------------------------------------------------
 /* build a record (packing) */
 int vlr_rec_init      (VLR_RECBUF *r, int nfields);
 int vlr_rec_put_field (VLR_RECBUF *r, int fieldno, const char *val, KINT64 len);
 int vlr_rec_put_null  (VLR_RECBUF *r, int fieldno);
 int vlr_rec_free      (VLR_RECBUF *r);
 /* read a fetched record (unpacking; builds/uses field_off cache) */
 char  *vlr_field_get    (VLR_RECBUF *r, int fieldno, KINT64 *len_out);
 int    vlr_field_is_null(VLR_RECBUF *r, int fieldno);
 KINT64 vlr_field_len    (VLR_RECBUF *r, int fieldno);
 /* varint length codec (shared) */
 int    vlr_varint_put (char *dst, KINT64 v);      /* -> bytes written          */
 int    vlr_varint_get (const char *src, KINT64 *v);/* -> bytes consumed         */


6. .vlx INDEX  (vlrindex.c) - persisted CLRS B-tree, recno -> offset
-------------------------------------------------------------------------------
 int    vlr_index_open   (VLR_TABLE *t);               /* open/create <table>.vlx*/
 int    vlr_index_close  (VLR_TABLE *t);
 KINT64 vlr_index_find   (VLR_TABLE *t, KINT64 recno); /* -> offset, 0 = absent  */
 int    vlr_index_put    (VLR_TABLE *t, KINT64 recno, KINT64 offset);
 int    vlr_index_del    (VLR_TABLE *t, KINT64 recno);
 int    vlr_index_rebuild(VLR_TABLE *t);   /* from the next_offset live chain    */


7. FREE-SPACE / COMPACTION  (vlrfree.c)
-------------------------------------------------------------------------------
 KINT64 vlr_alloc (VLR_TABLE *t, KINT64 need);   /* best-fit -> offset (+bumps HW)*/
 int    vlr_free  (VLR_TABLE *t, KINT64 offset, KINT64 len); /* + coalesce        */
 int    vlr_compact       (VLR_TABLE *t);         /* WRITE-locked, rebuilds vlx    */
 int    vlr_maybe_compact (VLR_TABLE *t);         /* auto if free_bytes>=30%*file  */
 int    vlr_freespace_stats(VLR_TABLE *t, VLR_STATS *out);


8. ENCRYPTION  (vlrcrypt.c) - master -> table -> per-record IV
-------------------------------------------------------------------------------
 int  vlr_key_set        (VLR_TABLE *t, const unsigned char *master, int mlen);
 static int vlr_table_key_unwrap(VLR_TABLE *t);   /* master decrypts header key */
 static int vlr_rec_encrypt(VLR_TABLE *t, KINT64 recno, char *payload, KINT64 len);
 static int vlr_rec_decrypt(VLR_TABLE *t, KINT64 recno, char *payload, KINT64 len);
 /* prologue (reclen,next_offset) + varint lengths stay PLAINTEXT; only the
    field-value payload is ciphertext (see architecture section 9). */


9. LEGACY <-> vlrlib DISPATCH  (vlrdispatch.c) - the redirection boundary
-------------------------------------------------------------------------------
 The legacy TABLEOBJECT path calls these thin shims; each checks the table's
 record format and, if VLR, forwards to vlrlib and RELAYS ONLY THE RETURN VALUE
 (legacy owns nothing VLR-internal). If FIXED, it runs the existing code.

 int    IsqlTableIsVlr   (TABLEOBJECT *tbl);      /* header tabletype == 'V'    */
 KINT64 IsqlInsertRecord (TABLEOBJECT *tbl, ...); /* -> vlr_insert when VLR     */
 int    IsqlFetchRecord  (TABLEOBJECT *tbl, KINT64 recno, ...); /* -> vlr_fetch */
 int    IsqlUpdateRecord (TABLEOBJECT *tbl, KINT64 recno, ...); /* -> vlr_update*/
 int    IsqlDeleteRecord (TABLEOBJECT *tbl, KINT64 recno);      /* -> vlr_delete*/
 int    IsqlScanRecord   (TABLEOBJECT *tbl, ...);              /* -> vlr_scan_* */
 /* FindTransRecNo / the record-locate path gains: if VLR, use vlr_index_find. */


10. CREATE-TABLE / CONFIG SURFACE
-------------------------------------------------------------------------------
 SQL:   CREATE TABLE t (...) ( recordformat = vlr [, encrypt = on] )
        (parsed in SQLCreateTable, sets tabletype='V' in the header)
 CONFIG: GlobalCfg.VlrDefaultOn  (0 default) - when 1, new user tables default
        to VLR without the CREATE option. Catalogs always FIXED regardless.

-------------------------------------------------------------------------------
NEXT (step 3, implementation order):
  1. varint codec + VLR_RECBUF pack/unpack + field access   (pure, unit-testable)
  2. header ext + vlr_create/open/close + single-record insert/fetch (append-only)
  3. .vlx B-tree persist (adapt transaction B-tree) + point lookup
  4. update/delete + free-list allocator + relocate
  5. scan cursor + compaction
  6. dispatch shims + CREATE recordformat=vlr parse
  7. encryption layer
  8. tests: pack/unpack round-trip, grow/shrink/relocate, scan==index counts,
     compaction reclaims, crash-recovery rebuild of vlx.
===============================================================================
