github.com/turingchain2020/turingchain@v1.1.21/common/db/go_ssdb_util.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package db
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"net"
    11  	"strconv"
    12  	"sync"
    13  	"time"
    14  
    15  	"github.com/turingchain2020/turingchain/types"
    16  )
    17  
    18  //const
    19  const (
    20  	ENDN = '\n'
    21  	ENDR = '\r'
    22  
    23  	OK       = "ok"
    24  	NotFound = "not_found"
    25  
    26  	ReadTimeOut  = 3
    27  	WriteTimeOut = 3
    28  
    29  	ReadBufSize = 8 * 1024
    30  
    31  	IteratorPageSize = 10240
    32  
    33  	PooledSize = 3
    34  )
    35  
    36  //SDBClient ...
    37  type SDBClient struct {
    38  	sock     *net.TCPConn
    39  	timeZero time.Time
    40  	mu       sync.Mutex
    41  }
    42  
    43  //SDBPool SDB池
    44  type SDBPool struct {
    45  	clients []*SDBClient
    46  	round   *RoundInt
    47  }
    48  
    49  //RoundInt ...
    50  type RoundInt struct {
    51  	round int
    52  	index int
    53  }
    54  
    55  func (val *RoundInt) incr() int {
    56  	val.index++
    57  	if val.index < val.round {
    58  		return val.index
    59  	}
    60  	val.index = 0
    61  	return val.index
    62  }
    63  
    64  func (pool *SDBPool) get() *SDBClient {
    65  	return pool.clients[pool.round.incr()]
    66  }
    67  func (pool *SDBPool) close() {
    68  	for _, v := range pool.clients {
    69  		err := v.Close()
    70  		dlog.Error("ssdb close ", "error", err)
    71  	}
    72  }
    73  
    74  //NewSDBPool new
    75  func NewSDBPool(nodes []*SsdbNode) (pool *SDBPool, err error) {
    76  	dbpool := &SDBPool{}
    77  	for i := 0; i < PooledSize; i++ {
    78  		for _, v := range nodes {
    79  			db, err := Connect(v.ip, v.port)
    80  			if err != nil {
    81  				dlog.Error("connect to ssdb error!", "ssdb", v)
    82  				return dbpool, types.ErrDataBaseDamage
    83  			}
    84  			dbpool.clients = append(dbpool.clients, db)
    85  		}
    86  	}
    87  	dbpool.round = &RoundInt{round: PooledSize * len(nodes)}
    88  	return dbpool, nil
    89  }
    90  
    91  //Connect 连接
    92  func Connect(ip string, port int) (*SDBClient, error) {
    93  	addr, err := net.ResolveTCPAddr("tcp", fmt.Sprintf("%s:%d", ip, port))
    94  	if err != nil {
    95  		return nil, err
    96  	}
    97  	sock, err := net.DialTCP("tcp", nil, addr)
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  
   102  	var c SDBClient
   103  	c.sock = sock
   104  	c.timeZero = time.Time{}
   105  
   106  	return &c, nil
   107  }
   108  
   109  //Get 获取指定 key 的值内容
   110  //  key 键值
   111  //  返回 一个 Value,可以方便的向其它类型转换
   112  //  返回 一个可能的错误,操作成功返回 nil
   113  func (c *SDBClient) Get(key string) (*Value, error) {
   114  	resp, err := c.Do("get", key)
   115  	if err != nil {
   116  		return nil, newErrorf(err, "Get %s error", key)
   117  	}
   118  
   119  	if len(resp) == 0 {
   120  		return nil, newError("ssdb response error")
   121  	}
   122  
   123  	if len(resp) == 2 && resp[0] == OK {
   124  		return toValue(resp[1]), nil
   125  	}
   126  
   127  	return nil, makeError(resp, key)
   128  }
   129  
   130  //Set 设置指定 key 的值内容
   131  //  key 键值
   132  //  val 存贮的 value 值,val只支持基本的类型,如果要支持复杂的类型,需要开启连接池的 Encoding 选项
   133  //  ttl 可选,设置的过期时间,单位为秒
   134  //  返回 err,可能的错误,操作成功返回 nil
   135  func (c *SDBClient) Set(key string, val []byte) (err error) {
   136  	var resp []string
   137  	resp, err = c.Do("set", key, val)
   138  	if err != nil {
   139  		return newErrorf(err, "Set %s error", key)
   140  	}
   141  	if len(resp) > 0 && resp[0] == OK {
   142  		return nil
   143  	}
   144  	return makeError(resp, key)
   145  }
   146  
   147  //Del 删除指定 key
   148  //  key 要删除的 key
   149  //  返回 err,执行的错误,操作成功返回 nil
   150  func (c *SDBClient) Del(key string) error {
   151  	resp, err := c.Do("del", key)
   152  	if err != nil {
   153  		return newErrorf(err, "Del %s error", key)
   154  	}
   155  
   156  	//response looks like s: [ok 1]
   157  	if len(resp) > 0 && resp[0] == OK {
   158  		return nil
   159  	}
   160  	return makeError(resp, key)
   161  }
   162  
   163  //MultiSet 批量设置一批 key-value.
   164  //  包含 key-value 的字典
   165  //  返回 err,可能的错误,操作成功返回 nil
   166  func (c *SDBClient) MultiSet(kvs map[string][]byte) (err error) {
   167  
   168  	args := []interface{}{"multi_set"}
   169  
   170  	for k, v := range kvs {
   171  		args = append(args, k)
   172  		args = append(args, v)
   173  	}
   174  	resp, err := c.Do(args...)
   175  
   176  	if err != nil {
   177  		return newErrorf(err, "MultiSet %s error", kvs)
   178  	}
   179  
   180  	if len(resp) > 0 && resp[0] == OK {
   181  		return nil
   182  	}
   183  	return makeError(resp, kvs)
   184  }
   185  
   186  //MultiDel 批量删除一批 key 和其对应的值内容.
   187  //  key,要删除的 key,可以为多个
   188  //  返回 err,可能的错误,操作成功返回 nil
   189  func (c *SDBClient) MultiDel(key ...string) (err error) {
   190  	if len(key) == 0 {
   191  		return nil
   192  	}
   193  	args := []interface{}{"multi_del"}
   194  	for _, v := range key {
   195  		args = append(args, v)
   196  	}
   197  	resp, err := c.Do(args...)
   198  	if err != nil {
   199  		return newErrorf(err, "MultiDel %s error", key)
   200  	}
   201  
   202  	if len(resp) > 0 && resp[0] == OK {
   203  		return nil
   204  	}
   205  	return makeError(resp, key)
   206  }
   207  
   208  //MultiGet 批量删除一批 key 和其对应的值内容.
   209  //  key,要删除的 key,可以为多个
   210  //  返回 err,可能的错误,操作成功返回 nil
   211  func (c *SDBClient) MultiGet(key ...string) (vals []*Value, err error) {
   212  	if len(key) == 0 {
   213  		return nil, nil
   214  	}
   215  	data := []interface{}{"multi_get"}
   216  	for _, k := range key {
   217  		data = append(data, k)
   218  	}
   219  	resp, err := c.Do(data...)
   220  
   221  	if err != nil {
   222  		return nil, newErrorf(err, "MultiGet %s error", key)
   223  	}
   224  
   225  	size := len(resp)
   226  	if size > 0 && resp[0] == OK {
   227  		for i := 1; i < size && i+1 < size; i += 2 {
   228  			vals = append(vals, toValue(resp[i+1]))
   229  		}
   230  		return vals, nil
   231  	}
   232  	return nil, makeError(resp, key)
   233  }
   234  
   235  //Keys 列出处于区间 (key_start, key_end] 的 key 列表.("", ""] 表示整个区间.
   236  //  keyStart int 返回的起始 key(不包含), 空字符串表示 -inf.
   237  //  keyEnd int 返回的结束 key(包含), 空字符串表示 +inf.
   238  //  limit int 最多返回这么多个元素.
   239  //  返回 返回包含 key 的数组.
   240  //  返回 err,可能的错误,操作成功返回 nil
   241  func (c *SDBClient) Keys(keyStart, keyEnd string, limit int64) ([]string, error) {
   242  
   243  	resp, err := c.Do("keys", keyStart, keyEnd, limit)
   244  
   245  	if err != nil {
   246  		return nil, newErrorf(err, "Keys [%s,%s] %d error", keyStart, keyEnd, limit)
   247  	}
   248  	if len(resp) > 0 && resp[0] == OK {
   249  		return resp[1:], nil
   250  	}
   251  	return nil, makeError(resp, keyStart, keyEnd, limit)
   252  }
   253  
   254  //Rkeys 列出处于区间 (key_start, key_end] 的 key 列表.("", ""] 表示整个区间.反向选择
   255  //  keyStart int 返回的起始 key(不包含), 空字符串表示 -inf.
   256  //  keyEnd int 返回的结束 key(包含), 空字符串表示 +inf.
   257  //  limit int 最多返回这么多个元素.
   258  //  返回 返回包含 key 的数组.
   259  //  返回 err,可能的错误,操作成功返回 nil
   260  func (c *SDBClient) Rkeys(keyStart, keyEnd string, limit int64) ([]string, error) {
   261  
   262  	resp, err := c.Do("rkeys", keyStart, keyEnd, limit)
   263  
   264  	if err != nil {
   265  		return nil, newErrorf(err, "Rkeys [%s,%s] %d error", keyStart, keyEnd, limit)
   266  	}
   267  	if len(resp) > 0 && resp[0] == OK {
   268  		return resp[1:], nil
   269  	}
   270  	return nil, makeError(resp, keyStart, keyEnd, limit)
   271  }
   272  
   273  //Do do
   274  func (c *SDBClient) Do(args ...interface{}) ([]string, error) {
   275  	c.mu.Lock()
   276  	defer c.mu.Unlock()
   277  	//dlog.Warn("begin to send", "value", fmt.Sprintf("%v", args))
   278  	err := c.send(args)
   279  	if err != nil {
   280  		//dlog.Error("send error", "value", fmt.Sprintf("%v", err))
   281  		return nil, err
   282  	}
   283  	resp, err := c.recv()
   284  	//dlog.Warn("begin to return", "value", fmt.Sprintf("%v", resp))
   285  	return resp, err
   286  }
   287  
   288  func (c *SDBClient) send(args []interface{}) error {
   289  	var packetBuf bytes.Buffer
   290  	var err error
   291  	for _, arg := range args {
   292  		switch arg := arg.(type) {
   293  		case string:
   294  			if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10)); err != nil {
   295  				return err
   296  			}
   297  			if err = packetBuf.WriteByte(ENDN); err != nil {
   298  				return err
   299  			}
   300  			if _, err = packetBuf.WriteString(arg); err != nil {
   301  				return err
   302  			}
   303  		case []string:
   304  			for _, a := range arg {
   305  				if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(a)), 10)); err != nil {
   306  					return err
   307  				}
   308  				if err = packetBuf.WriteByte(ENDN); err != nil {
   309  					return err
   310  				}
   311  				if _, err = packetBuf.WriteString(a); err != nil {
   312  					return err
   313  				}
   314  				if err = packetBuf.WriteByte(ENDN); err != nil {
   315  					return err
   316  				}
   317  			}
   318  			continue
   319  		case []byte:
   320  			if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(arg)), 10)); err != nil {
   321  				return err
   322  			}
   323  			if err = packetBuf.WriteByte(ENDN); err != nil {
   324  				return err
   325  			}
   326  			if _, err = packetBuf.Write(arg); err != nil {
   327  				return err
   328  			}
   329  		case int64:
   330  			bs := strconv.AppendInt(nil, arg, 10)
   331  			if _, err = packetBuf.Write(strconv.AppendInt(nil, int64(len(bs)), 10)); err != nil {
   332  				return err
   333  			}
   334  			if err = packetBuf.WriteByte(ENDN); err != nil {
   335  				return err
   336  			}
   337  			if _, err = packetBuf.Write(bs); err != nil {
   338  				return err
   339  			}
   340  		case nil:
   341  			if err = packetBuf.WriteByte(0); err != nil {
   342  				return err
   343  			}
   344  			if err = packetBuf.WriteByte(ENDN); err != nil {
   345  				return err
   346  			}
   347  			if _, err = packetBuf.WriteString(""); err != nil {
   348  				return err
   349  			}
   350  		default:
   351  			return fmt.Errorf("bad arguments type")
   352  		}
   353  		if err = packetBuf.WriteByte(ENDN); err != nil {
   354  			return err
   355  		}
   356  	}
   357  	if err = packetBuf.WriteByte(ENDN); err != nil {
   358  		return err
   359  	}
   360  	if err = c.sock.SetWriteDeadline(time.Now().Add(time.Second * WriteTimeOut)); err != nil {
   361  		return err
   362  	}
   363  	for _, err = packetBuf.WriteTo(c.sock); packetBuf.Len() > 0; {
   364  		if err != nil {
   365  			packetBuf.Reset()
   366  			return newErrorf(err, "client socket write error")
   367  		}
   368  	}
   369  	//设置不超时
   370  	if err := c.sock.SetWriteDeadline(c.timeZero); err != nil {
   371  		return err
   372  	}
   373  	packetBuf.Reset()
   374  	return nil
   375  }
   376  func (c *SDBClient) recv() (resp []string, err error) {
   377  	packetBuf := []byte{}
   378  	//设置读取数据超时,
   379  	if err = c.sock.SetReadDeadline(time.Now().Add(time.Second * ReadTimeOut)); err != nil {
   380  		return nil, err
   381  	}
   382  	//数据包分解,发现长度,找到结尾,循环发现,发现空行,结束
   383  	readBuf := make([]byte, ReadBufSize)
   384  	for {
   385  		bufSize, err := c.sock.Read(readBuf)
   386  		if err != nil {
   387  			return nil, newErrorf(err, "client socket read error")
   388  		}
   389  		if bufSize < 1 {
   390  			continue
   391  		}
   392  		packetBuf = append(packetBuf, readBuf[:bufSize]...)
   393  
   394  		for {
   395  			rsp, n := c.parse(packetBuf)
   396  			if n == -1 {
   397  				break
   398  			} else if n == -2 {
   399  				return nil, newErrorf(err, "parse error")
   400  			} else {
   401  				resp = append(resp, rsp)
   402  				packetBuf = packetBuf[n+1:]
   403  			}
   404  		}
   405  	}
   406  }
   407  
   408  func (c *SDBClient) parse(buf []byte) (resp string, size int) {
   409  	n := bytes.IndexByte(buf, ENDN)
   410  	size = -1
   411  	if n != -1 {
   412  		if n == 0 || n == 1 && buf[0] == ENDR { //空行,说明一个数据包结束
   413  			size = -2
   414  			return
   415  		}
   416  		//数据包开始,包长度解析
   417  		blockSize := ToNum(buf[:n])
   418  		bufSize := len(buf)
   419  
   420  		if n+blockSize < bufSize {
   421  			resp = string(buf[n+1 : blockSize+n+1])
   422  			for i := blockSize + n + 1; i < bufSize; i++ {
   423  				if buf[i] == ENDN {
   424  					size = i
   425  					return
   426  				}
   427  			}
   428  		}
   429  	}
   430  	return
   431  }
   432  
   433  // Close The Client Connection
   434  func (c *SDBClient) Close() error {
   435  	return c.sock.Close()
   436  }
   437  
   438  //生成通过的错误信息,已经确定是有错误
   439  func makeError(resp []string, errKey ...interface{}) error {
   440  	if len(resp) < 1 {
   441  		return newError("ssdb response error")
   442  	}
   443  	//正常返回的不存在不报错,如果要捕捉这个问题请使用exists
   444  	if resp[0] == NotFound {
   445  		return ErrNotFoundInDb
   446  	}
   447  	if len(errKey) > 0 {
   448  		return newError("access ssdb error, code is %v, parameter is %v", resp, errKey)
   449  	}
   450  	return newError("access ssdb error, code is %v", resp)
   451  
   452  }
   453  
   454  //Value 扩展值,原始类型为 string
   455  type Value struct {
   456  	val []byte
   457  }
   458  
   459  //返回 string 的值
   460  func (v *Value) String() string {
   461  	return string(v.val)
   462  }
   463  
   464  //Bytes 返回 []byte 类型的值
   465  func (v *Value) Bytes() []byte {
   466  	return v.val
   467  }
   468  
   469  func toValue(val interface{}) *Value {
   470  	if val == nil {
   471  		return nil
   472  	}
   473  	if v, ok := val.(string); ok {
   474  		return &Value{val: []byte(v)}
   475  	} else if v, ok := val.([]byte); ok {
   476  		return &Value{val: v}
   477  	} else {
   478  		dlog.Error("unsupported value type", "value", val)
   479  		return nil
   480  	}
   481  }
   482  
   483  var (
   484  	byt              = []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
   485  	maxByteSize byte = 57
   486  	minByteSize byte = 48
   487  )
   488  
   489  //ToNum []byte -> int
   490  func ToNum(bs []byte) int {
   491  	re := 0
   492  	for _, v := range bs {
   493  		if v > maxByteSize || v < minByteSize {
   494  			return re
   495  		}
   496  		re = re*10 + byt[v]
   497  	}
   498  	return re
   499  }
   500  
   501  var (
   502  	//FormatString 格式化字符串
   503  	FormatString = "%v\nthe trace error is\n%s"
   504  )
   505  
   506  //返回一个错误
   507  func newError(format string, p ...interface{}) error {
   508  	return fmt.Errorf(format, p...)
   509  }
   510  
   511  //按格式返回一个错误
   512  //同时携带原始的错误信息
   513  func newErrorf(err error, format string, p ...interface{}) error {
   514  	return fmt.Errorf(FormatString, fmt.Sprintf(format, p...), err)
   515  }