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

     1  package themis
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  
     7  	"github.com/insionng/yougam/libraries/juju/errors"
     8  	"github.com/insionng/yougam/libraries/ngaut/log"
     9  	"github.com/insionng/yougam/libraries/pingcap/go-hbase"
    10  	"github.com/insionng/yougam/libraries/pingcap/go-hbase/iohelper"
    11  )
    12  
    13  type themisPrimaryLock struct {
    14  	*themisLock
    15  	// {coordinate => type}
    16  	secondaries map[string]hbase.Type
    17  }
    18  
    19  func newThemisPrimaryLock() *themisPrimaryLock {
    20  	return &themisPrimaryLock{
    21  		themisLock: &themisLock{
    22  			clientAddr: "null",
    23  		},
    24  		secondaries: map[string]hbase.Type{},
    25  	}
    26  }
    27  
    28  func (l *themisPrimaryLock) Primary() Lock {
    29  	return l
    30  }
    31  
    32  func (l *themisPrimaryLock) Secondaries() []Lock {
    33  	var slocks []Lock
    34  	for k, v := range l.secondaries {
    35  		c := &hbase.ColumnCoordinate{}
    36  		// TODO: handle error, now just ignore
    37  		if err := c.ParseFromString(k); err != nil {
    38  			log.Warnf("parse from string error, column coordinate: %s, secondary: %s, error: %v", c, k, err)
    39  			continue
    40  		}
    41  		slock := newThemisSecondaryLock()
    42  		slock.primaryCoordinate = l.coordinate
    43  		slock.coordinate = c
    44  		slock.ts = l.ts
    45  		slock.typ = v
    46  		slocks = append(slocks, slock)
    47  	}
    48  	return slocks
    49  }
    50  
    51  func (l *themisPrimaryLock) Encode() []byte {
    52  	buf := bytes.NewBuffer(nil)
    53  	// set is primary
    54  	binary.Write(buf, binary.BigEndian, uint8(1))
    55  	l.themisLock.write(buf)
    56  
    57  	// write secondaries
    58  	binary.Write(buf, binary.BigEndian, int32(len(l.secondaries)))
    59  	for k, v := range l.secondaries {
    60  		c := &hbase.ColumnCoordinate{}
    61  		// TODO: handle error, now just log
    62  		if err := c.ParseFromString(k); err != nil {
    63  			log.Warnf("parse from string error, column coordinate: %s, secondary: %s, error: %v", c, k, err)
    64  		}
    65  		// TODO: handle error, now just log
    66  		if err := c.Write(buf); err != nil {
    67  			log.Warnf("write error, column coordinate: %s, buf: %s, error: %v", c, buf, err)
    68  		}
    69  		buf.WriteByte(uint8(v))
    70  	}
    71  	return buf.Bytes()
    72  }
    73  
    74  func (l *themisPrimaryLock) IsExpired() bool {
    75  	return l.themisLock.expired
    76  }
    77  
    78  func (l *themisPrimaryLock) getSecondaryColumnType(c *hbase.ColumnCoordinate) hbase.Type {
    79  	v, ok := l.secondaries[c.String()]
    80  	if !ok {
    81  		return hbase.TypeMinimum
    82  	}
    83  	return v
    84  }
    85  
    86  func (l *themisPrimaryLock) Role() LockRole {
    87  	return RolePrimary
    88  }
    89  
    90  func (l *themisPrimaryLock) addSecondary(col *hbase.ColumnCoordinate, t hbase.Type) {
    91  	l.secondaries[col.String()] = t
    92  }
    93  
    94  func (l *themisPrimaryLock) parse(buf iohelper.ByteMultiReader) error {
    95  	l.themisLock.parse(buf)
    96  	var sz int32
    97  	err := binary.Read(buf, binary.BigEndian, &sz)
    98  	if err != nil {
    99  		return errors.Trace(err)
   100  	}
   101  	for i := 0; i < int(sz); i++ {
   102  		c := &hbase.ColumnCoordinate{}
   103  		c.ParseField(buf)
   104  		b, err := buf.ReadByte()
   105  		if err != nil {
   106  			return errors.Trace(err)
   107  		}
   108  		t := hbase.Type(b)
   109  		l.addSecondary(c, t)
   110  	}
   111  	return nil
   112  }