Esempio n. 1
0
func itemValLength(coll *gkvlite.Collection, i *gkvlite.Item) int {
	if !strings.HasSuffix(coll.Name(), COLL_SUFFIX_CHANGES) {
		return len(i.Val)
	}
	if i.Val != nil {
		return len(i.Val)
	}
	if i.Transient == unsafe.Pointer(nil) {
		// TODO: The item might have nil Val when gkvlite is
		// traversing with a withValue of false; so we haven't
		// read/unmarshal'ed the Val/Transient yet.  Impact: the byte
		// aggregate math might wrong, and if we try to write with
		// this 0 length, it'll be wrong; but, assuming here that the
		// item.Loc() is non-empty so we'll never try to write this
		// nil Val/Transient.
		// panic(fmt.Sprintf("itemValLength saw nil Transient, i: %#v, coll.name: %v",
		// 	i, coll.Name()))
		return 0
	}
	ti := (interface{})(i.Transient)
	item, ok := ti.(*item)
	if !ok {
		panic(fmt.Sprintf("itemValLength invoked on non-item, i: %#v", i))
	}
	if item == nil {
		panic(fmt.Sprintf("itemValLength invoked on nil item, i: %#v", i))
	}
	return itemHdrLen + len(item.key) + len(item.data)
}
Esempio n. 2
0
func itemValWrite(coll *gkvlite.Collection, i *gkvlite.Item,
	w io.WriterAt, offset int64) error {
	if !strings.HasSuffix(coll.Name(), COLL_SUFFIX_CHANGES) {
		_, err := w.WriteAt(i.Val, offset)
		return err
	}
	if i.Val != nil {
		_, err := w.WriteAt(i.Val, offset)
		return err
	}
	if i.Transient == unsafe.Pointer(nil) {
		panic(fmt.Sprintf("itemValWrite saw nil Transient, i: %#v", i))
	}
	ti := (interface{})(i.Transient)
	item, ok := ti.(*item)
	if !ok {
		panic(fmt.Sprintf("itemValWrite invoked on non-item, i: %#v", i))
	}
	if item == nil {
		panic(fmt.Sprintf("itemValWrite invoked on nil item, i: %#v", i))
	}
	vBytes := item.toValueBytes()
	_, err := w.WriteAt(vBytes, offset)
	return err
}
Esempio n. 3
0
func collRangeCopy(src *gkvlite.Collection, dst *gkvlite.Collection,
	minKey []byte,
	minKeyInclusive []byte,
	maxKeyExclusive []byte) error {
	var errVisit error
	visitor := func(i *gkvlite.Item) bool {
		if len(minKeyInclusive) > 0 &&
			bytes.Compare(i.Key, minKeyInclusive) < 0 {
			return true
		}
		if len(maxKeyExclusive) > 0 &&
			bytes.Compare(i.Key, maxKeyExclusive) >= 0 {
			return true
		}
		errVisit = dst.SetItem(i)
		if errVisit != nil {
			return false
		}
		return true
	}
	if errVisit != nil {
		return errVisit
	}
	return src.VisitItemsAscend(minKey, true, visitor)
}
Esempio n. 4
0
func (bs *BasicStore) withRecordContext(id string, col *gkvlite.Collection, fn func(record []byte) error) error {
	record, err := col.Get([]byte(id))
	if err != nil {
		return &taurus.StoreError{Code: taurus.ErrFailedRead, Err: err}
	}
	return fn(record)
}
Esempio n. 5
0
func testFillColl(x *gkvlite.Collection, arr []string) {
	for i, s := range arr {
		x.SetItem(&gkvlite.Item{
			Key:      []byte(s),
			Val:      []byte(s),
			Priority: int32(i),
		})
	}
}
Esempio n. 6
0
// You can use fmt.Printf() for the printf param.
func dumpColl(printf func(format string, a ...interface{}) (n int, err error),
	c *gkvlite.Collection, prefix string) (int, error) {
	n := 0
	err := c.VisitItemsAscend(nil, true, func(cItem *gkvlite.Item) bool {
		n++
		printf("%v%s %#v\n", prefix, string(cItem.Key), cItem)
		return true
	})
	return n, err
}
Esempio n. 7
0
func colItemExists(key string, col *gkvlite.Collection) bool {
	exists := false
	col.VisitItemsAscend([]byte(""), true, func(i *gkvlite.Item) bool {
		if key == string(i.Key) {
			exists = true
			return false
		}
		return true
	})
	return exists
}
Esempio n. 8
0
func copyColl(srcColl *gkvlite.Collection, dstColl *gkvlite.Collection,
	writeEvery int) (numItems uint64, lastItem *gkvlite.Item, err error) {
	minItem, err := srcColl.MinItem(true)
	if err != nil {
		return 0, nil, err
	}
	if minItem == nil {
		return 0, nil, nil
	}

	var errVisit error = nil
	err = srcColl.VisitItemsAscend(minItem.Key, true, func(i *gkvlite.Item) bool {
		if errVisit = dstColl.SetItem(i); errVisit != nil {
			return false
		}
		numItems++
		lastItem = i
		if writeEvery > 0 && numItems%uint64(writeEvery) == 0 {
			if errVisit = dstColl.Write(); errVisit != nil {
				return false
			}
		}
		return true
	})
	if err != nil {
		return 0, nil, err
	}
	if errVisit != nil {
		return 0, nil, errVisit
	}

	return numItems, lastItem, nil
}
Esempio n. 9
0
func (p *partitionstore) visit(coll *gkvlite.Collection,
	start []byte, withValue bool,
	v func(*gkvlite.Item) bool) (err error) {
	if start == nil {
		i, err := coll.MinItem(false)
		if err != nil {
			return err
		}
		if i == nil {
			return nil
		}
		start = i.Key
	}
	return coll.VisitItemsAscend(start, withValue, v)
}
Esempio n. 10
0
// You can use fmt.Printf() for the printf param.
func dumpCollAsItems(printf func(format string, a ...interface{}) (n int, err error),
	c *gkvlite.Collection, prefix string) (int, error) {
	n := 0
	var vErr error
	err := c.VisitItemsAscend(nil, true, func(cItem *gkvlite.Item) bool {
		i := &item{}
		if vErr = i.fromValueBytes(cItem.Val); vErr != nil {
			return false
		}
		n++
		printf("%v%#v, data: %v\n", prefix, i, string(i.data))
		return true
	})
	if vErr != nil {
		return 0, vErr
	}
	return n, err
}
Esempio n. 11
0
func rangeCopy(srcColl *gkvlite.Collection, dstColl *gkvlite.Collection,
	minKeyInclusive []byte, maxKeyExclusive []byte) (hasItems bool, err error) {
	minItem, err := srcColl.MinItem(false)
	if err != nil {
		return false, err
	}
	// TODO: What if we flush between the keys update and changes
	// update?  That could result in an inconsistent db file?
	// Solution idea #1 is to have load-time fixup, that
	// incorporates changes into the key-index.
	if minItem != nil {
		if err := collRangeCopy(srcColl, dstColl, minItem.Key,
			minKeyInclusive, maxKeyExclusive); err != nil {
			return false, err
		}
		return true, nil
	}
	return false, nil
}
Esempio n. 12
0
func itemValRead(coll *gkvlite.Collection, i *gkvlite.Item,
	r io.ReaderAt, offset int64, valLength uint32) error {
	if i.Val != nil {
		panic(fmt.Sprintf("itemValRead saw non-nil Val, i: %#v", i))
	}
	i.Val = make([]byte, valLength)
	_, err := r.ReadAt(i.Val, offset)
	if err != nil {
		return err
	}
	if !strings.HasSuffix(coll.Name(), COLL_SUFFIX_CHANGES) {
		return nil
	}
	x := &item{}
	if err = x.fromValueBytes(i.Val); err != nil {
		return err
	}
	atomic.StorePointer(&i.Transient, unsafe.Pointer(x))
	return nil
}
Esempio n. 13
0
func testCheckColl(t *testing.T, x *gkvlite.Collection, start string, arr []string, cb func(i *gkvlite.Item)) {
	n := 0
	err := x.VisitItemsAscend([]byte(start), true, func(i *gkvlite.Item) bool {
		if cb != nil {
			cb(i)
		}
		if n >= len(arr) {
			t.Errorf("visited more than expected: %v, saw: %v", len(arr), n+1)
		}
		if string(i.Key) != arr[n] {
			t.Errorf("expected visit item: %v, saw: %v", arr[n], i)
		}
		n++
		return true
	})
	if err != nil {
		t.Errorf("expected no visit error, got: %v", err)
	}
	if n != len(arr) {
		t.Errorf("expected # visit callbacks: %v, saw: %v", len(arr), n)
	}
}