func SeekAndCopySyncPkg(it *Iterator, p *proto.PkgMultiOp, migration bool, migSlotId uint16) bool { p.PkgFlag &^= 0xFF p.ErrCode = 0 p.Kvs = nil var size = 0 for i := 0; i < 10 && size < 400 && it.Valid(); i++ { var kv proto.KeyValue dbId, slotId, ok := seekAndCopySyncKV(it, &kv) if !ok { return false } if migration && migSlotId != slotId { if migSlotId < slotId { return false } else if migSlotId > slotId { seekToSlot(it, migSlotId, 0, 0) if !it.Valid() { return false } dbId, slotId, ok = seekAndCopySyncKV(it, &kv) if !ok || migSlotId != slotId { return false } } } if len(p.Kvs) == 0 { p.DbId = dbId } else if p.DbId != dbId { return true } p.Kvs = append(p.Kvs, kv) size += 13 + len(kv.RowKey) + len(kv.ColKey) + len(kv.Value) it.Next() } return true }
// MGet, MSet, MDel, MIncr, ZMGet, ZMSet, ZMDel, ZMIncr func (c *Context) goMultiOp(zop bool, args multiArgs, cmd uint8, done chan *Call) (*Call, error) { call := c.cli.newCall(cmd, done) if call.err != nil { return call, call.err } var p proto.PkgMultiOp p.Seq = call.seq p.DbId = c.dbId p.Cmd = call.cmd // ZMGet, ZMSet, ZMDel, ZMIncr if zop { p.PkgFlag |= proto.FlagZop } p.Kvs = make([]proto.KeyValue, args.length()) args.toKV(p.Kvs) var pkgLen = p.Length() if pkgLen > proto.MaxPkgLen { c.cli.errCall(call, ErrInvPkgLen) return call, call.err } call.pkg = make([]byte, pkgLen) _, err := p.Encode(call.pkg) if err != nil { c.cli.errCall(call, err) return call, err } c.cli.sending <- call return call, nil }
func TestTableZScan(t *testing.T) { // MZSET { var in proto.PkgMultiOp in.Cmd = proto.CmdMSet in.DbId = 2 in.Seq = 20 in.PkgFlag |= proto.FlagZop in.Kvs = append(in.Kvs, getTestKV(2, []byte("row2"), []byte("col0"), []byte("v0"), 40, 0)) in.Kvs = append(in.Kvs, getTestKV(2, []byte("row2"), []byte("col1"), []byte("v1"), 30, 0)) in.Kvs = append(in.Kvs, getTestKV(2, []byte("row2"), []byte("col2"), []byte("v2"), 20, 0)) in.Kvs = append(in.Kvs, getTestKV(2, []byte("row2"), []byte("col3"), []byte("v3"), 10, 0)) in.Kvs = append(in.Kvs, getTestKV(2, []byte("row2"), []byte("col4"), []byte("v4"), 0, 0)) myMSet(in, testAuth, getTestWA(), true, t) } // ZSCAN ASC order by SCORE var in proto.PkgScanReq in.Cmd = proto.CmdScan in.DbId = 2 in.Seq = 20 in.Num = 10 in.TableId = 2 in.RowKey = []byte("row2") in.SetScore(-1) in.ColKey = []byte("") in.PkgFlag |= proto.FlagScanAsc in.SetColSpace(proto.ColSpaceScore1) // order by SCORE out := myScan(in, testAuth, t) if len(out.Kvs) != 5 { t.Fatalf("Invalid KV number: %d", len(out.Kvs)) } if out.PkgFlag&proto.FlagScanEnd == 0 { t.Fatalf("Scan should end") } for i := 0; i < len(out.Kvs); i++ { idx := 4 - i if out.Kvs[i].ErrCode != 0 { t.Fatalf("ErrCode is 0") } if out.Kvs[i].TableId != 2 { t.Fatalf("TableId mismatch") } if bytes.Compare(out.Kvs[i].RowKey, []byte("row2")) != 0 { t.Fatalf("RowKey mismatch") } if bytes.Compare(out.Kvs[i].ColKey, []byte(fmt.Sprintf("col%d", idx))) != 0 { t.Fatalf("ColKey mismatch") } if out.Kvs[i].Score != int64(i*10) { t.Fatalf("Score mismatch") } if bytes.Compare(out.Kvs[i].Value, []byte(fmt.Sprintf("v%d", idx))) != 0 { t.Fatalf("Value mismatch") } } // ZSCAN DESC order by SCORE in.PkgFlag &^= 0xFF in.PkgFlag |= proto.FlagScanKeyStart out = myScan(in, testAuth, t) if len(out.Kvs) != 5 { t.Fatalf("Invalid KV number: %d", len(out.Kvs)) } if out.PkgFlag&proto.FlagScanEnd == 0 { t.Fatalf("Scan should end") } for i := 0; i < len(out.Kvs); i++ { idx := 4 - i if out.Kvs[i].ErrCode != 0 { t.Fatalf("ErrCode is 0") } if out.Kvs[i].TableId != 2 { t.Fatalf("TableId mismatch") } if bytes.Compare(out.Kvs[i].RowKey, []byte("row2")) != 0 { t.Fatalf("RowKey mismatch") } if bytes.Compare(out.Kvs[i].ColKey, []byte(fmt.Sprintf("col%d", i))) != 0 { t.Fatalf("ColKey mismatch") } if out.Kvs[i].Score != int64(idx*10) { t.Fatalf("Score mismatch") } if bytes.Compare(out.Kvs[i].Value, []byte(fmt.Sprintf("v%d", i))) != 0 { t.Fatalf("Value mismatch") } } }