Ejemplo n.º 1
0
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
}
Ejemplo n.º 2
0
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
}
Ejemplo n.º 3
0
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
}
Ejemplo n.º 4
0
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)
		}
	}
}
Ejemplo n.º 5
0
// 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
}
Ejemplo n.º 6
0
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
}