(define-module (tracks nodedb) #:export (nodedb load-nodedb)) (use-modules (ice-9 binary-ports) (ice-9 textual-ports) (rnrs bytevectors) (srfi srfi-2) (srfi srfi-69) (tracks register)) (define nodedb (make-hash-table)) (define (load-nodedb filename) (letrec* ((names (make-vector 65536 #f)) (nodes (make-hash-table)) (read-bv (lambda (port n) (and-let* ((v (get-bytevector-n port n)) ((not (eof-object? v))) ((= (bytevector-length v) n))) v))) (bo (endianness big)) (read-u16 (lambda (port) (and-let* ((v (read-bv port 2))) (bytevector-u16-ref v 0 bo)))) (balance (lambda (n) (- n 32768))) (read-int (lambda (port) (and-let* ((n (read-u16 port))) (balance n)))) (read-node-entry (lambda (port) (and-let* ((v (read-bv port 8)) (b (lambda (v i) (balance (bytevector-u16-ref v i bo)))) (x (b v 0)) (y (b v 2)) (z (b v 4)) (id (b v 6)) (c (list x y z)) (n (+ (ash id -2) 32768)) (p (bit-extract id 0 2))) (and-let* ((s (vector-ref names n))) (hash-table-set! nodes c (vector-ref s p))) #t))) (read-node-definition (lambda (port) (let* ((k (read-u16 port)) (v (get-line port))) (when (and v (hash-table-exists? registered-tracks v)) (vector-set! names k (hash-table-ref registered-tracks v)))))) (read-node-definitions (lambda (port) (do ((i (read-int port) (- i 1))) ((zero? i)) (read-node-definition port)))) (read-nodes (lambda (port) (while (read-node-entry port)))) (read-ndb (lambda (port) (unless (equal? (get-u8 port) 1) (error "wrong nodedb version")) (read-node-definitions port) (read-nodes port) (set! nodedb nodes)))) (call-with-input-file filename read-ndb #:binary #t) (format #t "Node database: ~d tracks in database~%" (hash-table-size nodedb))))