github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/database/leveldb.chai2010/db.go (about) 1 // Copyright 2013 <chaishushan{AT}gmail.com>. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package leveldb 6 7 import ( 8 "runtime" 9 ) 10 11 const ( 12 MajorVersion = 1 13 MinorVersion = 14 14 ) 15 16 // Snapshot provides a consistent view of read operations in a DB. It is set 17 // on to a ReadOptions and passed in. It is only created by DB.NewSnapshot. 18 type Snapshot struct { 19 snap *leveldb_snapshot_t 20 } 21 22 // Range is a key range. 23 type Range struct { 24 Start []byte // Start of the key range, include in the range. 25 Limit []byte // Limit of the key range, not include in the range. 26 } 27 28 // DB is a reusable handle to a LevelDB database on disk, created by Open. 29 // 30 // To avoid memory and file descriptor leaks, call Close when the process no 31 // longer needs the handle. Calls to any DB method made after Close will 32 // panic. 33 // 34 // The DB instance may be shared between goroutines. The usual data race 35 // conditions will occur if the same key is written to from more than one, of 36 // course. 37 type DB struct { 38 *dbHandler 39 } 40 type dbHandler struct { 41 db *leveldb_t 42 defaultOpt *leveldb_options_t 43 defaultReadOpt *leveldb_readoptions_t 44 defaultWriteOpt *leveldb_writeoptions_t 45 optState optStateContainer 46 opt Options 47 } 48 49 // Open opens a database. 50 // 51 // Creating a new database is done by calling SetCreateIfMissing(true) on the 52 // Options passed to Open. 53 // 54 // It is usually wise to set a Cache object on the Options with SetCache to 55 // keep recently used data from that database in memory. 56 func Open(name string, opt *Options) (*DB, error) { 57 var err error 58 59 h := &dbHandler{} 60 if opt != nil { 61 h.opt = *opt 62 } 63 h.defaultOpt = leveldb_options_create_copy(&h.optState, &h.opt) 64 h.defaultReadOpt = leveldb_readoptions_create() 65 h.defaultWriteOpt = leveldb_writeoptions_create() 66 defer func() { 67 if err != nil { 68 leveldb_options_destroy(h.defaultOpt) 69 leveldb_readoptions_destroy(h.defaultReadOpt) 70 leveldb_writeoptions_destroy(h.defaultWriteOpt) 71 } 72 }() 73 74 h.db, err = leveldb_open(name, h.defaultOpt) 75 if err != nil { 76 return nil, err 77 } 78 79 runtime.SetFinalizer(h, (*dbHandler).Close) 80 return &DB{h}, nil 81 } 82 83 // Close closes the database, rendering it unusable for I/O, by deallocating 84 // the underlying handle. 85 // 86 // Any attempts to use the DB after Close is called will panic. 87 func (p *dbHandler) Close() { 88 runtime.SetFinalizer(p, nil) 89 90 leveldb_close(p.db) 91 leveldb_options_destroy(p.defaultOpt) 92 leveldb_readoptions_destroy(p.defaultReadOpt) 93 leveldb_writeoptions_destroy(p.defaultWriteOpt) 94 *p = dbHandler{} 95 } 96 97 // Get returns the data associated with the key from the database. 98 // 99 // If the key does not exist in the database, a nil Value is returned. If the 100 // key does exist, but the data is zero-length in the database, a zero-length 101 // Value will be returned. 102 // 103 // When the process no longer needs the Value, call Value.Release. 104 func (p *dbHandler) Get(key []byte, opt *ReadOptions) (*Value, error) { 105 ro := p.defaultReadOpt 106 if opt != nil { 107 ro = leveldb_readoptions_create_copy(opt) 108 defer leveldb_readoptions_destroy(ro) 109 } 110 d, err := leveldb_get(p.db, key, ro) 111 if err != nil { 112 return nil, err 113 } 114 return newValueHandler(d), nil 115 } 116 117 // Put writes data associated with a key to the database. 118 // 119 // If a nil []byte is passed in as value, it will be returned by Get as an 120 // zero-length slice. 121 // 122 // The key and value byte slices may be reused safely. Put takes a copy of 123 // them before returning. 124 func (p *dbHandler) Put(key, value []byte, opt *WriteOptions) error { 125 wo := p.defaultWriteOpt 126 if opt != nil { 127 wo = leveldb_writeoptions_create_copy(opt) 128 defer leveldb_writeoptions_destroy(wo) 129 } 130 return leveldb_put(p.db, key, value, wo) 131 } 132 133 // Delete removes the data associated with the key from the database. 134 // 135 // The key byte slice may be reused safely. Delete takes a copy of 136 // them before returning. 137 func (p *dbHandler) Delete(key []byte, opt *WriteOptions) error { 138 wo := p.defaultWriteOpt 139 if opt != nil { 140 wo = leveldb_writeoptions_create_copy(opt) 141 defer leveldb_writeoptions_destroy(wo) 142 } 143 return leveldb_delete(p.db, key, wo) 144 } 145 146 // Write atomically writes a WriteBatch to disk. 147 func (p *dbHandler) Write(batch *WriteBatch, opt *WriteOptions) error { 148 wo := p.defaultWriteOpt 149 if opt != nil { 150 wo = leveldb_writeoptions_create_copy(opt) 151 defer leveldb_writeoptions_destroy(wo) 152 } 153 return leveldb_write(p.db, batch.batch, wo) 154 } 155 156 // GetProperty returns the value of a database property. 157 // 158 // Examples of properties include "leveldb.stats", "leveldb.sstables", 159 // and "leveldb.num-files-at-level0". 160 // 161 // 162 // When the process no longer needs the Value, call Value.Release. 163 func (p *dbHandler) GetProperty(property string) *Value { 164 return newValueHandler(leveldb_property_value(p.db, property)) 165 } 166 167 // GetApproximateSizes returns the approximate number of bytes of file system 168 // space used by one or more key ranges. 169 // 170 // The keys counted will begin at Range.Start and end on the key before 171 // Range.Limit. 172 func (p *dbHandler) GetApproximateSizes(keyRanges []Range) []uint64 { 173 rangeStartKey := make([][]byte, len(keyRanges)) 174 rangeLimitKey := make([][]byte, len(keyRanges)) 175 for i := 0; i < len(keyRanges); i++ { 176 rangeStartKey[i] = keyRanges[i].Start 177 rangeLimitKey[i] = keyRanges[i].Limit 178 } 179 return leveldb_approximate_sizes(p.db, rangeStartKey, rangeLimitKey) 180 } 181 182 // CompactRange runs a manual compaction on the Range of keys given. This is 183 // not likely to be needed for typical usage. 184 func (p *dbHandler) CompactRange(begin, end []byte) { 185 leveldb_compact_range(p.db, begin, end) 186 } 187 188 // GetSnapshot creates a new snapshot of the database. 189 // 190 // The snapshot, when used in a ReadOptions, provides a consistent view of 191 // state of the database at the the snapshot was created. 192 // 193 // To prevent memory leaks and resource strain in the database, the snapshot 194 // returned must be released with DB.ReleaseSnapshot method on the DB that 195 // created it. 196 // 197 // See the LevelDB documentation for details. 198 func (p *dbHandler) GetSnapshot() *Snapshot { 199 return &Snapshot{ 200 snap: leveldb_create_snapshot(p.db), 201 } 202 } 203 204 // ReleaseSnapshot removes the snapshot from the database's list of snapshots, 205 // and deallocates it. 206 func (p *dbHandler) ReleaseSnapshot(snap *Snapshot) { 207 leveldb_release_snapshot(p.db, snap.snap) 208 *snap = Snapshot{} 209 } 210 211 // RepairDB attempts to repair a database. 212 // If the database is unrepairable, an error is returned. 213 func RepairDB(name string, opt *Options) error { 214 var opt_ *leveldb_options_t 215 var state optStateContainer 216 if opt != nil { 217 opt_ = leveldb_options_create_copy(&state, opt) 218 defer leveldb_options_destroy(opt_) 219 } 220 return leveldb_repair_db(name, opt_) 221 } 222 223 // DestroyDB removes a database entirely, 224 // removing everything from the filesystem. 225 func DestroyDB(name string, opt *Options) error { 226 var opt_ *leveldb_options_t 227 var state optStateContainer 228 if opt != nil { 229 opt_ = leveldb_options_create_copy(&state, opt) 230 defer leveldb_options_destroy(opt_) 231 } 232 return leveldb_destroy_db(name, opt_) 233 }