From 532da174ddcdfcc6bb080f5f633ef84e2cf22c56 Mon Sep 17 00:00:00 2001 From: xushiwei Date: Tue, 9 Jul 2024 15:25:21 +0800 Subject: [PATCH] refactor rust/sled --- _rsdemo/sled/sled.go | 18 --- rust/sled/_demo/sleddemo/sled.go | 21 ++++ rust/sled/sled.go | 203 ++++++++++++++++++++++++------- 3 files changed, 178 insertions(+), 64 deletions(-) delete mode 100644 _rsdemo/sled/sled.go create mode 100644 rust/sled/_demo/sleddemo/sled.go diff --git a/_rsdemo/sled/sled.go b/_rsdemo/sled/sled.go deleted file mode 100644 index 282ead09..00000000 --- a/_rsdemo/sled/sled.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import ( - "github.com/goplus/llgo/c" - "github.com/goplus/llgo/rust/sled" -) - -func main() { - var valueLen c.Ulong - conf := sled.CreateConfig() - path := c.Str("./db") - copyPath := c.Strdup(path) - pathConfig := conf.SetPath(copyPath) - db := pathConfig.OpenDb() - db.Set(c.Str("key"), 3, c.Str("value"), 5) - value := db.Get(c.Str("key"), 3, &valueLen) - c.Printf(c.Str("value: %s\n"), value) -} diff --git a/rust/sled/_demo/sleddemo/sled.go b/rust/sled/_demo/sleddemo/sled.go new file mode 100644 index 00000000..d9768641 --- /dev/null +++ b/rust/sled/_demo/sleddemo/sled.go @@ -0,0 +1,21 @@ +package main + +import ( + "fmt" + + "github.com/goplus/llgo/c" + "github.com/goplus/llgo/rust/sled" +) + +func main() { + conf := sled.NewConfig().SetPath(c.Str("./db")) + defer conf.Free() + + db := sled.Open(conf) + db.SetString("key", "value") + + val := db.GetString("key") + defer val.Free() + + fmt.Println("value:", val) +} diff --git a/rust/sled/sled.go b/rust/sled/sled.go index e68b25ac..9e2837c6 100644 --- a/rust/sled/sled.go +++ b/rust/sled/sled.go @@ -1,70 +1,181 @@ package sled -import "github.com/goplus/llgo/c" +import ( + "unsafe" + _ "unsafe" + + "github.com/goplus/llgo/c" +) // Write the .pc file for the dylib generated by the Rust library and copy it to pkg-config for proper location. const ( LLGoPackage = "link: $(pkg-config --libs sled); -lsled" ) +// ----------------------------------------------------------------------------- + +// Free a buffer originally allocated by sled database. +// +//go:linkname FreeBuf C.sled_free_buf +func FreeBuf(buf *byte, sz uintptr) + +// Value represents a value returns by sled database. +type Value string + +func (v Value) Free() { + FreeBuf(unsafe.StringData(string(v)), uintptr(len(v))) +} + +// ----------------------------------------------------------------------------- + type Config struct { Unused [8]byte } +// Create a new configuration. +// +//go:linkname NewConfig C.sled_create_config +func NewConfig() *Config + +// Free a configuration. +// +// llgo:link (*Config).Free C.sled_free_config +func (conf *Config) Free() {} + +// Set the configured file path. +// The caller is responsible for freeing the path string after calling +// this (it is copied in this function). +// +// llgo:link (*Config).SetPath C.sled_config_set_path +func (conf *Config) SetPath(path *c.Char) *Config { return nil } + +// Set the configured cache capacity in bytes. +// +// llgo:link (*Config).SetCacheCapacity C.sled_config_set_cache_capacity +func (conf *Config) SetCacheCapacity(capacity uintptr) *Config { return nil } + +// Set the configured IO buffer flush interval in milliseconds. +// +// llgo:link (*Config).SetFlushEveryMs C.sled_config_flush_every_ms +func (conf *Config) SetFlushEveryMs(flushEveryMs c.Int) *Config { return nil } + +// Configure the use of the zstd compression library. +// +// llgo:link (*Config).UseCompression C.sled_config_use_compression +func (conf *Config) UseCompression(useCompression byte) *Config { return nil } + +// ----------------------------------------------------------------------------- + +// DB represents a sled database. +// Its implementation is based on lock-free log-structured tree. type DB struct { Unused [8]byte } -// Create a new configuration -// llgo:link CreateConfig C.sled_create_config -func CreateConfig() *Config { return nil } +// Open a sled database. +// +//go:linkname Open C.sled_open_db +func Open(conf *Config) *DB -// Free a configuration -// llgo:link (*Config).FreeConfig C.sled_free_config -func (conf *Config) FreeConfig() {} - -// Set the configured file path -// llgo:link (*Config).SetPath C.sled_config_set_path -func (conf *Config) SetPath(path *c.Char) *Config { return nil } - -// Set the configured cache capacity in bytes -// llgo:link (*Config).SetCacheCapacity C.sled_config_set_cache_capacity -func (conf *Config) SetCacheCapacity(capacity c.Ulong) *Config { return nil } - -// Configure the use of the zstd compression library -// llgo:link (*Config).UseCompression C.sled_config_use_compression -func (conf *Config) UseCompression(use_compression c.Char) *Config { return nil } - -// Set the configured IO buffer flush interval in milliseconds -// llgo:link (*Config).SetFlushEveryMs C.sled_config_flush_every_ms -func (conf *Config) SetFlushEveryMs(flush_every c.Int) *Config { return nil } - -// Open a sled lock-free log-structured tree -// llgo:link (*Config).OpenDb C.sled_open_db -func (conf *Config) OpenDb() *DB { return nil } - -// Close a sled lock-free log-structured tree +// Close a sled database. +// // llgo:link (*DB).Close C.sled_close func (db *DB) Close() {} -// Free a buffer originally allocated by sled -// llgo:link FreeBuf C.sled_free_buf -func FreeBuf(buf *c.Char, sz c.Ulong) {} - // Set a key to a value +// // llgo:link (*DB).Set C.sled_set -func (db *DB) Set(key *c.Char, keylen c.Ulong, val *c.Char, vallen c.Ulong) {} +func (db *DB) Set(key *byte, keyLen uintptr, val *byte, valLen uintptr) {} -// Get the value of a key -// llgo:link (*DB).Get C.sled_get -func (db *DB) Get(key *c.Char, keylen c.Ulong, vallen *c.Ulong) *c.Char { return nil } - -// Delete the value of a key -// llgo:link (*DB).Del C.sled_del -func (db *DB) Del(key *c.Char, keylen c.Ulong) {} - -// Compare and swap -// llgo:link (*DB).CompareAndSwap C.sled_compare_and_swap -func (db *DB) CompareAndSwap(key *c.Char, keylen c.Ulong, old_val *c.Char, old_vallen c.Ulong, new_val *c.Char, new_vallen c.Ulong, actual_val **c.Char, actual_vallen *c.Ulong) c.Char { - return 0 +// SetBytes sets a key to a value +func (db *DB) SetBytes(key, val []byte) { + db.Set(unsafe.SliceData(key), uintptr(len(key)), unsafe.SliceData(val), uintptr(len(val))) } + +// SetString sets a key to a value +func (db *DB) SetString(key, val string) { + db.Set(unsafe.StringData(key), uintptr(len(key)), unsafe.StringData(val), uintptr(len(val))) +} + +// Get gets the value of a key. +// +// llgo:link (*DB).Get C.sled_get +func (db *DB) Get(key *byte, keyLen uintptr, valLen *uintptr) *byte { return nil } + +// GetBytes gets the value of a key. +func (db *DB) GetBytes(key []byte) Value { + var valLen uintptr + val := db.Get(unsafe.SliceData(key), uintptr(len(key)), &valLen) + return Value(unsafe.String(val, valLen)) +} + +// GetString gets the value of a key. +func (db *DB) GetString(key string) Value { + var valLen uintptr + val := db.Get(unsafe.StringData(key), uintptr(len(key)), &valLen) + return Value(unsafe.String(val, valLen)) +} + +// Delete deletes the value of a key. +// +// llgo:link (*DB).Del C.sled_del +func (db *DB) Del(key *byte, keyLen uintptr) {} + +// DelBytes deletes the value of a key. +func (db *DB) DelBytes(key []byte) { + db.Del(unsafe.SliceData(key), uintptr(len(key))) +} + +// DelString deletes the value of a key. +func (db *DB) DelString(key string) { + db.Del(unsafe.StringData(key), uintptr(len(key))) +} + +// CAS compares and swaps the value of a key. +// +// llgo:link (*DB).CAS C.sled_compare_and_swap +func (db *DB) CAS( + key *byte, keyLen uintptr, oldVal *byte, oldValLen uintptr, + newVal *byte, newValLen uintptr, actualVal **byte, actualValLen *uintptr) bool { + return false +} + +// CASBytes compares and swaps the value of a key. +func (db *DB) CASBytes(key, oldVal, newVal []byte, actual *Value) bool { + var pactualVal **byte + var actualVal *byte + var actualValLen uintptr + if actual != nil { + pactualVal = &actualVal + } + ret := db.CAS( + unsafe.SliceData(key), uintptr(len(key)), + unsafe.SliceData(oldVal), uintptr(len(oldVal)), + unsafe.SliceData(newVal), uintptr(len(newVal)), + pactualVal, &actualValLen) + if actual != nil { + *actual = Value(unsafe.String(actualVal, actualValLen)) + } + return ret +} + +// CASString compares and swaps the value of a key. +func (db *DB) CASString(key, oldVal, newVal string, actual *Value) bool { + var pactualVal **byte + var actualVal *byte + var actualValLen uintptr + if actual != nil { + pactualVal = &actualVal + } + ret := db.CAS( + unsafe.StringData(key), uintptr(len(key)), + unsafe.StringData(oldVal), uintptr(len(oldVal)), + unsafe.StringData(newVal), uintptr(len(newVal)), + pactualVal, &actualValLen) + if actual != nil { + *actual = Value(unsafe.String(actualVal, actualValLen)) + } + return ret +} + +// -----------------------------------------------------------------------------