func BenchmarkMutateSerializeWithNestedMaps(b *testing.B) { b.ReportAllocs() for i := 0; i < b.N; i++ { data := map[string]map[string][]byte{ "cf": map[string][]byte{ "a": []byte{10}, "b": []byte{20}, "c": []byte{30, 0}, "d": []byte{40, 0, 0, 0}, "e": []byte{50, 0, 0, 0, 0, 0, 0, 0}, "f": []byte{60}, "g": []byte{70}, "h": []byte{80, 0}, "i": []byte{90, 0, 0, 0}, "j": []byte{100, 0, 0, 0, 0, 0, 0, 0}, "k": []byte{0, 0, 220, 66}, "l": []byte{0, 0, 0, 0, 0, 0, 94, 64}, "m": []byte{0, 0, 2, 67, 0, 0, 0, 0}, "n": []byte{0, 0, 0, 0, 0, 128, 97, 64, 0, 0, 0, 0, 0, 0, 0, 0}, "o": []byte{150}, "p": []byte{4, 8, 15, 26, 23, 42}, "q": []byte{1, 1, 3, 5, 8, 13, 21, 34, 55}, "r": []byte("This is a test string."), }, } mutate, err := hrpc.NewPutStr(context.Background(), "", "", data) if err != nil { b.Errorf("Error creating mutate: %v", err) } mutate.SetRegion(region.NewInfo(nil, nil, nil, nil)) mutate.Serialize() } }
func BenchmarkMutateSerializeWithReflection(b *testing.B) { b.ReportAllocs() type teststr struct { AnInt int `hbase:"cf:a"` AnInt8 int8 `hbase:"cf:b"` AnInt16 int16 `hbase:"cf:c"` AnInt32 int32 `hbase:"cf:d"` AnInt64 int64 `hbase:"cf:e"` AnUInt uint `hbase:"cf:f"` AnUInt8 uint8 `hbase:"cf:g"` AnUInt16 uint16 `hbase:"cf:h"` AnUInt32 uint32 `hbase:"cf:i"` AnUInt64 uint64 `hbase:"cf:j"` AFloat32 float32 `hbase:"cf:k"` AFloat64 float64 `hbase:"cf:l"` AComplex64 complex64 `hbase:"cf:m"` AComplex128 complex128 `hbase:"cf:n"` APointer *int `hbase:"cf:o"` AnArray [6]uint8 `hbase:"cf:p"` ASlice []uint8 `hbase:"cf:q"` AString string `hbase:"cf:r"` } number := 150 for i := 0; i < b.N; i++ { str := teststr{ AnInt: 10, AnInt8: 20, AnInt16: 30, AnInt32: 40, AnInt64: 50, AnUInt: 60, AnUInt8: 70, AnUInt16: 80, AnUInt32: 90, AnUInt64: 100, AFloat32: 110, AFloat64: 120, AComplex64: 130, AComplex128: 140, APointer: &number, AnArray: [6]uint8{4, 8, 15, 26, 23, 42}, ASlice: []uint8{1, 1, 3, 5, 8, 13, 21, 34, 55}, AString: "This is a test string.", } mutate, err := hrpc.NewPutStrRef(context.Background(), "", "", str) if err != nil { b.Errorf("Error creating mutate: %v", err) } mutate.SetRegion(region.NewInfo(nil, nil, nil, nil)) mutate.Serialize() } }
func newClient(zkquorum string, options ...Option) *client { log.WithFields(log.Fields{ "Host": zkquorum, }).Debug("Creating new client.") c := &client{ clientType: standardClient, regions: keyRegionCache{regions: b.TreeNew(region.CompareGeneric)}, clients: clientRegionCache{ regions: make(map[hrpc.RegionClient][]hrpc.RegionInfo), }, zkquorum: zkquorum, rpcQueueSize: 100, flushInterval: 20 * time.Millisecond, metaRegionInfo: region.NewInfo( []byte("hbase:meta"), []byte("hbase:meta,,1"), nil, nil), adminRegionInfo: region.NewInfo( nil, nil, nil, nil), zkClient: zk.NewClient(zkquorum), } for _, option := range options { option(c) } if c.master == (zk.ResourceName)("") { c.master = zk.ResourceName("/hbase/master") } if c.meta == (zk.ResourceName)("") { c.meta = zk.ResourceName("/hbase/meta-region-server") } return c }
func TestRegionDiscovery(t *testing.T) { client := newClient("~invalid.quorum~") // We shouldn't connect to ZK. reg := client.getRegionFromCache([]byte("test"), []byte("theKey")) if reg != nil { t.Errorf("Found region %#v even though the cache was empty?!", reg) } // Inject a "test" table with a single region that covers the entire key // space (both the start and stop keys are empty). family := []byte("info") metaRow := &pb.GetResponse{ Result: &pb.Result{Cell: []*pb.Cell{ &pb.Cell{ Row: []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), Family: family, Qualifier: []byte("regioninfo"), Value: []byte("PBUF\b\xc4\xcd\xe9\x99\xe0)\x12\x0f\n\adefault\x12\x04test" + "\x1a\x00\"\x00(\x000\x008\x00"), }, &pb.Cell{ Row: []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), Family: family, Qualifier: []byte("seqnumDuringOpen"), Value: []byte("\x00\x00\x00\x00\x00\x00\x00\x02"), }, &pb.Cell{ Row: []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), Family: family, Qualifier: []byte("server"), Value: []byte("localhost:50966"), }, &pb.Cell{ Row: []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), Family: family, Qualifier: []byte("serverstartcode"), Value: []byte("\x00\x00\x01N\x02\x92R\xb1"), }, }}} reg, _, _, err := region.ParseRegionInfo(metaRow) if err != nil { t.Fatalf("Failed to discover region: %s", err) } client.regions.put(reg) reg = client.getRegionFromCache([]byte("test"), []byte("theKey")) if reg == nil { t.Fatal("Region not found even though we injected it in the cache.") } expected := region.NewInfo( []byte("test"), []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), nil, nil, ) if !bytes.Equal(reg.Table(), expected.Table()) || !bytes.Equal(reg.Name(), expected.Name()) || !bytes.Equal(reg.StartKey(), expected.StartKey()) || !bytes.Equal(reg.StopKey(), expected.StopKey()) { t.Errorf("Found region %#v \nbut expected %#v", reg, expected) } reg = client.getRegionFromCache([]byte("notfound"), []byte("theKey")) if reg != nil { t.Errorf("Found region %#v even though this table doesn't exist", reg) } }
func TestMetaCache(t *testing.T) { client := newClient("~invalid.quorum~") // We shouldn't connect to ZK. reg := client.getRegionFromCache([]byte("test"), []byte("theKey")) if reg != nil { t.Errorf("Found region %#v even though the cache was empty?!", reg) } // Inject an entry in the cache. This entry covers the entire key range. wholeTable := region.NewInfo( []byte("test"), []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), nil, nil, ) regClient, _ := region.NewClient("", 0, region.RegionClient, 0, 0) client.regions.put(wholeTable) client.clients.put(regClient, wholeTable) reg = client.getRegionFromCache([]byte("test"), []byte("theKey")) if !reflect.DeepEqual(reg, wholeTable) { t.Errorf("Found region %#v but expected %#v", reg, wholeTable) } reg = client.getRegionFromCache([]byte("test"), []byte("")) // edge case. if !reflect.DeepEqual(reg, wholeTable) { t.Errorf("Found region %#v but expected %#v", reg, wholeTable) } // Clear our client. client = newClient("~invalid.quorum~") // Inject 3 entries in the cache. region1 := region.NewInfo( []byte("test"), []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("foo"), ) client.regions.put(region1) client.clients.put(regClient, region1) region2 := region.NewInfo( []byte("test"), []byte("test,foo,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte("foo"), []byte("gohbase"), ) client.regions.put(region2) client.clients.put(regClient, region2) region3 := region.NewInfo( []byte("test"), []byte("test,gohbase,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte("gohbase"), []byte(""), ) client.regions.put(region3) client.clients.put(regClient, region3) testcases := []struct { key string reg hrpc.RegionInfo }{ {key: "theKey", reg: region3}, {key: "", reg: region1}, {key: "bar", reg: region1}, {key: "fon\xFF", reg: region1}, {key: "foo", reg: region2}, {key: "foo\x00", reg: region2}, {key: "gohbase", reg: region3}, } for i, testcase := range testcases { reg = client.getRegionFromCache([]byte("test"), []byte(testcase.key)) if !reflect.DeepEqual(reg, testcase.reg) { t.Errorf("[#%d] Found region %#v but expected %#v", i, reg, testcase.reg) } } // Change the last region (maybe it got split). region3 = region.NewInfo( []byte("test"), []byte("test,gohbase,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), nil, []byte("zab"), ) client.regions.put(region3) client.clients.put(regClient, region3) reg = client.getRegionFromCache([]byte("test"), []byte("theKey")) if !reflect.DeepEqual(reg, region3) { t.Errorf("Found region %#v but expected %#v", reg, region3) } reg = client.getRegionFromCache([]byte("test"), []byte("zoo")) if reg != nil { t.Errorf("Shouldn't have found any region yet found %#v", reg) } }
func TestMetaCacheGetOverlaps(t *testing.T) { region1 := region.NewInfo( []byte("test"), []byte("test,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("foo"), ) regionA := region.NewInfo( []byte("hello"), []byte("hello,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("foo"), ) regionB := region.NewInfo( []byte("hello"), []byte("hello,foo,987654321042.56f833d5569a27c7a43fbf547b4924a4."), []byte("foo"), []byte("fox"), ) regionC := region.NewInfo( []byte("hello"), []byte("hello,fox,987654321042.56f833d5569a27c7a43fbf547b4924a4."), []byte("fox"), []byte("yolo"), ) regionTests := []struct { cachedRegions []hrpc.RegionInfo newRegion hrpc.RegionInfo expected []hrpc.RegionInfo }{ {[]hrpc.RegionInfo{}, region1, []hrpc.RegionInfo{}}, // empty cache {[]hrpc.RegionInfo{region1}, region1, []hrpc.RegionInfo{region1}}, // with itself { // different table []hrpc.RegionInfo{region1}, region.NewInfo( []byte("hello"), []byte("hello,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("fake"), ), []hrpc.RegionInfo{}, }, { // overlaps with both []hrpc.RegionInfo{regionA, regionB}, region.NewInfo( []byte("hello"), []byte("hello,bar,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte("bar"), []byte("fop"), ), []hrpc.RegionInfo{regionA, regionB}, }, { // overlaps with both, key start == old one []hrpc.RegionInfo{regionA, regionB}, region.NewInfo( []byte("hello"), []byte("hello,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("yolo"), ), []hrpc.RegionInfo{regionA, regionB}, }, { // overlaps with second []hrpc.RegionInfo{regionA, regionB}, region.NewInfo( []byte("hello"), []byte("hello,fop,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte("fop"), []byte("yolo"), ), []hrpc.RegionInfo{regionB}, }, { // overlaps with first, new key start == old one []hrpc.RegionInfo{regionA, regionB}, region.NewInfo( []byte("hello"), []byte("hello,,1234567890042.56f833d5569a27c7a43fbf547b4924a4."), []byte(""), []byte("abc"), ), []hrpc.RegionInfo{regionA}, }, { // doesn't overlap, is between existing []hrpc.RegionInfo{regionA, regionC}, regionB, []hrpc.RegionInfo{}, }, } client := newClient("~invalid.quorum~") // fake client for i, tt := range regionTests { client.regions.regions.Clear() // set up initial cache for _, region := range tt.cachedRegions { client.regions.put(region) } expectedNames := make(regionNames, len(tt.expected)) for i, r := range tt.expected { expectedNames[i] = r.Name() } os := client.regions.getOverlaps(tt.newRegion) osNames := make(regionNames, len(os)) for i, o := range os { osNames[i] = o.Name() } sort.Sort(expectedNames) sort.Sort(osNames) if !reflect.DeepEqual(expectedNames, osNames) { t.Errorf("=== TestMetaCacheGetOverlaps #%d: Expected overlaps %q, found %q", i+1, expectedNames, osNames) } } }