github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/pingcap/go-themis/themis_lock.go (about)

     1  package themis
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"io"
     7  
     8  	"github.com/insionng/yougam/libraries/juju/errors"
     9  	"github.com/insionng/yougam/libraries/pingcap/go-hbase"
    10  	"github.com/insionng/yougam/libraries/pingcap/go-hbase/iohelper"
    11  )
    12  
    13  var (
    14  	_ Lock = (*themisPrimaryLock)(nil)
    15  	_ Lock = (*themisSecondaryLock)(nil)
    16  )
    17  
    18  type themisLock struct {
    19  	// lock coordinate, table, row, cf, q
    20  	coordinate *hbase.ColumnCoordinate
    21  	// lock type: put/delete/minimal(lock only)
    22  	typ hbase.Type
    23  	// prewrite ts
    24  	ts uint64
    25  	// not used, for alignment
    26  	wallTs uint64
    27  	// not used, for alignment
    28  	clientAddr string
    29  	expired    bool
    30  }
    31  
    32  func (l *themisLock) Timestamp() uint64 {
    33  	return l.ts
    34  }
    35  
    36  func (l *themisLock) IsExpired() bool {
    37  	return l.expired
    38  }
    39  
    40  func (l *themisLock) SetExpired(b bool) {
    41  	l.expired = b
    42  }
    43  
    44  func (l *themisLock) SetCoordinate(c *hbase.ColumnCoordinate) {
    45  	l.coordinate = c
    46  }
    47  
    48  func (l *themisLock) Coordinate() *hbase.ColumnCoordinate {
    49  	return l.coordinate
    50  }
    51  
    52  func (l *themisLock) Context() interface{} {
    53  	return nil
    54  }
    55  
    56  func (l *themisLock) Type() hbase.Type {
    57  	return l.typ
    58  }
    59  
    60  func (l *themisLock) write(w io.Writer) {
    61  	binary.Write(w, binary.BigEndian, byte(l.typ))
    62  	binary.Write(w, binary.BigEndian, int64(l.ts))
    63  	// write client addr
    64  	iohelper.WriteVarBytes(w, []byte(l.clientAddr))
    65  	binary.Write(w, binary.BigEndian, int64(l.wallTs))
    66  }
    67  
    68  func (l *themisLock) parse(r iohelper.ByteMultiReader) error {
    69  	// read type
    70  	var typ uint8
    71  	err := binary.Read(r, binary.BigEndian, &typ)
    72  	if err != nil {
    73  		return errors.Trace(err)
    74  	}
    75  	l.typ = hbase.Type(typ)
    76  
    77  	// read ts
    78  	var ts int64
    79  	err = binary.Read(r, binary.BigEndian, &ts)
    80  	if err != nil {
    81  		return errors.Trace(err)
    82  	}
    83  	l.ts = uint64(ts)
    84  
    85  	// read client addr
    86  	sz, err := binary.ReadUvarint(r)
    87  	if err != nil {
    88  		return errors.Trace(err)
    89  	}
    90  	addr := make([]byte, sz)
    91  	r.Read(addr)
    92  	l.clientAddr = string(addr)
    93  
    94  	// read wall time
    95  	var wallTs int64
    96  	err = binary.Read(r, binary.BigEndian, &wallTs)
    97  	if err != nil {
    98  		return errors.Trace(err)
    99  	}
   100  	l.wallTs = uint64(wallTs)
   101  	return nil
   102  }
   103  
   104  func parseLockFromBytes(b []byte) (Lock, error) {
   105  	buf := bytes.NewBuffer(b)
   106  	var isPrimary uint8
   107  	err := binary.Read(buf, binary.BigEndian, &isPrimary)
   108  	if err != nil {
   109  		return nil, errors.Trace(err)
   110  	}
   111  	var ret Lock
   112  	if isPrimary == 1 {
   113  		l := newThemisPrimaryLock()
   114  		err = l.parse(buf)
   115  		ret = l
   116  	} else {
   117  		l := newThemisSecondaryLock()
   118  		err = l.parse(buf)
   119  		ret = l
   120  	}
   121  	if err != nil {
   122  		return nil, errors.Trace(err)
   123  	}
   124  	return ret, nil
   125  }
   126  
   127  func isLockResult(r *hbase.ResultRow) bool {
   128  	return len(r.SortedColumns) > 0 && isLockColumn(r.SortedColumns[0].Column)
   129  }
   130  
   131  func isLockColumn(c hbase.Column) bool {
   132  	return bytes.Compare(c.Family, LockFamilyName) == 0
   133  }