1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
package sophia
import (
"errors"
"fmt"
)
const (
keyCompactionCache = "db.%v.compaction.cache"
keyCompactionNodeSize = "db.%v.compaction.node_size"
keyCompactionPageSize = "db.%v.compaction.page_size"
keyCompactionPageChecksum = "db.%v.compaction.page_checksum"
keyCompactionExpirePeriod = "db.%v.compaction.expire_period"
keyCompactionGCWatermark = "db.%v.compaction.gc_wm"
keyCompactionGCPeriod = "db.%v.compaction.gc_period"
keyMmap = "db.%v.mmap"
keyCompression = "db.%v.compression"
keyDirectIO = "db.%v.direct_io"
keySync = "db.%v.sync"
)
// DatabaseConfig a structure for the description of the database to be created.
type DatabaseConfig struct {
// Name of database.
// It will be used to set and get values specific to this base.
Name string
// Schema of database.
// It is used to describe the keys and values that will be stored in the database.
Schema *Schema
// CacheSize precalculated memory usage (cache size) for expected storage capacity and write rates.
// See more http://sophia.systems/v2.2/admin/memory_requirements.html
CompactionCacheSize int64
// CompactionNodeSize set a node file size in bytes.
// Node file can grow up to two times the size before the old node file is being split.
CompactionNodeSize int64
// CompactionNodeSize set size of a page to use.
CompactionPageSize int64
// CompactionPageChecksum check checksum during compaction.
DisableCompactionPageChecksum bool
// CompactionExpirePeriod set expire check process period in seconds.
CompactionExpirePeriod int64
// CompactionGcWm when this value reaches a compaction, operation is scheduled.
// Garbage collection starts when watermark value reaches a certain percent of duplicates.
CompactionGCWatermark int64
// CompactionGCPeriod run check for a gc every CompactionGCPeriod seconds.
CompactionGCPeriod int64
// DisableMmapMode can be set to disable mmap mode.
// By default Sophia uses pread(2) to read data from disk.
// Using mmap mode, Sophia handles all requests by directly accessing memory-mapped node files memory.
//
// It is a good idea to try this mode, even if your dataset is rather small
// or you need to handle a large ratio of read request with a predictable pattern.
//
// Disadvantage of mmap mode, in comparison to RAM Storage,
// is a possible unpredictable latency behaviour and a OS cache warmup period after recovery.
DisableMmapMode bool
// DirectIO can be set to enable O_DIRECT to see what actual read
// performance might be, if we avoid using file system cache.
//
// When a database size is lower then RAM, it probably sits in file system cache and all operations do very little actual IO.
// In some sense, when a database grows in size load scenario might change from from CPU bound to IO bound.
// It is possible to set DirectIO=true and MmapMode=false to get it.
// DirectIO=true and MmapMode=true will cause panic.
DirectIO bool
// DisableSync can be set to disable sync node file on compaction completion.
DisableSync bool
// Expire can be set to enable or disable key expire.
Expire bool
// Compression specify compression driver. Supported: lz4, zstd, none (default).
Compression CompressionType
// Upsert is a function that will be called on every upsert operation.
// If it was not set during the configuration database, upsert operation will not be available
Upsert UpsertFunc
// UpsertArg an argument which is additionally passed every call
UpsertArg interface{}
}
// Database is used for accessing a database.
// Take it's name from sophia.
// Usually object with same features is called 'table'.
type Database struct {
*dataStore
name string
schema *Schema
fieldsCount int
}
// Document creates a Document for a single or multi-statement transactions
func (db *Database) Document() *Document {
ptr := spDocument(db.ptr)
if ptr == nil {
return nil
}
return newDocument(ptr, db.fieldsCount)
}
// Cursor returns a Cursor for iterating over rows in the database
func (db *Database) Cursor(doc *Document) (*Cursor, error) {
if nil == doc {
return nil, errors.New("failed to create cursor: nil Document")
}
cPtr := spCursor(db.env.ptr)
if nil == cPtr {
return nil, fmt.Errorf("failed to create cursor: err=%v", db.env.Error())
}
return &Cursor{
ptr: cPtr,
doc: doc,
}, nil
}
|