diff options
author | Ben Johnson <benbjohnson@yahoo.com> | 2014-01-30 19:26:10 -0800 |
---|---|---|
committer | Ben Johnson <benbjohnson@yahoo.com> | 2014-01-30 19:26:10 -0800 |
commit | d05191d164dbab56adbb3a17a62f66a62695c6d3 (patch) | |
tree | 3f270655af94ff2dbbce62f6065d4f1c24030c71 /sys.go | |
parent | Merge pull request #2 from benbjohnson/master (diff) | |
parent | Add RWTransaction.write(). (diff) | |
download | dedo-d05191d164dbab56adbb3a17a62f66a62695c6d3.tar.gz dedo-d05191d164dbab56adbb3a17a62f66a62695c6d3.tar.xz |
Merge pull request #3 from benbjohnson/spill
Spill to dirty pages, write to disk
Diffstat (limited to 'sys.go')
-rw-r--r-- | sys.go | 95 |
1 files changed, 95 insertions, 0 deletions
@@ -0,0 +1,95 @@ +package bolt + +import ( + "sort" + "unsafe" +) + +// sys represents a in-memory system page. +type sys struct { + pgid pgid + buckets map[string]*bucket +} + +// size returns the size of the page after serialization. +func (s *sys) size() int { + var size int = pageHeaderSize + for key, _ := range s.buckets { + size += int(unsafe.Sizeof(bucket{})) + len(key) + } + return size +} + +// get retrieves a bucket by name. +func (s *sys) get(key string) *bucket { + return s.buckets[key] +} + +// put sets a new value for a bucket. +func (s *sys) put(key string, b *bucket) { + s.buckets[key] = b +} + +// del deletes a bucket by name. +func (s *sys) del(key string) { + delete(s.buckets, key) +} + +// read initializes the data from an on-disk page. +func (s *sys) read(p *page) { + s.pgid = p.id + s.buckets = make(map[string]*bucket) + + var buckets []*bucket + var keys []string + + // Read buckets. + nodes := (*[maxNodesPerPage]bucket)(unsafe.Pointer(&p.ptr)) + for i := 0; i < int(p.count); i++ { + node := &nodes[i] + buckets = append(buckets, node) + } + + // Read keys. + buf := (*[maxAllocSize]byte)(unsafe.Pointer(&nodes[p.count]))[:] + for i := 0; i < int(p.count); i++ { + size := int(buf[0]) + buf = buf[1:] + keys = append(keys, string(buf[:size])) + buf = buf[size:] + } + + // Associate keys and buckets. + for index, key := range keys { + s.buckets[key] = buckets[index] + } +} + +// write writes the items onto a page. +func (s *sys) write(p *page) { + // Initialize page. + p.flags |= p_sys + p.count = uint16(len(s.buckets)) + + // Sort keys. + var keys []string + for key, _ := range s.buckets { + keys = append(keys, key) + } + sort.StringSlice(keys).Sort() + + // Write each bucket to the page. + buckets := (*[maxNodesPerPage]bucket)(unsafe.Pointer(&p.ptr)) + for index, key := range keys { + buckets[index] = *s.buckets[key] + } + + // Write each key to the page. + buf := (*[maxAllocSize]byte)(unsafe.Pointer(&buckets[p.count]))[:] + for _, key := range keys { + buf[0] = byte(len(key)) + buf = buf[1:] + copy(buf, []byte(key)) + buf = buf[len(key):] + } +} |