2.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2+++ b/lisp/btrfs.asd Thu Oct 12 22:36:34 2023 -0400
2.3@@ -0,0 +1,34 @@
2.4+;;; btrfs.asd --- BTRFS SYSTEMS
2.5+
2.6+;; BTRFS for lisp.
2.7+
2.8+;;; Code:
2.9+(eval-when (:compile-toplevel :load-toplevel :execute)
2.10+ (require :sb-grovel))
2.11+
2.12+(defpackage :btrfs.sys
2.13+ (:use :cl :asdf :sb-grovel :sb-alien))
2.14+
2.15+(in-package :btrfs.sys)
2.16+
2.17+(defsystem "btrfs"
2.18+ :version "0.1.0"
2.19+ :license (:file "LICENSE")
2.20+ :maintainer "ellis <ellis@rwest.io>"
2.21+ :homepage "https://nas-t.net"
2.22+ :bug-tracker "https://lab.rwest.io/comp/startup/nas-t/issues"
2.23+;; :depends-on (:macs :sxp)
2.24+ :in-order-to ((test-op (test-op "btrfs/tests")))
2.25+ :components ((:module "btrfs"
2.26+ :components
2.27+ ((:file "btrfs")))))
2.28+
2.29+(defsystem "btrfs/tests"
2.30+ :version "0.1.0"
2.31+ :license (:file "LICENSE")
2.32+ :maintainer "ellis <ellis@rwest.io>"
2.33+ :homepage "https://nas-t.net"
2.34+ :bug-tracker "https://lab.rwest.io/comp/startup/nas-t/issues"
2.35+ :depends-on (:btrfs :sb-rt :rt)
2.36+ :components ((:file "btrfs/tests"))
2.37+ :perform (test-op (op c) (uiop:symbol-call '#:btrfs.tests '#:run-all-tests)))
3.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2+++ b/lisp/btrfs/btrfs.lisp Thu Oct 12 22:36:34 2023 -0400
3.3@@ -0,0 +1,55 @@
3.4+;;; src/fs/btrfs/btrfs.lisp --- BTRFS common-lisp API
3.5+
3.6+;; This package contains FFI bindings to the BTRFS C libraries libbtrfs and
3.7+;; libbtrfsutil as well as some additional core routines from Rust.
3.8+
3.9+;;; Commentary:
3.10+
3.11+;; BTRFS is a core component of the NAS-T stack. We might even consider NAS-T as a
3.12+;; wrapper around BTRFS APIs in the same we we could say that TrueNAS is a wrapper
3.13+;; around ZFS.
3.14+
3.15+;; NOTE 2023-09-03: currently the app has no concrete use-cases for accessing BTRFS APIs
3.16+;; directly from lisp. This will inevitably change, and we want the bindings for
3.17+;; debugging and experimentation.
3.18+
3.19+;;; Code:
3.20+(defpackage btrfs
3.21+ (:use :cl :sb-alien)
3.22+ (:export
3.23+ :btrfs-shared-objects
3.24+ :btrfs-lib-path
3.25+ :load-btrfs :unload-btrfs
3.26+ :load-btrfsutil :unload-btrfsutil
3.27+ :define-btrfs-ioctl))
3.28+
3.29+(in-package :btrfs)
3.30+
3.31+(eval-when (:compile-toplevel :load-toplevel :execute)
3.32+ (defvar btrfs-shared-objects
3.33+ (list '(:btrfs "/usr/lib/libbtrfs.so")
3.34+ '(:btrfsutil "/usr/lib/libbtrfsutil.so")))
3.35+
3.36+ (defun btrfs-lib-path (lib) (cadr (assoc lib btrfs-shared-objects))))
3.37+
3.38+(defmacro when-lib-exists-p ((sym lib) &body body)
3.39+ `(let ((,sym ,(btrfs-lib-path lib)))
3.40+ (when (uiop:file-exists-p ,sym) ,@body)))
3.41+
3.42+(defun load-btrfs (&optional save)
3.43+ "Open 'libbtrfs' using `dlopen'. exposing the C API to the current Lisp image."
3.44+ (when-lib-exists-p (l :btrfs) (load-shared-object l :dont-save (not save))))
3.45+
3.46+(defun unload-btrfs ()
3.47+ "Close 'libbtrfs' using `dlclose'."
3.48+ (unload-shared-object (btrfs-lib-path :btrfs)))
3.49+
3.50+(defun load-btrfsutil ()
3.51+ "Open 'libbtrfsutil' using `dlopen'. exposing the C API to the current Lisp image."
3.52+ (when-lib-exists-p (l :btrfsutil) (load-shared-object l)))
3.53+
3.54+(defun unload-btrfsutil ()
3.55+ "Close 'libbtrfsutil' using `dlclose'."
3.56+ (unload-shared-object (btrfs-lib-path :btrfsutil)))
3.57+
3.58+(defmacro define-btrfs-ioctl () "Define a wrapper for IOCTLs exposed by BTRFS.")
4.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2+++ b/lisp/btrfs/tests.lisp Thu Oct 12 22:36:34 2023 -0400
4.3@@ -0,0 +1,10 @@
4.4+;;; src/fs/btrfs/tests.lisp --- BTRFS common-lisp tests
4.5+
4.6+;;; Code:
4.7+(defpackage btrfs.tests
4.8+ (:use :cl :rt :btrfs))
4.9+(in-package :btrfs.tests)
4.10+
4.11+(defsuite :btrfs)
4.12+
4.13+(in-suite :btrfs)
5.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2+++ b/lisp/rocksdb.asd Thu Oct 12 22:36:34 2023 -0400
5.3@@ -0,0 +1,32 @@
5.4+;;; rocksdb.asd --- ROCKSDB SYSTEMS
5.5+
5.6+;; rocksdb for lisp.
5.7+
5.8+;;; Commentary:
5.9+
5.10+;; based on Vee's cl-rocksdb: https://github.com/veer66/cl-rocksdb/tree/main
5.11+
5.12+;;; Code:
5.13+(defsystem "rocksdb"
5.14+ :version "0.1.0"
5.15+ :license (:file "LICENSE")
5.16+ :maintainer "ellis <ellis@rwest.io>"
5.17+ :homepage "https://nas-t.net"
5.18+ :bug-tracker "https://lab.rwest.io/comp/startup/nas-t/issues"
5.19+ :depends-on (:macs)
5.20+ :in-order-to ((test-op (test-op "rocksdb/tests")))
5.21+ :components ((:module "rocksdb"
5.22+ :serial t
5.23+ :components
5.24+ ((:file "rocksdb")
5.25+ (:file "rdb")))))
5.26+
5.27+(defsystem "rocksdb/tests"
5.28+ :version "0.1.0"
5.29+ :license (:file "LICENSE")
5.30+ :maintainer "ellis <ellis@rwest.io>"
5.31+ :homepage "https://nas-t.net"
5.32+ :bug-tracker "https://lab.rwest.io/comp/nas-t/issues"
5.33+ :depends-on (:rocksdb :rt)
5.34+ :components ((:file "rocksdb/tests"))
5.35+ :perform (test-op (op c) (uiop:symbol-call '#:rt '#:do-tests :rocksdb)))
6.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2+++ b/lisp/rocksdb/rdb.lisp Thu Oct 12 22:36:34 2023 -0400
6.3@@ -0,0 +1,178 @@
6.4+;;; rdb.lisp --- High-level RocksDB API
6.5+
6.6+;; a thin ORM for working with RocksDB storage.
6.7+
6.8+;; Low-level bindings are in rocksdb.lisp.
6.9+
6.10+;; Commentary:
6.11+
6.12+;; Code:
6.13+(in-package :rocksdb)
6.14+(defpackage :rdb
6.15+ (:use :cl :rocksdb :sb-alien :alien)
6.16+ (:import-from :sb-ext :string-to-octets :octets-to-string)
6.17+ (:export :with-open-db :with-iter
6.18+ :create-iter
6.19+ :iter-key :iter-key-str
6.20+ :iter-val :iter-val-str
6.21+ :unable-to-open-db :unable-to-put-key-value-to-db :unable-to-get-value-to-db))
6.22+
6.23+(defmacro with-open-db ((db-var db-path &optional opt) &body body)
6.24+ `(let ((,db-var (open-db ,db-path ,opt)))
6.25+ (unwind-protect (progn ,@body)
6.26+ (rocksdb-close ,db-var))))
6.27+
6.28+(defmacro with-iter ((iter-var db &optional opt) &body body)
6.29+ `(let ((,iter-var (create-iter ,db ,opt)))
6.30+ (unwind-protect (progn ,@body)
6.31+ (rocksdb-iter-destroy ,iter-var))))
6.32+
6.33+
6.34+;;; Conditions
6.35+(define-condition unable-to-open-db (error)
6.36+ ((db-path :initarg :db-path
6.37+ :reader db-path)
6.38+ (error-message :initarg :error-message
6.39+ :reader error-message)))
6.40+
6.41+(defmethod print-object ((obj unable-to-open-db) stream)
6.42+ (print-unreadable-object (obj stream :type t :identity t)
6.43+ (format stream "error-message=~A" (error-message obj))))
6.44+
6.45+(define-condition unable-to-put-key-value-to-db (error)
6.46+ ((db :initarg :db
6.47+ :reader db)
6.48+ (key :initarg :key
6.49+ :reader key)
6.50+ (val :initarg :val
6.51+ :reader val)
6.52+ (error-message :initarg :error-message
6.53+ :reader error-message)))
6.54+
6.55+(define-condition unable-to-get-value-to-db (error)
6.56+ ((db :initarg :db
6.57+ :reader db)
6.58+ (key :initarg :key
6.59+ :reader key)
6.60+ (error-message :initarg :error-message
6.61+ :reader error-message)))
6.62+
6.63+;;; API
6.64+(defun open-db (db-path &optional opt)
6.65+ (unless opt
6.66+ (setq opt (rocksdb-options-create)))
6.67+ (with-alien ((e rocksdb-errptr nil))
6.68+ (let* ((db-path (if (pathnamep db-path)
6.69+ (namestring db-path)
6.70+ db-path))
6.71+ (db (rocksdb-open opt db-path e)))
6.72+ (if (null-alien e)
6.73+ db
6.74+ (error 'unable-to-open-db
6.75+ :db-path db-path
6.76+ :error-message e)))))
6.77+
6.78+;; (defmacro clone-octets-to-foreign (lisp-array foreign-array)
6.79+;; (let ((i (gensym)))
6.80+;; `(loop for ,i from 0 below (length ,lisp-array)
6.81+;; do (setf (deref ,foreign-array ,i)
6.82+;; (aref ,lisp-array ,i)))))
6.83+
6.84+;; (defmacro clone-octets-from-foreign (foreign-array lisp-array len)
6.85+;; (let ((i (gensym)))
6.86+;; `(loop for ,i from 0 below ,len
6.87+;; do (setf (aref ,lisp-array ,i)
6.88+;; (deref ,foreign-array ,i)))))
6.89+
6.90+;; (defun put-kv (db key val &optional opt)
6.91+;; (unless opt
6.92+;; (setq opt (create-writeoptions)))
6.93+;; (with-alien ((errptr (* t))
6.94+;; (key* unsigned-char (length key))
6.95+;; (val* unsigned-char (length val)))
6.96+;; (clone-octets-to-foreign key key*)
6.97+;; (clone-octets-to-foreign val val*)
6.98+;; (put* db
6.99+;; opt
6.100+;; key*
6.101+;; (length key)
6.102+;; val*
6.103+;; (length val)
6.104+;; errptr)
6.105+;; (let ((err errptr))
6.106+;; (unless (null-alien err)
6.107+;; (error 'unable-to-put-key-value-to-db
6.108+;; :db db
6.109+;; :key key
6.110+;; :val val
6.111+;; :error-message (sap-alien err c-string))))))
6.112+
6.113+;; (defun put-kv-str (db key val &optional opt)
6.114+;; (let ((key-octets (string-to-octets key))
6.115+;; (val-octets (string-to-octets val)))
6.116+;; (put-kv db key-octets val-octets opt)))
6.117+
6.118+;; (defun get-kv (db key &optional opt)
6.119+;; (unless opt
6.120+;; (setq opt (create-readoptions)))
6.121+
6.122+;; (with-alien ((val-len-ptr unsigned-int)
6.123+;; (errptr system-area-pointer)
6.124+;; (key* unsigned-char (length key)))
6.125+;; (clone-octets-to-foreign key key*)
6.126+;; ;; (setf (mem-ref errptr :pointer) (null-pointer))
6.127+;; (let ((val (get* db
6.128+;; opt
6.129+;; key*
6.130+;; (length key)
6.131+;; val-len-ptr
6.132+;; errptr)))
6.133+;; (let ((err errptr))
6.134+;; (unless (null-alien err)
6.135+;; (error 'unable-to-get-value-to-db
6.136+;; :db db
6.137+;; :key key
6.138+;; :error-message (sap-alien err c-string)))
6.139+
6.140+;; (unless (null-alien val)
6.141+;; (let* ((val-len val-len-ptr)
6.142+;; (val* (make-array val-len
6.143+;; :element-type '(unsigned-byte 8))))
6.144+;; (clone-octets-from-foreign val val* val-len)
6.145+;; val*))))))
6.146+
6.147+;; (defun get-kv-str (db key &optional opt)
6.148+;; (let ((key-octets (string-to-octets key)))
6.149+;; (let ((#1=val-octets (get-kv db key-octets opt)))
6.150+;; (when #1#
6.151+;; (octets-to-string #1#)))))
6.152+
6.153+(defun create-iter (db &optional opt)
6.154+ (unless opt
6.155+ (setq opt (rocksdb-readoptions-create)))
6.156+ (rocksdb-create-iterator db opt))
6.157+
6.158+;; (defun iter-key (iter)
6.159+;; (with-alien ((klen-ptr unsigned-int 0))
6.160+;; (let* ((key-ptr (rocksdb-iter-key iter klen-ptr))
6.161+;; (klen klen-ptr)
6.162+;; (key (make-array klen :element-type '(unsigned-byte 8))))
6.163+;; (clone-octets-from-foreign key-ptr key klen)
6.164+;; key)))
6.165+
6.166+;; (defun iter-key-str (iter)
6.167+;; (when-let ((key-octets (iter-key iter)))
6.168+;; (octets-to-string key-octets)))
6.169+
6.170+;; (defun iter-val (iter)
6.171+;; (with-alien ((len-ptr unsigned-int 0))
6.172+;; (let* ((value-ptr (rocksdb-iter-value iter len-ptr))
6.173+;; (vlen len-ptr)
6.174+;; (value* (make-array vlen :element-type '(unsigned-byte 8))))
6.175+;; (clone-octets-from-foreign value-ptr value* vlen)
6.176+;; value*)))
6.177+
6.178+;; (defun iter-val-str (iter)
6.179+;; (let ((#1=val-octets (iter-value iter)))
6.180+;; (when #1#
6.181+;; (octets-to-string #1#))))
7.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2+++ b/lisp/rocksdb/rocksdb.lisp Thu Oct 12 22:36:34 2023 -0400
7.3@@ -0,0 +1,181 @@
7.4+;;; rocksdb.lisp --- low-level bindings to the RocksDB C API
7.5+
7.6+;; for the high-level interface, see rdb.lisp.
7.7+
7.8+;;; Commentary:
7.9+
7.10+;; if ur on archlinux and installed rocksdb via AUR you may receive an error from
7.11+;; jemalloc: cannot allocate memory in static TLS block:
7.12+
7.13+;; https://github.com/veer66/cl-rocksdb/issues/1
7.14+
7.15+;; for best results, you should compile rocksdb from source - use j0ni's snippet as a
7.16+;; starting point.
7.17+
7.18+;; make shared_lib DISABLE_JEMALLOC=1 &&
7.19+;; sudo cp librocksdb.so.* /usr/local/lib/ &&
7.20+;; sudo cp -rf include/* /usr/local/include/
7.21+
7.22+;; https://github.com/facebook/rocksdb/blob/main/Makefile
7.23+
7.24+;; check /usr/local/include/rocksdb/c.h for the C API header, the source is under
7.25+;; db/c.cc
7.26+
7.27+;;; Code:
7.28+(defpackage :rocksdb
7.29+ (:use :cl :sb-alien :macs.alien)
7.30+ (:export
7.31+ :load-rocksdb
7.32+ :rocksdb-open
7.33+ :rocksdb-close
7.34+ :rocksdb-destroy-db
7.35+ :rocksdb-put
7.36+ :rocksdb-get
7.37+ :rocksdb-delete
7.38+ :rocksdb-cancel-all-background-work
7.39+ :rocksdb-errptr
7.40+ ;; LRU CACHE
7.41+ :rocksdb-cache-create-lru
7.42+ ;; BLOCK-BASED OPTIONS
7.43+ :rocksdb-block-based-options-create
7.44+ :rocksdb-block-based-options-destroy
7.45+ :rocksdb-block-based-options-set-block-cache
7.46+ :set-block-based-options-cache-index-and-filter-blocks
7.47+ ;; OPTIONS
7.48+ :rocksdb-options-create
7.49+ :rocksdb-options-destroy
7.50+ :rocksdb-options-increase-parallelism
7.51+ :rocksdb-options-optimize-level-style-compaction
7.52+ :rocksdb-options-set-create-if-missing
7.53+ :rocksdb-options-set-block-based-table-factory
7.54+ :rocksdb-writeoptions-create
7.55+ :rocksdb-writeoptions-destroy
7.56+ :rocksdb-readoptions-create
7.57+ :rocksdb-readoptions-destroy
7.58+ ;; ITERATOR
7.59+ :rocksdb-iter-seek-to-first
7.60+ :rocksdb-iter-next
7.61+ :rocksdb-iter-prev
7.62+ :rocksdb-iter-valid
7.63+ :rocksdb-create-iterator
7.64+ :rocksdb-iter-key
7.65+ :rocksdb-iter-value
7.66+ :rocksdb-iter-destroy))
7.67+
7.68+(in-package :rocksdb)
7.69+
7.70+(defun load-rocksdb ()
7.71+ (unless (member :rocksdb *features*)
7.72+ (sb-alien:load-shared-object "librocksdb.so" :dont-save t)
7.73+ (push :rocksdb *features*)))
7.74+
7.75+(load-rocksdb)
7.76+
7.77+;;; Opaque Types
7.78+(define-alien-type rocksdb (* t))
7.79+(define-alien-type rocksdb-options (* t))
7.80+(define-alien-type rocksdb-readoptions (* t))
7.81+(define-alien-type rocksdb-writeoptions (* t))
7.82+(define-alien-type rocksdb-compactoptions (* t))
7.83+(define-alien-type rocksdb-block-based-table-options (* t))
7.84+(define-alien-type rocksdb-iterator (* t))
7.85+(define-alien-type rocksdb-column-family-handle (* t))
7.86+(define-alien-type rocksdb-sstfilewriter (* t))
7.87+(define-alien-type rocksdb-errptr (* c-string))
7.88+
7.89+;;; LRU
7.90+(define-alien-routine rocksdb-cache-create-lru (* rocksdb) (capacity unsigned-int))
7.91+
7.92+;;; Options
7.93+;;;; block-based
7.94+(define-alien-routine rocksdb-block-based-options-create (* t))
7.95+(define-alien-routine rocksdb-block-based-options-destroy void
7.96+ (options (* t)))
7.97+(define-alien-routine rocksdb-block-based-options-set-block-cache void
7.98+ (options (* t))
7.99+ (block-cache (* t)))
7.100+(define-alien-routine rocksdb-block-based-options-set-cache-index-and-filter-blocks void
7.101+ (options (* t))
7.102+ (val c-string))
7.103+;;;; db
7.104+(define-alien-routine rocksdb-options-create rocksdb-options)
7.105+(define-alien-routine rocksdb-options-destroy void
7.106+ (options rocksdb-options))
7.107+(define-alien-routine rocksdb-options-increase-parallelism void
7.108+ (opt rocksdb-options) (total-threads int))
7.109+(define-alien-routine rocksdb-options-optimize-level-style-compaction void
7.110+ (opt rocksdb-options)
7.111+ (memtable_memory_budget (unsigned 4)))
7.112+(define-alien-routine rocksdb-options-set-create-if-missing void
7.113+ (opt rocksdb-options)
7.114+ (val boolean))
7.115+(define-alien-routine rocksdb-options-set-block-based-table-factory void
7.116+ (opt rocksdb-options)
7.117+ (table-options rocksdb-block-based-table-options))
7.118+;;;; write
7.119+(define-alien-routine rocksdb-writeoptions-create rocksdb-writeoptions)
7.120+(define-alien-routine rocksdb-writeoptions-destroy void
7.121+ (opt rocksdb-writeoptions))
7.122+;;;; read
7.123+(define-alien-routine rocksdb-readoptions-create rocksdb-readoptions)
7.124+(define-alien-routine rocksdb-readoptions-destroy void
7.125+ (opt rocksdb-readoptions))
7.126+
7.127+;;; DB
7.128+(define-alien-routine rocksdb-open rocksdb
7.129+ (opt rocksdb-options)
7.130+ (name c-string)
7.131+ (errptr rocksdb-errptr))
7.132+(define-alien-routine rocksdb-close void
7.133+ (db rocksdb))
7.134+(define-alien-routine rocksdb-cancel-all-background-work void
7.135+ (db rocksdb)
7.136+ (wait boolean))
7.137+
7.138+(define-alien-routine rocksdb-put void
7.139+ (db rocksdb)
7.140+ (options rocksdb-writeoptions)
7.141+ (key c-string)
7.142+ (keylen size-t)
7.143+ (val c-string)
7.144+ (vallen size-t)
7.145+ (errptr rocksdb-errptr))
7.146+
7.147+(define-alien-routine rocksdb-get c-string
7.148+ (db rocksdb)
7.149+ (options rocksdb-readoptions)
7.150+ (key c-string)
7.151+ (keylen size-t)
7.152+ (vallen (* size-t))
7.153+ (errptr rocksdb-errptr))
7.154+
7.155+(define-alien-routine rocksdb-delete void
7.156+ (db rocksdb)
7.157+ (options rocksdb-writeoptions)
7.158+ (key c-string)
7.159+ (keylen size-t)
7.160+ (errptr rocksdb-errptr))
7.161+
7.162+;;; Iterators
7.163+(define-alien-routine rocksdb-create-iterator rocksdb-iterator
7.164+ (db rocksdb)
7.165+ (opt rocksdb-readoptions))
7.166+(define-alien-routine rocksdb-iter-destroy void
7.167+ (iter rocksdb-iterator))
7.168+(define-alien-routine rocksdb-iter-seek-to-first void
7.169+ (iter rocksdb-iterator))
7.170+(define-alien-routine rocksdb-iter-valid boolean
7.171+ (iter rocksdb-iterator))
7.172+(define-alien-routine rocksdb-iter-next void
7.173+ (iter rocksdb-iterator))
7.174+(define-alien-routine rocksdb-iter-prev void
7.175+ (iter rocksdb-iterator))
7.176+(define-alien-routine rocksdb-iter-key (* t)
7.177+ (iter rocksdb-iterator)
7.178+ (klen-ptr (* size-t)))
7.179+(define-alien-routine rocksdb-iter-value (* t)
7.180+ (iter rocksdb-iterator) (vlen-ptr (* size-t)))
7.181+(define-alien-routine rocksdb-destroy-db void
7.182+ (options rocksdb-options)
7.183+ (name c-string)
7.184+ (errptr rocksdb-errptr))
8.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2+++ b/lisp/rocksdb/tests.lisp Thu Oct 12 22:36:34 2023 -0400
8.3@@ -0,0 +1,62 @@
8.4+;;; rocksdb/tests.lisp --- RocksDB tests
8.5+
8.6+;;; Code:
8.7+(defpackage :rocksdb.tests
8.8+ (:use :cl :rt :rocksdb :rdb :sb-alien :alien :sb-ext)
8.9+ (:export :rocksdb-test-dir))
8.10+
8.11+(in-package :rocksdb.tests)
8.12+
8.13+(defun rocksdb-test-dir ()
8.14+ (format nil "/tmp/~A/" (gensym "rocksdb-tests-")))
8.15+
8.16+(defun test-opts ()
8.17+ (let ((opts (rocksdb-options-create)))
8.18+ (rocksdb-options-set-create-if-missing opts t)
8.19+ opts))
8.20+
8.21+(defsuite :rocksdb)
8.22+
8.23+(defsuite :rdb)
8.24+
8.25+(in-suite :rocksdb)
8.26+
8.27+(deftest set-opts ()
8.28+ (let ((opts (rocksdb-options-create))
8.29+ (wopts (rocksdb-writeoptions-create))
8.30+ (ropts (rocksdb-readoptions-create))
8.31+ (bopts (rocksdb-block-based-options-create)))
8.32+ (rocksdb-options-set-create-if-missing opts t)
8.33+ (rocksdb-options-destroy opts)
8.34+ (rocksdb-writeoptions-destroy wopts)
8.35+ (rocksdb-readoptions-destroy ropts)
8.36+ (rocksdb-block-based-options-destroy bopts)))
8.37+
8.38+(deftest db ()
8.39+ (let* ((opts (test-opts))
8.40+ (path (rocksdb-test-dir))
8.41+ (db (rocksdb-open opts path nil)))
8.42+ (let ((k "key")
8.43+ (v "val")
8.44+ (wopts (rocksdb-writeoptions-create))
8.45+ (ropts (rocksdb-readoptions-create)))
8.46+ (with-alien ((key (* char) (make-alien-string k))
8.47+ (val (* char) (make-alien-string v :external-format :ascii :null-terminate t))
8.48+ (errptr rocksdb-errptr nil)
8.49+ (vlen (* size-t) (make-alien size-t 1))
8.50+ (ar (array char)))
8.51+ (rocksdb-put db
8.52+ wopts
8.53+ key
8.54+ (length k)
8.55+ val
8.56+ (length v)
8.57+ errptr)
8.58+ (is (string= v (rocksdb-get db ropts key (length k) vlen errptr)))
8.59+
8.60+ (rocksdb-delete db wopts key (length k) errptr)
8.61+ (rocksdb-writeoptions-destroy wopts)
8.62+ (rocksdb-readoptions-destroy ropts)))
8.63+ (rocksdb-close db)
8.64+ (rocksdb-options-destroy opts)
8.65+ (sb-ext:delete-directory path :recursive t)))
9.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2+++ b/readme.org Thu Oct 12 22:36:34 2023 -0400
9.3@@ -0,0 +1,8 @@
9.4+#+TITLE: comp/core
9.5+* rust
9.6+** btrfs
9.7+** btrfsutil
9.8+* lisp
9.9+** btrfs
9.10+** rocksdb
9.11+
10.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2+++ b/rust/btrfs/Cargo.toml Thu Oct 12 22:36:34 2023 -0400
10.3@@ -0,0 +1,9 @@
10.4+### src/sys/btrfs/Cargo.toml --- libbtrfs Rust bindings
10.5+[package]
10.6+name = "btrfs-sys"
10.7+version = "0.1.0"
10.8+edition = "2021"
10.9+[lib]
10.10+path = "lib.rs"
10.11+[build-dependencies]
10.12+bindgen = "0.66.1"
11.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2+++ b/rust/btrfs/build.rs Thu Oct 12 22:36:34 2023 -0400
11.3@@ -0,0 +1,21 @@
11.4+//! src/sys/btrfs/build.rs --- btrfs bindgen builder
11.5+
11.6+//! Code:
11.7+fn main() {
11.8+ println!("cargo:rustc-link-search=/usr/include");
11.9+ println!("cargo:rerun-if-changed=wrapper.h");
11.10+ let bindings = bindgen::Builder::default()
11.11+ .header("wrapper.h")
11.12+ .generate_comments(true)
11.13+ .prepend_enum_name(false)
11.14+// .use_core()
11.15+ .derive_default(true)
11.16+// .allowlist_type("btrfs.*")
11.17+// .allowlist_var("BTRFS.*")
11.18+ .parse_callbacks(Box::new(bindgen::CargoCallbacks))
11.19+ .generate()
11.20+ .expect("Unable to generate bindings");
11.21+ bindings
11.22+ .write_to_file(format!("{}/{}", std::env::var("OUT_DIR").unwrap(), "bindings.rs"))
11.23+ .expect("Couldn't write bindings!");
11.24+}
12.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2+++ b/rust/btrfs/lib.rs Thu Oct 12 22:36:34 2023 -0400
12.3@@ -0,0 +1,7 @@
12.4+//! src/sys/btrfs/lib.rs --- libbtrfs Rust bindings
12.5+#![allow(non_upper_case_globals)]
12.6+#![allow(non_camel_case_types)]
12.7+#![allow(non_snake_case)]
12.8+// NOTE 2023-08-20: the u128s aren't FFI-safe, but are just UUIDs on C-side so nbd
12.9+#![allow(improper_ctypes)]
12.10+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
13.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2+++ b/rust/btrfs/wrapper.h Thu Oct 12 22:36:34 2023 -0400
13.3@@ -0,0 +1,14 @@
13.4+/// src/sys/btrfs/wrapper.h --- btrfs wrapper
13.5+
13.6+/// Code:
13.7+// #include <btrfs/version.h>
13.8+/* #include <btrfs/kerncompat.h> */
13.9+/* #include <btrfs/list.h> */
13.10+/* #include <btrfs/rbtree_types.h> */
13.11+/* #include <btrfs/rbtree.h> */
13.12+/* #include <btrfs/ioctl.h> */
13.13+#include <btrfs/ctree.h>
13.14+#include <btrfs/send.h>
13.15+#include <btrfs/send-stream.h>
13.16+#include <btrfs/send-utils.h>
13.17+// #include <btrfsutil.h>
14.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2+++ b/rust/btrfsutil/Cargo.toml Thu Oct 12 22:36:34 2023 -0400
14.3@@ -0,0 +1,9 @@
14.4+### src/sys/btrfsutil/Cargo.toml --- libbtrfsutil Rust bindings
14.5+[package]
14.6+name = "btrfsutil-sys"
14.7+version = "0.1.0"
14.8+edition = "2021"
14.9+[lib]
14.10+path = "lib.rs"
14.11+[build-dependencies]
14.12+bindgen = "0.66.1"
15.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2+++ b/rust/btrfsutil/build.rs Thu Oct 12 22:36:34 2023 -0400
15.3@@ -0,0 +1,19 @@
15.4+//! src/sys/btrfsutil/build.rs --- libbtrfsutil bindgen builder
15.5+fn main() {
15.6+ println!("cargo:rustc-link-search=/usr/include");
15.7+ println!("cargo:rustc-link-lib=btrfsutil");
15.8+ println!("cargo:rerun-if-changed=wrapper.h");
15.9+ let bindings = bindgen::Builder::default()
15.10+ .header("wrapper.h")
15.11+ .prepend_enum_name(false)
15.12+ .derive_default(true)
15.13+ .generate_comments(true)
15.14+// .allowlist_type("btrfs.*")
15.15+// .allowlist_var("BTRFS.*")
15.16+ .parse_callbacks(Box::new(bindgen::CargoCallbacks))
15.17+ .generate()
15.18+ .expect("Unable to generate bindings");
15.19+ bindings
15.20+ .write_to_file(format!("{}/{}", std::env::var("OUT_DIR").unwrap(), "bindings.rs"))
15.21+ .expect("Couldn't write bindings!");
15.22+}
16.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2+++ b/rust/btrfsutil/lib.rs Thu Oct 12 22:36:34 2023 -0400
16.3@@ -0,0 +1,8 @@
16.4+//! src/sys/btrfsutil/lib.rs --- btrfsutil Rust bindings
16.5+
16.6+//! Code:
16.7+#![allow(non_upper_case_globals)]
16.8+#![allow(non_camel_case_types)]
16.9+#![allow(non_snake_case)]
16.10+
16.11+include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
17.1--- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2+++ b/rust/btrfsutil/wrapper.h Thu Oct 12 22:36:34 2023 -0400
17.3@@ -0,0 +1,18 @@
17.4+/// src/sys/btrfsutil/wrapper.h --- btrfsutil wrapper
17.5+
17.6+/// Code:
17.7+// #include <btrfs/version.h>
17.8+/* #include <btrfs/kerncompat.h> */
17.9+/* #include <btrfs/list.h> */
17.10+/* #include <btrfs/rbtree_types.h> */
17.11+/* #include <btrfs/rbtree.h> */
17.12+/* #include <btrfs/ioctl.h> */
17.13+// #include <btrfs/ctree.h>
17.14+/* #include <btrfs/send.h> */
17.15+/* #include <btrfs/send-stream.h> */
17.16+/* #include <btrfs/send-utils.h> */
17.17+#include <stdbool.h>
17.18+#include <stddef.h>
17.19+#include <stdint.h>
17.20+#include <sys/time.h>
17.21+#include <btrfsutil.h>