aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dedo.go172
1 files changed, 83 insertions, 89 deletions
diff --git a/src/dedo.go b/src/dedo.go
index 416d575..a7bc629 100644
--- a/src/dedo.go
+++ b/src/dedo.go
@@ -1729,16 +1729,15 @@ func (db *DB) String() string {
}
func newDB(path string, file *os.File) *DB {
- db := &DB{
+ return &DB{
MaxBatchSize: DefaultMaxBatchSize,
MaxBatchDelay: DefaultMaxBatchDelay,
AllocSize: DefaultAllocSize,
opened: true,
path: path,
file: file,
- ops: dbops{file.WriteAt},
+ ops: dbops{writeAt: file.WriteAt},
}
- return db
}
func openFile(path string) (*os.File, error) {
@@ -1760,9 +1759,82 @@ func openFile(path string) (*os.File, error) {
return os.OpenFile(path, flagsRO, fileMode)
}
+func readPageSize(db *DB) (int, error) {
+ // Read the first meta page to determine the page size.
+ const size4KiB = 0x1000
+ buf := [0x1000]byte{}
+ _, err := db.file.ReadAt(buf[:], 0)
+ if err != nil {
+ return 0, err
+ }
+
+ m := pageInBuffer(db, buf[:], 0).meta()
+ err = m.validate()
+ if err != nil {
+ return 0, err
+ }
+
+ return int(m.pageSize), nil
+}
+
+// init creates a new database file and initializes its meta pages.
+func initDB(db *DB, size int64) error {
+ if size != 0 {
+ pageSize, err := readPageSize(db)
+ if err != nil {
+ return err
+ }
+
+ db.pageSize = pageSize
+ return nil
+ }
+ // Set the page size to the OS page size.
+ db.pageSize = os.Getpagesize()
+
+ // Create two meta pages on a buffer.
+ buf := make([]byte, db.pageSize*4)
+ for i := 0; i < 2; i++ {
+ p := pageInBuffer(db, buf[:], pgid(i))
+ p.id = pgid(i)
+ p.flags = metaPageFlag
+
+ // Initialize the meta page.
+ m := p.meta()
+ m.magic = magic
+ m.version = version
+ m.pageSize = uint32(db.pageSize)
+ m.freelist = 2
+ m.root = bucket{root: 3}
+ m.pgid = 4
+ m.txid = txid(i)
+ m.checksum = m.sum64()
+ }
+
+ // Write an empty freelist at page 3.
+ p := pageInBuffer(db, buf[:], pgid(2))
+ p.id = pgid(2)
+ p.flags = freelistPageFlag
+ p.count = 0
+
+ // Write an empty leaf page at page 4.
+ p = pageInBuffer(db, buf[:], pgid(3))
+ p.id = pgid(3)
+ p.flags = leafPageFlag
+ p.count = 0
+
+ // Write the buffer to our data file.
+ if _, err := db.ops.writeAt(buf, 0); err != nil {
+ return err
+ }
+ if err := fdatasync(db); err != nil {
+ return err
+ }
+
+ return nil
+}
+
// Open creates and opens a database at the given path.
// If the file does not exist then it will be created automatically.
-// Passing in nil options will cause Bolt to open the database with the default options.
func Open(path string) (*DB, error) {
file, err := openFile(path)
if err != nil {
@@ -1776,14 +1848,9 @@ func Open(path string) (*DB, error) {
}
db := newDB(path, file)
- // Lock file so that other processes using Bolt in read-write mode cannot
- // use the database at the same time. This would cause corruption since
- // the two processes would write meta pages and free pages separately.
- // The database file is locked exclusively (only one process can grab the lock)
- // if !options.ReadOnly.
- // The database file is locked using the shared lock (more than one process may
- // hold a lock at the same time) otherwise (options.ReadOnly is set).
- if err := flock(db); err != nil {
+
+ err = flock(db)
+ if err != nil {
_ = db.close()
return nil, err
}
@@ -1801,7 +1868,8 @@ func Open(path string) (*DB, error) {
}
// Memory map the data file.
- if err := db.mmap(0); err != nil {
+ err = db.mmap(0)
+ if err != nil {
_ = db.close()
return nil, err
}
@@ -1913,80 +1981,6 @@ func (db *DB) mmapSize(size int) (int, error) {
return int(sz), nil
}
-func readPageSize(db *DB) (int, error) {
- // Read the first meta page to determine the page size.
- var buf [0x1000]byte
- _, err := db.file.ReadAt(buf[:], 0)
- if err != nil {
- return 0, err
- }
-
- m := db.pageInBuffer(buf[:], 0).meta()
- err = m.validate()
- if err != nil {
- // return 0, err
- return os.Getpagesize(), nil
- }
-
- return int(m.pageSize), nil
-}
-
-// init creates a new database file and initializes its meta pages.
-func initDB(db *DB, size int64) error {
- if size != 0 {
- pageSize, err := readPageSize(db)
- if err != nil {
- return err
- }
-
- db.pageSize = pageSize
- return nil
- }
- // Set the page size to the OS page size.
- db.pageSize = os.Getpagesize()
-
- // Create two meta pages on a buffer.
- buf := make([]byte, db.pageSize*4)
- for i := 0; i < 2; i++ {
- p := db.pageInBuffer(buf[:], pgid(i))
- p.id = pgid(i)
- p.flags = metaPageFlag
-
- // Initialize the meta page.
- m := p.meta()
- m.magic = magic
- m.version = version
- m.pageSize = uint32(db.pageSize)
- m.freelist = 2
- m.root = bucket{root: 3}
- m.pgid = 4
- m.txid = txid(i)
- m.checksum = m.sum64()
- }
-
- // Write an empty freelist at page 3.
- p := db.pageInBuffer(buf[:], pgid(2))
- p.id = pgid(2)
- p.flags = freelistPageFlag
- p.count = 0
-
- // Write an empty leaf page at page 4.
- p = db.pageInBuffer(buf[:], pgid(3))
- p.id = pgid(3)
- p.flags = leafPageFlag
- p.count = 0
-
- // Write the buffer to our data file.
- if _, err := db.ops.writeAt(buf, 0); err != nil {
- return err
- }
- if err := fdatasync(db); err != nil {
- return err
- }
-
- return nil
-}
-
// Close releases all database resources.
// All transactions must be closed before closing the database.
func (db *DB) Close() error {
@@ -2356,7 +2350,7 @@ func (db *DB) page(id pgid) *page {
}
// pageInBuffer retrieves a page reference from a given byte array based on the current page size.
-func (db *DB) pageInBuffer(b []byte, id pgid) *page {
+func pageInBuffer(db *DB, b []byte, id pgid) *page {
return (*page)(unsafe.Pointer(&b[id*pgid(db.pageSize)]))
}
@@ -4003,7 +3997,7 @@ func (tx *Tx) write() error {
func (tx *Tx) writeMeta() error {
// Create a temporary buffer for the meta page.
buf := make([]byte, tx.db.pageSize)
- p := tx.db.pageInBuffer(buf, 0)
+ p := pageInBuffer(tx.db, buf, 0)
tx.meta.write(p)
// Write the meta page to file.