Пример #1
0
func TestNewHeader(t *testing.T) {
	h1 := new_header(4, 8, false)
	h2 := new_header(4, 8, true)

	b1 := h1.Bytes()
	b2 := h2.Bytes()

	h1_2, _ := load_header(b1)
	h2_2, _ := load_header(b2)

	if !bs.ByteSlice(h1_2.Bytes()).Eq(b1) {
		t.Fatal("h1 != h1_2")
	}
	if !bs.ByteSlice(h2_2.Bytes()).Eq(b2) {
		t.Fatal("h2 != h2_2")
	}

	o1 := h1_2.flags()
	o2 := h2_2.flags()

	if o1 {
		t.Fatal("h1 flag not set properly")
	}
	if !o2 {
		t.Fatal("h2 flag not set properly")
	}
}
Пример #2
0
func load_ctrlblk(bytes []byte) (cb *ctrlblk, err error) {
	if len(bytes) < CONTROLSIZE {
		return nil, fmt.Errorf("len(bytes) < %d", CONTROLSIZE)
	}
	cb = &ctrlblk{
		end:       int64(bs.ByteSlice(bytes[0:8]).Int64()),
		free_head: int64(bs.ByteSlice(bytes[8:16]).Int64()),
		free_len:  bs.ByteSlice(bytes[16:20]).Int32(),
	}
	return cb, nil
}
Пример #3
0
func init() {
	if urandom, err := os.Open("/dev/urandom"); err != nil {
		return
	} else {
		seed := make([]byte, 8)
		if _, err := urandom.Read(seed); err == nil {
			rand.Seed(int64(bs.ByteSlice(seed).Int64()))
		}
	}
}
Пример #4
0
func TestPutHasGetRemoveLinearHash(t *testing.T) {
	fmt.Println("start test")
	const RECORDS = 300
	g := testfile(t, VPATH)
	defer func() {
		if e := g.Close(); e != nil {
			panic(e)
		}
		if e := g.Remove(); e != nil {
			panic(e)
		}
	}()
	store, err := bucket.NewVarcharStore(g)
	if err != nil {
		panic(err)
	}
	f := testfile(t, PATH)
	defer func() {
		if e := f.Close(); e != nil {
			panic(e)
		}
		if e := f.Remove(); e != nil {
			panic(e)
		}
	}()
	linhash, err := NewLinearHash(f, store)
	if err != nil {
		t.Fatal(err)
	}

	type record struct {
		key   bs.ByteSlice
		value bs.ByteSlice
	}

	keyset := make(map[string]bool)
	var records []*record
	var values2 []bs.ByteSlice
	for i := 0; i < RECORDS; i++ {
		key := randslice(rand.Intn(16) + 1)
		for {
			if _, has := keyset[string(key)]; !has {
				break
			}
			key = randslice(rand.Intn(16) + 1)
		}
		keyset[string(key)] = true
		records = append(records, &record{key, randslice(rand.Intn(150) + 25)})
		values2 = append(values2, randslice(rand.Intn(150)+25))
	}
	fmt.Println("real start test")

	for i, record := range records {
		err := linhash.Put(record.key, record.value)
		if err != nil {
			t.Fatal(err)
		}
		has, err := linhash.Has(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !has {
			hash := hash(record.key)
			bkt_idx := linhash.bucket(hash)
			bkt, _ := linhash.get_bucket(bkt_idx)
			bkt.PrintBucket()
			bkt_idx2 := bkt_idx - (1 << (linhash.ctrl.i - 1))
			if bkt_idx2 < linhash.ctrl.buckets {
				bkt2, _ := linhash.get_bucket(bkt_idx2)
				bkt2.PrintBucket()
			}
			fmt.Println(i, bs.ByteSlice64(hash), record.key, bkt_idx, bkt_idx2, linhash.ctrl.buckets, linhash.ctrl.i)
			t.Fatal("Expected key")
		}
		value, err := linhash.Get(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !value.Eq(record.value) {
			t.Fatal("Error getting record, value was not as expected")
		}
	}

	if linhash.ctrl.records != RECORDS {
		t.Fatalf("Expected record count == %d got %d", RECORDS,
			linhash.ctrl.records)
	}

	rkeys, err := linhash.Keys()
	if err != nil {
		t.Fatal(err)
	}
	rkeyset := make(map[string]bool)
	for _, bkey := range rkeys {
		key := string(bkey)
		if _, has := keyset[key]; !has {
			t.Fatal("got non-existent key", bs.ByteSlice(key))
		}
		rkeyset[key] = true
	}

	for key, _ := range keyset {
		if _, has := rkeyset[key]; !has {
			t.Fatal("missed key", bs.ByteSlice(key))
		}
	}

	for i, record := range records {
		has, err := linhash.Has(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !has {
			hash := hash(record.key)
			bkt_idx := linhash.bucket(hash)
			bkt, _ := linhash.get_bucket(bkt_idx)
			bkt.PrintBucket()
			bkt_idx2 := bkt_idx - (1 << (linhash.ctrl.i - 1))
			if bkt_idx2 < linhash.ctrl.buckets {
				bkt2, _ := linhash.get_bucket(bkt_idx2)
				bkt2.PrintBucket()
			}
			fmt.Println(i, bs.ByteSlice64(hash), record.key, bkt_idx, bkt_idx2, linhash.ctrl.buckets, linhash.ctrl.i)
			t.Fatal("Expected key")
		}
		value, err := linhash.Get(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !value.Eq(record.value) {
			t.Fatal("Error getting record, value was not as expected")
		}
		ran := randslice(rand.Intn(25) + 1)
		if _, has := keyset[string(ran)]; !has {
			value, err := linhash.DefaultGet(ran, bs.ByteSlice64(0))
			if err != nil {
				t.Fatal(err)
			}
			if !value.Eq(bs.ByteSlice64(0)) {
				t.Fatal("Error getting default")
			}
		} else {
			_, err := linhash.DefaultGet(ran, bs.ByteSlice64(0))
			if err != nil {
				t.Fatal(err)
			}
		}
	}

	for i, record := range records {
		has, err := linhash.Has(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !has {
			t.Fatal("Expected key")
		}
		value, err := linhash.Get(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !value.Eq(record.value) {
			t.Fatal("Error getting record, value was not as expected")
		}
		err = linhash.Put(record.key, values2[i])
		if err != nil {
			t.Fatal(err)
		}
		value, err = linhash.Get(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !value.Eq(values2[i]) {
			t.Fatal("Error getting record, value was not as expected")
		}
		if linhash.Length() != RECORDS {
			t.Fatalf("Expected record count == %d got %d", RECORDS,
				linhash.ctrl.records)
		}
	}

	length := linhash.Length()
	for _, record := range records[length/2:] {
		err := linhash.Remove(record.key)
		if err != nil {
			t.Fatal(err)
		}
	}

	for _, record := range records[length/2:] {
		has, err := linhash.Has(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if has {
			t.Fatal("expected key to be gone")
		}
	}

	for i, record := range records[:length/2] {
		has, err := linhash.Has(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !has {
			t.Fatal("Expected key")
		}
		value, err := linhash.Get(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if !value.Eq(values2[i]) {
			t.Fatal("Error getting record, value was not as expected")
		}
	}

	for _, record := range records[:length/2] {
		err := linhash.Remove(record.key)
		if err != nil {
			t.Fatal(err)
		}
	}

	for _, record := range records {
		has, err := linhash.Has(record.key)
		if err != nil {
			t.Fatal(err)
		}
		if has {
			t.Fatal("expected key to be gone")
		}
	}

	if linhash.Length() != 0 {
		t.Fatalf("Expected record count == %d got %d", 0,
			linhash.ctrl.records)
	}
}
Пример #5
0
func TestPutHasGetRemove(t *testing.T) {

	type record struct {
		key   String
		value String
	}

	ranrec := func() *record {
		return &record{
			String(bs.ByteSlice(randstr(20)).String()),
			String(bs.ByteSlice(randstr(20)).String()),
		}
	}

	test := func(table HashTable) {
		records := make([]*record, 400)
		for i := range records {
			r := ranrec()
			records[i] = r
			err := table.Put(r.key, String(""))
			if err != nil {
				t.Error(err)
			}
			err = table.Put(r.key, r.value)
			if err != nil {
				t.Error(err)
			}
			if table.Size() != (i + 1) {
				t.Error("size was wrong", table.Size(), i+1)
			}
		}

		for _, r := range records {
			if has := table.Has(r.key); !has {
				t.Error(table, "Missing key")
			}
			if has := table.Has(randstr(12)); has {
				t.Error("Table has extra key")
			}
			if val, err := table.Get(r.key); err != nil {
				t.Error(err)
			} else if !(val.(String)).Equals(r.value) {
				t.Error("wrong value")
			}
		}

		for i, x := range records {
			if val, err := table.Remove(x.key); err != nil {
				t.Error(err)
			} else if !(val.(String)).Equals(x.value) {
				t.Error("wrong value")
			}
			for _, r := range records[i+1:] {
				if has := table.Has(r.key); !has {
					t.Error("Missing key")
				}
				if has := table.Has(randstr(12)); has {
					t.Error("Table has extra key")
				}
				if val, err := table.Get(r.key); err != nil {
					t.Error(err)
				} else if !(val.(String)).Equals(r.value) {
					t.Error("wrong value")
				}
			}
			if table.Size() != (len(records) - (i + 1)) {
				t.Error("size was wrong", table.Size(), (len(records) - (i + 1)))
			}
		}
	}

	test(NewHashTable(64))
	test(NewLinearHash())
}
Пример #6
0
func TestPutHasGetRemoveBucket(t *testing.T) {

	type record struct {
		key   String
		value String
	}

	records := make([]*record, 400)
	var tree *bst
	var err error
	var val interface{}
	var updated bool

	ranrec := func() *record {
		return &record{randstr(20), randstr(20)}
	}

	for i := range records {
		r := ranrec()
		records[i] = r
		tree, updated = tree.Put(r.key, String(""))
		if updated {
			t.Error("should have not been updated")
		}
		tree, updated = tree.Put(r.key, r.value)
		if !updated {
			t.Error("should have been updated")
		}
		if tree.Size() != (i + 1) {
			t.Error("size was wrong", tree.Size(), i+1)
		}
	}

	for _, r := range records {
		if has := tree.Has(r.key); !has {
			t.Error("Missing key")
		}
		if has := tree.Has(randstr(12)); has {
			t.Error("Table has extra key")
		}
		if val, err := tree.Get(r.key); err != nil {
			t.Error(err, bs.ByteSlice(val.(String)), bs.ByteSlice(r.value))
		} else if !(val.(String)).Equals(r.value) {
			t.Error("wrong value")
		}
	}

	for i, x := range records {
		if tree, val, err = tree.Remove(x.key); err != nil {
			t.Error(err)
		} else if !(val.(String)).Equals(x.value) {
			t.Error("wrong value")
		}
		for _, r := range records[i+1:] {
			if has := tree.Has(r.key); !has {
				t.Error("Missing key")
			}
			if has := tree.Has(randstr(12)); has {
				t.Error("Table has extra key")
			}
			if val, err := tree.Get(r.key); err != nil {
				t.Error(err)
			} else if !(val.(String)).Equals(r.value) {
				t.Error("wrong value")
			}
		}
		if tree.Size() != (len(records) - (i + 1)) {
			t.Error("size was wrong", tree.Size(), (len(records) - (i + 1)))
		}
	}
}
Пример #7
0
func randstr(length int) types.String {
	return types.String(bs.ByteSlice(randslice(length)).String()[2:])
}
Пример #8
0
func (self *VarcharList) Push(key int64, raw_bytes bs.ByteSlice) (err error) {
	// fmt.Println()
	element := new_element(raw_bytes)
	bytes := element.Bytes()
	item_key, hblk, dirty, blocks, err := self.alloc(key, int64(len(bytes)))
	if err != nil {
		return err
	}
	start_offset := int(self.data_offset(item_key))
	end_offset := int(self.data_offset(self._find_end_algo(blocks, item_key, uint32(len(bytes)))))
	// fmt.Println( "VarcharList.Push", key, len(blocks[0].data), start_offset, end_offset, len(bytes))
	if len(blocks) == 1 {
		// fmt.Println("VarcharList.Push", "only one block just copy")
		copy(blocks[0].data[start_offset:end_offset], bytes)
	} else {
		// fmt.Println("VarcharList.Push", "several blocks")
		var strings []string
		start_bytes_offset := len(blocks[0].data) - start_offset
		s := fmt.Sprint("start ", len(blocks), len(bytes), start_offset, start_bytes_offset)
		strings = append(strings, s)
		copy(blocks[0].data[start_offset:], bytes[0:start_bytes_offset])
		offset := start_bytes_offset
		for i, blk := range blocks[1 : len(blocks)-1] {
			s := fmt.Sprint("middle ", i, len(blocks), len(bytes), offset, offset+len(blk.data))
			strings = append(strings, s)
			copy(blk.data, bytes[offset:offset+len(blk.data)])
			offset += len(blk.data)
		}
		if offset > len(bytes) {
			fmt.Println(len(blocks), len(bytes), offset)
			panic(fmt.Errorf("offset out of bounds on bytes"))
		}
		if end_offset > len(blocks[len(blocks)-1].data) {
			for _, s := range strings {
				fmt.Println(s)
			}
			fmt.Println(len(blocks), len(bytes), len(blocks[len(blocks)-1].data), end_offset)
			panic(fmt.Errorf("offset out of bounds on blocks[len(blocks)-1].data")) // this is the trigger!
		}
		copy(blocks[len(blocks)-1].data[:end_offset], bytes[offset:]) // BUG HERE
	}
	hblk.header.list_length += 1
	err = dirty.Write()
	if err != nil {
		return err
	}
	start_blk := blocks[0]
	offset := item_key - start_blk.key
	ramt := start_blk.bytes[offset : offset+4].Int32()
	ramt2 := start_blk.data[self.data_offset(item_key) : self.data_offset(item_key)+4].Int32()
	// fmt.Println("VarcharList.Push", "cal_offset", offset, self.data_offset(item_key), self.data_offset(item_key) + 40)
	if ramt != element.length() || ramt2 != ramt {
		panic(fmt.Errorf("Written amount incorrect! %v != %v, %v \n %v", element.length(), ramt, bs.ByteSlice(element.Bytes()), blocks[0].data))
	}
	return nil
}