예제 #1
0
파일: god_server.go 프로젝트: rhino1998/god
func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	flag.Parse()
	if *dir == address {
		*dir = fmt.Sprintf("%v_%v", *broadcastIp, *port)
	}
	s := dhash.NewNodeDir(fmt.Sprintf("%v:%v", *listenIp, *port), fmt.Sprintf("%v:%v", *broadcastIp, *port), *dir)
	if *verbose {
		s.AddChangeListener(func(ring *common.Ring) bool {
			fmt.Println(s.Describe())
			return true
		})
		s.AddMigrateListener(func(dhash *dhash.Node, source, destination []byte) bool {
			fmt.Printf("Migrated from %v to %v\n", common.HexEncode(source), common.HexEncode(destination))
			return true
		})
		s.AddSyncListener(func(source, dest common.Remote, pulled, pushed int) bool {
			fmt.Printf("%v pulled %v and pushed %v keys synchronizing with %v\n", source.Addr, pulled, pushed, dest.Addr)
			return true
		})
		s.AddCleanListener(func(source, dest common.Remote, cleaned, pushed int) bool {
			fmt.Printf("%v cleaned %v and pushed %v keys to %v\n", source.Addr, cleaned, pushed, dest.Addr)
			return true
		})
	}
	s.MustStart()
	if *joinIp != "" {
		s.MustJoin(fmt.Sprintf("%v:%v", *joinIp, *joinPort))
	}

	select {}
}
예제 #2
0
파일: node.go 프로젝트: rhino1998/god
// Describe returns a humanly readable string describing the broadcast address, position and ring of this Node.
func (self *Node) Describe() string {
	self.metaLock.RLock()
	buffer := bytes.NewBufferString(fmt.Sprintf("%v@%v\n", common.HexEncode(self.position), self.broadcastAddr))
	self.metaLock.RUnlock()
	fmt.Fprint(buffer, self.ring.Describe())
	return string(buffer.Bytes())
}
예제 #3
0
파일: dhash_test.go 프로젝트: rhino1998/god
func testMigrate(t *testing.T, dhashes []*Node) {
	for _, d := range dhashes {
		d.Clear()
	}
	var item common.Item
	for i := 0; i < 1000; i++ {
		item.Key = []byte(fmt.Sprint(i))
		item.Value = []byte(fmt.Sprint(i))
		item.Timestamp = 1
		dhashes[0].Put(item)
	}
	common.AssertWithin(t, func() (string, bool) {
		sum := 0
		status := new(bytes.Buffer)
		ordered := dhashAry(dhashes)
		sort.Sort(ordered)
		lastOwned := ordered[len(ordered)-1].Owned()
		ok := true
		for _, d := range ordered {
			sum += d.Owned()
			fmt.Fprintf(status, "%v %v %v\n", d.node.GetBroadcastAddr(), common.HexEncode(d.node.GetPosition()), d.Owned())
			if float64(lastOwned)/float64(d.Owned()) > migrateHysteresis {
				ok = false
			}
			if d.Owned() == 0 {
				ok = false
			}
			lastOwned = d.Owned()
		}
		return string(status.Bytes()), ok && sum == 1000
	}, time.Second*100)
}
예제 #4
0
파일: asserts.go 프로젝트: rhino1998/god
func assertDelSuccess(t *testing.T, tree *Tree, k, old string) {
	assertExistance(t, tree, k, old)
	if value, existed := tree.Del([]byte(k)); !existed || string(value) != old {
		t.Errorf("%v should contain %v => %v, got %v, %v", tree.Describe(), common.HexEncode([]byte(k)), old, value, existed)
	}
	assertNonExistance(t, tree, k)
}
예제 #5
0
파일: client.go 프로젝트: rhino1998/god
// DescribeNode will return the description structure of the node at pos.
func (self *Conn) DescribeNode(pos []byte) (result common.DHashDescription, err error) {
	_, match, _ := self.ring.Remotes(pos)
	if match == nil {
		err = fmt.Errorf("No node with position %v found", common.HexEncode(pos))
		return
	}
	err = match.Call("DHash.Describe", 0, &result)
	return
}
예제 #6
0
파일: radix_test.go 프로젝트: rhino1998/god
func TestTreeIndexOf(t *testing.T) {
	tree := NewTree()
	for i := 100; i < 200; i += 2 {
		tree.Put([]byte(fmt.Sprint(i)), []byte(fmt.Sprint(i)), 1)
	}
	for i := 100; i < 200; i++ {
		shouldExist := i%2 == 0
		wantedIndex := (i - 99) / 2
		if ind, e := tree.IndexOf([]byte(fmt.Sprint(i))); ind != wantedIndex || e != shouldExist {
			t.Errorf("%v.IndexOf(%v) => %v, %v should be %v, %v", tree.Describe(), common.HexEncode([]byte(fmt.Sprint(i))), ind, e, wantedIndex, shouldExist)
		}
	}
	if ind, e := tree.IndexOf([]byte("1991")); ind != 50 || e {
		t.Errorf("%v.IndexOf(%v) => %v, %v should be %v, %v", tree.Describe(), "1991", ind, e, 50, false)
	}
	if ind, e := tree.IndexOf([]byte("099")); ind != 0 || e {
		t.Errorf("%v.IndexOf(%v) => %v, %v should be %v, %v", tree.Describe(), "099", ind, e, 0, false)
	}
}
예제 #7
0
파일: node.go 프로젝트: rhino1998/god
func (self *Node) String() string {
	return fmt.Sprintf("<%v@%v>", common.HexEncode(self.GetPosition()), self.GetBroadcastAddr())
}
예제 #8
0
파일: radix_test.go 프로젝트: rhino1998/god
func TestSyncRandomLimits(t *testing.T) {
	tree1 := NewTree()
	n := 10
	var k []byte
	var v []byte
	for i := 0; i < n; i++ {
		k = murmur.HashString(fmt.Sprint(i))
		v = []byte(fmt.Sprint(i))
		tree1.Put(k, v, 1)
	}
	var keys [][]byte
	tree1.Each(func(key []byte, byteValue []byte, timestamp int64) bool {
		keys = append(keys, key)
		return true
	})
	var fromKey []byte
	var toKey []byte
	var tree2 *Tree
	var tree3 *Tree
	var s *Sync
	for fromIndex, _ := range keys {
		for toIndex, _ := range keys {
			if fromIndex != toIndex {
				fromKey = keys[fromIndex]
				toKey = keys[toIndex]
				if bytes.Compare(fromKey, toKey) < 0 {
					tree2 = NewTree()
					tree1.Each(func(key []byte, byteValue []byte, timestamp int64) bool {
						if common.BetweenIE(key, fromKey, toKey) {
							tree2.Put(key, byteValue, 1)
						}
						return true
					})
					tree3 = NewTree()
					s = NewSync(tree1, tree3).From(fromKey).To(toKey)
					s.Run()
					if !tree3.deepEqual(tree2) {
						t.Errorf("when syncing from %v to %v, %v and %v have hashes\n%v\n%v\nand they should be equal!", common.HexEncode(fromKey), common.HexEncode(toKey), tree3.Describe(), tree2.Describe(), tree3.Hash(), tree2.Hash())
					}
				}
			}
		}
	}
}
예제 #9
0
파일: radix_test.go 프로젝트: rhino1998/god
func TestTreeSizeBetween(t *testing.T) {
	tree := NewTree()
	for i := 11; i < 20; i++ {
		tree.Put([]byte(fmt.Sprint(i)), []byte(fmt.Sprint(i)), 1)
	}
	for i := 10; i < 21; i++ {
		for j := i; j < 21; j++ {
			expected := common.Max(0, common.Min(j+1, 20)-common.Max(11, i))
			val := tree.SizeBetween([]byte(fmt.Sprint(i)), []byte(fmt.Sprint(j)), true, true)
			if val != expected {
				t.Errorf("%v.SizeBetween(%v, %v, true, true) should be %v but was %v", tree.Describe(), common.HexEncode([]byte(fmt.Sprint(i))), common.HexEncode([]byte(fmt.Sprint(j))), expected, val)
			}
			expected = common.Max(0, common.Min(j+1, 20)-common.Max(11, i+1))
			val = tree.SizeBetween([]byte(fmt.Sprint(i)), []byte(fmt.Sprint(j)), false, true)
			if val != expected {
				t.Errorf("%v.SizeBetween(%v, %v, false, true) should be %v but was %v", tree.Describe(), common.HexEncode([]byte(fmt.Sprint(i))), common.HexEncode([]byte(fmt.Sprint(j))), expected, val)
			}
			expected = common.Max(0, common.Min(j, 20)-common.Max(11, i))
			val = tree.SizeBetween([]byte(fmt.Sprint(i)), []byte(fmt.Sprint(j)), true, false)
			if val != expected {
				t.Errorf("%v.SizeBetween(%v, %v, true, false) should be %v but was %v", tree.Describe(), common.HexEncode([]byte(fmt.Sprint(i))), common.HexEncode([]byte(fmt.Sprint(j))), expected, val)
			}
			expected = common.Max(0, common.Min(j, 20)-common.Max(11, i+1))
			val = tree.SizeBetween([]byte(fmt.Sprint(i)), []byte(fmt.Sprint(j)), false, false)
			if val != expected {
				t.Errorf("%v.SizeBetween(%v, %v, false, false) should be %v but was %v", tree.Describe(), common.HexEncode([]byte(fmt.Sprint(i))), common.HexEncode([]byte(fmt.Sprint(j))), expected, val)
			}
		}
	}
	for i := 0; i < 10; i++ {
		tree.SubPut([]byte{50}, []byte{byte(i)}, []byte{byte(i)}, 1)
	}
	ary := []byte{50}
	if s := tree.SizeBetween(ary, ary, true, true); s != 10 {
		t.Errorf("wrong size calculated for %v\nbetween %v and %v\nwanted %v but got %v", tree.Describe(), common.HexEncode(ary), common.HexEncode(ary), 10, s)
	}
}