func (f *bitFiler) ReadAt(b []byte, off int64) (n int, err error) { avail := f.size - off pgI := off >> bfBits pgO := int(off & bfMask) rem := len(b) if int64(rem) >= avail { rem = int(avail) err = io.EOF } for rem != 0 && avail > 0 { pg := f.m[pgI] if pg == nil { pg = &bitPage{} if f.parent != nil { _, err = f.parent.ReadAt(pg.data[:], off&^bfMask) if err != nil && !fileutil.IsEOF(err) { return } err = nil } f.m[pgI] = pg } nc := copy(b[:mathutil.Min(rem, bfSize)], pg.data[pgO:]) pgI++ pgO = 0 rem -= nc n += nc b = b[nc:] off += int64(nc) } return }
func (t *treeCache) getTree(db *DB, prefix int, name string, canCreate bool, cacheSize int) (r *lldb.BTree, err error) { m := t.get() r, ok := m[name] if ok { return } root, err := db.root() if err != nil { return } val, err := root.get(prefix, name) if err != nil { return } switch x := val.(type) { case nil: if !canCreate { return } var h int64 r, h, err = lldb.CreateBTree(db.alloc, collate) if err != nil { return nil, err } if err = root.set(h, prefix, name); err != nil { return nil, err } case int64: if r, err = lldb.OpenBTree(db.alloc, collate, x); err != nil { return nil, err } default: return nil, &lldb.ErrINVAL{Src: "corrupted root directory value for", Val: fmt.Sprintf("%q, %q", prefix, name)} } if len(m) > cacheSize { i, j, n := 0, cacheSize/2, mathutil.Min(cacheSize/20, 10) loop: for k := range m { if i++; i >= j { delete(m, k) if n == 0 { break loop } n-- } } } m[name] = r return }
func (c *cache) get2(n int) (r *node, isZeroed bool) { s := *c lens := len(s) if lens == 0 { return &node{b: make([]byte, n, mathutil.Min(2*n, maxBuf))}, true } i := sort.Search(lens, func(x int) bool { return len(s[x].b) >= n }) if i == lens { i-- s[i].b, isZeroed = make([]byte, n, mathutil.Min(2*n, maxBuf)), true } r = s[i] r.b = r.b[:n] copy(s[i:], s[i+1:]) s = s[:lens-1] *c = s return }
func BenchmarkRollbackFiler(b *testing.B) { rng := rand.New(rand.NewSource(42)) type t struct { off int64 b []byte } a := []t{} for rem := b.N; rem > 0; { off := rng.Int63() n := mathutil.Min(rng.Intn(1e3)+1, rem) a = append(a, t{off, rndBytes(rng, n)}) rem -= n } var r *RollbackFiler f := NewMemFiler() checkpoint := func(sz int64) (err error) { return f.Truncate(sz) } r, err := NewRollbackFiler(f, checkpoint, f) if err != nil { b.Fatal(err) } if err := r.BeginUpdate(); err != nil { b.Fatal(err) } b.SetBytes(1) b.ResetTimer() for _, v := range a { if _, err := r.WriteAt(v.b, v.off); err != nil { b.Fatal(err) } } }
// ReadAt implements Filer. func (f *MemFiler) ReadAt(b []byte, off int64) (n int, err error) { avail := f.size - off pgI := off >> pgBits pgO := int(off & pgMask) rem := len(b) if int64(rem) >= avail { rem = int(avail) err = io.EOF } for rem != 0 && avail > 0 { pg := f.m[pgI] if pg == nil { pg = &zeroPage } nc := copy(b[:mathutil.Min(rem, pgSize)], pg[pgO:]) pgI++ pgO = 0 rem -= nc n += nc b = b[nc:] } return }
func (f *File) readAt(b []byte, off int64, bits bool) (n int, err error) { var fsize int64 if !bits { fsize, err = f.Size() if err != nil { return } } avail := fsize - off pgI := off >> pgBits pgO := int(off & pgMask) rem := len(b) if !bits && int64(rem) >= avail { rem = int(avail) err = io.EOF } for rem != 0 && (bits || avail > 0) { v, err := (*Array)(f).Get(pgI) if err != nil { return n, err } pg, _ := v.([]byte) if len(pg) == 0 { pg = zeroPage[:] } nc := copy(b[:mathutil.Min(rem, pgSize)], pg[pgO:]) pgI++ pgO = 0 rem -= nc n += nc b = b[nc:] } return }