// GetApproximateSizes returns the approximate number of bytes of file system // space used by one or more key ranges. // // The keys counted will begin at Range.Start and end on the key before // Range.Limit. func (db *DB) GetApproximateSizes(ranges []Range) []uint64 { starts := make([]*C.char, len(ranges)) limits := make([]*C.char, len(ranges)) startLens := make([]C.size_t, len(ranges)) limitLens := make([]C.size_t, len(ranges)) for i, r := range ranges { starts[i] = C.CString(string(r.Start)) startLens[i] = C.size_t(len(r.Start)) limits[i] = C.CString(string(r.Limit)) limitLens[i] = C.size_t(len(r.Limit)) } sizes := make([]uint64, len(ranges)) numranges := C.int(len(ranges)) startsPtr := &starts[0] limitsPtr := &limits[0] startLensPtr := &startLens[0] limitLensPtr := &limitLens[0] sizesPtr := (*C.uint64_t)(&sizes[0]) C.go_leveldb_approximate_sizes( db.Ldb, numranges, startsPtr, startLensPtr, limitsPtr, limitLensPtr, sizesPtr) for i := range ranges { C.leveldb_free(unsafe.Pointer(starts[i])) C.leveldb_free(unsafe.Pointer(limits[i])) } return sizes }
// DestroyDatabase removes a database entirely, removing everything from the // filesystem. func DestroyDatabase(dbname string, o *Options) error { var errStr *C.char ldbname := C.CString(dbname) defer C.leveldb_free(unsafe.Pointer(ldbname)) C.leveldb_destroy_db(o.Opt, ldbname, &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return DatabaseError(gs) } return nil }
// Open opens a database. // // Creating a new database is done by calling SetCreateIfMissing(true) on the // Options passed to Open. // // It is usually wise to set a Cache object on the Options with SetCache to // keep recently used data from that database in memory. func Open(dbname string, o *Options) (*DB, error) { var errStr *C.char ldbname := C.CString(dbname) defer C.leveldb_free(unsafe.Pointer(ldbname)) leveldb := C.leveldb_open(o.Opt, ldbname, &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return nil, DatabaseError(gs) } return &DB{leveldb}, nil }
// Put writes data associated with a key to the database. // // If a nil []byte is passed in as value, it will be returned by Get // as an zero-length slice. The WriteOptions passed in can be reused // by multiple calls to this and if the WriteOptions is left unchanged. // // The key and value byte slices may be reused safely. Put takes a copy of // them before returning. func (db *DB) Put(wo *WriteOptions, key, value []byte) error { var errStr *C.char // leveldb_put, _get, and _delete call memcpy() (by way of Memtable::Add) // when called, so we do not need to worry about these []byte being // reclaimed by GC. var k, v *C.char if len(key) != 0 { k = (*C.char)(unsafe.Pointer(&key[0])) } if len(value) != 0 { v = (*C.char)(unsafe.Pointer(&value[0])) } lenk := len(key) lenv := len(value) C.leveldb_put( db.Ldb, wo.Opt, k, C.size_t(lenk), v, C.size_t(lenv), &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return DatabaseError(gs) } return nil }
func saveError(errStr *C.char) error { if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return fmt.Errorf(gs) } return nil }
func (db *LevelDB) Delete(key string) (err error) { opt := C.leveldb_writeoptions_create() // write option defer C.leveldb_free(unsafe.Pointer(opt)) k := C.CString(key) // copy defer C.leveldb_free(unsafe.Pointer(k)) var cerr *C.char C.leveldb_delete(db.CLevelDB, opt, k, C.size_t(len(key)), &cerr) if cerr != nil { defer C.leveldb_free(unsafe.Pointer(cerr)) return errors.New(C.GoString(cerr)) } return }
// Write atomically writes a WriteBatch to disk. The WriteOptions // passed in can be reused by multiple calls to this and other methods. func (db *DB) Write(wo *WriteOptions, w *WriteBatch) error { var errStr *C.char C.leveldb_write(db.Ldb, wo.Opt, w.wbatch, &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return DatabaseError(gs) } return nil }
// GetError returns an IteratorError from LevelDB if it had one during // iteration. // // This method is safe to call when Valid returns false. func (it *Iterator) GetError() error { var errStr *C.char C.leveldb_iter_get_error(it.Iter, &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return IteratorError(gs) } return nil }
// Open LevelDB with given name func OpenLevelDB(path string) (leveldb *LevelDB, err error) { cpath := C.CString(path) // convert path to c string defer C.leveldb_free(unsafe.Pointer(cpath)) // allocate LevelDB Option struct to open opt := C.leveldb_options_create() defer C.leveldb_free(unsafe.Pointer(opt)) // set open option C.leveldb_options_set_create_if_missing(opt, C.uchar(1)) // open leveldb var cerr *C.char cleveldb := C.leveldb_open(opt, cpath, &cerr) if cerr != nil { defer C.leveldb_free(unsafe.Pointer(cerr)) return nil, errors.New(C.GoString(cerr)) } return &LevelDB{cleveldb, path}, nil }
func (db *DB) open() error { db.initOptions(db.cfg) var errStr *C.char ldbname := C.CString(db.path) defer C.leveldb_free(unsafe.Pointer(ldbname)) db.db = C.leveldb_open(db.opts.Opt, ldbname, &errStr) if errStr != nil { db.db = nil return saveError(errStr) } return nil }
// Get returns the data associated with the key from the database. // // If the key does not exist in the database, a nil []byte is returned. If the // key does exist, but the data is zero-length in the database, a zero-length // []byte will be returned. // // The key byte slice may be reused safely. Get takes a copy of // them before returning. func (db *DB) Get(ro *ReadOptions, key []byte) ([]byte, error) { var errStr *C.char var vallen C.size_t var k *C.char if len(key) != 0 { k = (*C.char)(unsafe.Pointer(&key[0])) } value := C.leveldb_get( db.Ldb, ro.Opt, k, C.size_t(len(key)), &vallen, &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return nil, DatabaseError(gs) } if value == nil { return nil, nil } defer C.leveldb_free(unsafe.Pointer(value)) return C.GoBytes(unsafe.Pointer(value), C.int(vallen)), nil }
func (db *LevelDB) Get(key string) (value string, err error) { opt := C.leveldb_readoptions_create() // write option defer C.leveldb_free(unsafe.Pointer(opt)) k := C.CString(key) // copy defer C.leveldb_free(unsafe.Pointer(k)) var vallen C.size_t var cerr *C.char cvalue := C.leveldb_get(db.CLevelDB, opt, k, C.size_t(len(key)), &vallen, &cerr) if cerr != nil { defer C.leveldb_free(unsafe.Pointer(cerr)) return "", errors.New(C.GoString(cerr)) } if cvalue == nil { return "", nil } defer C.leveldb_free(unsafe.Pointer(cvalue)) return C.GoString(cvalue), nil }
func Get(k *string) (v string, err error) { var v_len C.size_t key := C.CString(*k) defer C.free(unsafe.Pointer(key)) val := C.get(key, C.size_t(len(*k)), &v_len) if val == nil { err = NotExist return } defer C.leveldb_free(unsafe.Pointer(val)) v = C.GoStringN(val, C.int(v_len)) return }
// Delete removes the data associated with the key from the database. // // The key byte slice may be reused safely. Delete takes a copy of // them before returning. The WriteOptions passed in can be reused by // multiple calls to this and if the WriteOptions is left unchanged. func (db *DB) Delete(wo *WriteOptions, key []byte) error { var errStr *C.char var k *C.char if len(key) != 0 { k = (*C.char)(unsafe.Pointer(&key[0])) } C.leveldb_delete( db.Ldb, wo.Opt, k, C.size_t(len(key)), &errStr) if errStr != nil { gs := C.GoString(errStr) C.leveldb_free(unsafe.Pointer(errStr)) return DatabaseError(gs) } return nil }
func (db *DB) Destroy() error { path := db.cfg.Path db.Close() opts := NewOptions() defer opts.Close() var errStr *C.char ldbname := C.CString(path) defer C.leveldb_free(unsafe.Pointer(ldbname)) C.leveldb_destroy_db(opts.Opt, ldbname, &errStr) if errStr != nil { return saveError(errStr) } return nil }
func OpenLeveldb(dir string) (*Leveldb, error) { options := C.leveldb_options_create() C.leveldb_options_set_create_if_missing(options, C.uchar(1)) cache := C.leveldb_cache_create_lru(levelCacheCap) C.leveldb_options_set_cache(options, cache) cDir := C.CString(dir) defer C.free(unsafe.Pointer(cDir)) var err *C.char db := C.leveldb_open(options, cDir, &err) if err != nil { return nil, errors.New(fmt.Sprintf("%s: %s", err, dir)) } C.leveldb_free(unsafe.Pointer(err)) err = nil leveldb := &Leveldb{ cdb: db, read_options: C.leveldb_readoptions_create(), write_options: C.leveldb_writeoptions_create(), cache: cache, } return leveldb, nil }
func Repair(cfg *Config) error { db := new(DB) db.cfg = cfg err := db.open() defer db.Close() //open ok, do not need repair if err == nil { return nil } var errStr *C.char ldbname := C.CString(db.cfg.Path) defer C.leveldb_free(unsafe.Pointer(ldbname)) C.leveldb_repair_db(db.opts.Opt, ldbname, &errStr) if errStr != nil { return saveError(errStr) } return nil }
func (s Store) Repair(path string, cfg *config.Config) error { db := new(DB) db.cfg = &cfg.LevelDB db.path = path err := db.open() defer db.Close() //open ok, do not need repair if err == nil { return nil } var errStr *C.char ldbname := C.CString(path) defer C.leveldb_free(unsafe.Pointer(ldbname)) C.leveldb_repair_db(db.opts.Opt, ldbname, &errStr) if errStr != nil { return saveError(errStr) } return nil }
func (s *CSlice) Free() { C.leveldb_free(s.data) }
// PropertyValue returns the value of a database property. // // Examples of properties include "leveldb.stats", "leveldb.sstables", // and "leveldb.num-files-at-level0". func (db *DB) PropertyValue(propName string) string { cname := C.CString(propName) value := C.GoString(C.leveldb_property_value(db.Ldb, cname)) C.leveldb_free(unsafe.Pointer(cname)) return value }