예제 #1
0
파일: sync.go 프로젝트: morya/redis-port
func (cmd *cmdSync) PSyncPipeCopy(c net.Conn, br *bufio.Reader, bw *bufio.Writer, offset int64, copyto io.Writer) (int64, error) {
	defer c.Close()
	var nread atomic2.Int64
	go func() {
		defer c.Close()
		for {
			time.Sleep(time.Second * 5)
			if err := sendPSyncAck(bw, offset+nread.Get()); err != nil {
				return
			}
		}
	}()

	var p = make([]byte, 8192)
	for {
		n, err := br.Read(p)
		if err != nil {
			return nread.Get(), nil
		}
		if _, err := copyto.Write(p[:n]); err != nil {
			return nread.Get(), err
		}
		nread.Add(int64(n))
	}
}
예제 #2
0
func (cmd *cmdDump) DumpRDBFile(reader *bufio.Reader, writer *bufio.Writer, nsize int64) {
	var nread atomic2.Int64
	wait := make(chan struct{})
	go func() {
		defer close(wait)
		p := make([]byte, WriterBufferSize)
		for nsize != nread.Get() {
			nstep := int(nsize - nread.Get())
			ncopy := int64(iocopy(reader, writer, p, nstep))
			nread.Add(ncopy)
			flushWriter(writer)
		}
	}()

	for done := false; !done; {
		select {
		case <-wait:
			done = true
		case <-time.After(time.Second):
		}
		n := nread.Get()
		p := 100 * n / nsize
		log.Infof("total = %d - %12d [%3d%%]\n", nsize, n, p)
	}
	log.Info("dump: rdb done")
}
예제 #3
0
func (cmd *cmdDump) DumpCommand(reader *bufio.Reader, writer *bufio.Writer, nsize int64) {
	var nread atomic2.Int64
	go func() {
		p := make([]byte, ReaderBufferSize)
		for {
			ncopy := int64(iocopy(reader, writer, p, len(p)))
			nread.Add(ncopy)
			flushWriter(writer)
		}
	}()

	for {
		time.Sleep(time.Second)
		log.Infof("dump: total = %d\n", nsize+nread.Get())
	}
}
예제 #4
0
func TestEncodeRdb(t *testing.T) {
	objs := make([]struct {
		db       uint32
		expireat uint64
		key      []byte
		obj      interface{}
		typ      string
	}, 128)
	var b bytes.Buffer
	enc := NewEncoder(&b)
	assert.MustNoError(enc.EncodeHeader())
	for i := 0; i < len(objs); i++ {
		db := uint32(i + 32)
		expireat := uint64(i)
		key := []byte(strconv.Itoa(i))
		var obj interface{}
		var typ string
		switch i % 5 {
		case 0:
			s := strconv.Itoa(i)
			obj = s
			typ = "string"
			assert.MustNoError(enc.EncodeObject(db, key, expireat, toString(s)))
		case 1:
			list := []string{}
			for j := 0; j < 32; j++ {
				list = append(list, fmt.Sprintf("l%d_%d", i, rand.Int()))
			}
			obj = list
			typ = "list"
			assert.MustNoError(enc.EncodeObject(db, key, expireat, toList(list...)))
		case 2:
			hash := make(map[string]string)
			for j := 0; j < 32; j++ {
				hash[strconv.Itoa(j)] = fmt.Sprintf("h%d_%d", i, rand.Int())
			}
			obj = hash
			typ = "hash"
			assert.MustNoError(enc.EncodeObject(db, key, expireat, toHash(hash)))
		case 3:
			zset := make(map[string]float64)
			for j := 0; j < 32; j++ {
				zset[strconv.Itoa(j)] = rand.Float64()
			}
			obj = zset
			typ = "zset"
			assert.MustNoError(enc.EncodeObject(db, key, expireat, toZSet(zset)))
		case 4:
			set := []string{}
			for j := 0; j < 32; j++ {
				set = append(set, fmt.Sprintf("s%d_%d", i, rand.Int()))
			}
			obj = set
			typ = "set"
			assert.MustNoError(enc.EncodeObject(db, key, expireat, toSet(set...)))
		}
		objs[i].db = db
		objs[i].expireat = expireat
		objs[i].key = key
		objs[i].obj = obj
		objs[i].typ = typ
	}
	assert.MustNoError(enc.EncodeFooter())
	rdb := b.Bytes()
	var c atomic2.Int64
	l := NewLoader(stats.NewCountReader(bytes.NewReader(rdb), &c))
	assert.MustNoError(l.Header())
	var i int = 0
	for {
		e, err := l.NextBinEntry()
		assert.MustNoError(err)
		if e == nil {
			break
		}
		assert.Must(objs[i].db == e.DB)
		assert.Must(objs[i].expireat == e.ExpireAt)
		assert.Must(bytes.Equal(objs[i].key, e.Key))
		o, err := DecodeDump(e.Value)
		assert.MustNoError(err)
		switch objs[i].typ {
		case "string":
			checkString(t, o, objs[i].obj.(string))
		case "list":
			checkList(t, o, objs[i].obj.([]string))
		case "hash":
			checkHash(t, o, objs[i].obj.(map[string]string))
		case "zset":
			checkZSet(t, o, objs[i].obj.(map[string]float64))
		case "set":
			checkSet(t, o, objs[i].obj.([]string))
		}
		i++
	}
	assert.Must(i == len(objs))
	assert.MustNoError(l.Footer())
	assert.Must(c.Get() == int64(len(rdb)))
}