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 }