(pre-define (dg-relation-data-ordinal-set relation-data value) (array-set-index (convert-type relation-data dg-ordinal-t*) 0 value)) (pre-define (dg-relation-data-id-set relation-data value) (array-set-index (convert-type (+ 1 (convert-type relation-data dg-ordinal-t*)) dg-id-t*) 0 value)) (pre-define (dg-define-relation-key name) (define-array name dg-id-t (2) 0 0)) (pre-define (dg-define-relation-data name) (define-array name b8 ((+ dg-size-octets-ordinal dg-size-octets-id))) (memset name 0 (+ dg-size-octets-ordinal dg-size-octets-id))) (pre-define (dg-define-relation-record name) (define name dg-relation-record-t (struct-literal 0 0 0 0))) (pre-define (dg-relation-records-add! target record target-temp) (dg-pointer-allocation-set target (dg-relation-records-add target record) target-temp)) (define (dg-mdb-left->right-seek-right left->right id-right) (status-t MDB-cursor* dg-id-t) "search data until the given id-right has been found" status-init dg-mdb-introduce-val-relation-key dg-mdb-introduce-val-relation-data (dg-mdb-cursor-get! left->right val-relation-key val-relation-data MDB-GET-CURRENT) (label each-data (if dg-mdb-status-success? (if (= id-right (dg-mdb-val-relation-data->id val-relation-data)) (return status) (begin (dg-mdb-cursor-next-dup! left->right val-relation-key val-relation-data) (goto each-data))) dg-mdb-status-require-notfound)) (label exit (return status))) (define (dg-relation-ensure txn left right label ordinal-generator ordinal-generator-state) (status-t dg-txn-t* dg-ids-t* dg-ids-t* dg-ids-t* dg-relation-ordinal-generator-t b0*) status-init (define right-pointer dg-ids-t* label-pointer dg-ids-t* id-left dg-id-t id-right dg-id-t id-label dg-id-t) (define ordinal dg-ordinal-t (if* (and (not ordinal-generator) ordinal-generator-state) (set ordinal (deref (convert-type ordinal-generator-state dg-ordinal-t*))) 0)) (dg-define-relation-key relation-key) (dg-define-relation-data relation-data) dg-mdb-introduce-val-id dg-mdb-introduce-val-id-2 dg-mdb-introduce-val-relation-key dg-mdb-introduce-val-relation-data (dg-mdb-introduce-cursor-3 txn left->right right->left label->left) (while left (set id-left (dg-ids-first left) label-pointer label) (while label-pointer (set id-label (dg-ids-first label-pointer) right-pointer right) (struct-set val-id-2 mv-data (address-of id-label)) (while right-pointer (set id-right (dg-ids-first right-pointer)) (array-set-index relation-key 0 id-right 1 id-label) (struct-set val-relation-key mv-data relation-key) (struct-set val-id mv-data (address-of id-left)) (dg-mdb-cursor-get! right->left val-relation-key val-id MDB-GET-BOTH) (if (= MDB-NOTFOUND status.id) (begin (dg-mdb-status-require! (mdb-cursor-put right->left (address-of val-relation-key) (address-of val-id) 0)) (dg-mdb-status-require! (mdb-cursor-put label->left (address-of val-id-2) (address-of val-id) 0)) (array-set-index relation-key 0 id-left 1 id-label) (if ordinal-generator (set ordinal ((deref ordinal-generator) ordinal-generator-state))) (dg-relation-data-ordinal-set relation-data ordinal) (dg-relation-data-id-set relation-data id-right) (struct-set val-relation-data mv-data relation-data) (dg-mdb-status-require! (mdb-cursor-put left->right (address-of val-relation-key) (address-of val-relation-data) 0))) (if (not dg-mdb-status-success?) (status-set-group-goto dg-status-group-lmdb))) (set right-pointer (dg-ids-rest right-pointer))) (set label-pointer (dg-ids-rest label-pointer))) (set left (dg-ids-rest left))) (label exit (dg-mdb-cursor-close-3 left->right right->left label->left) (return status))) (sc-include-once sph-dg-relation-delete "relation-delete" sph-dg-relation-read "relation-read" sph-dg-debug-relation "lib/debug-relation")