forked from forgejo/forgejo
go1.16 (#14783)
This commit is contained in:
parent
030646eea4
commit
47f6a4ec3f
947 changed files with 26119 additions and 7062 deletions
110
vendor/github.com/couchbase/gomemcached/client/mc.go
generated
vendored
110
vendor/github.com/couchbase/gomemcached/client/mc.go
generated
vendored
|
@ -44,6 +44,7 @@ type ClientIface interface {
|
|||
GetSubdoc(vb uint16, key string, subPaths []string, context ...*ClientContext) (*gomemcached.MCResponse, error)
|
||||
Hijack() io.ReadWriteCloser
|
||||
Incr(vb uint16, key string, amt, def uint64, exp int, context ...*ClientContext) (uint64, error)
|
||||
LastBucket() string
|
||||
Observe(vb uint16, key string) (result ObserveResult, err error)
|
||||
ObserveSeq(vb uint16, vbuuid uint64) (result *ObserveSeqResult, err error)
|
||||
Receive() (*gomemcached.MCResponse, error)
|
||||
|
@ -56,6 +57,7 @@ type ClientIface interface {
|
|||
SelectBucket(bucket string) (*gomemcached.MCResponse, error)
|
||||
SetCas(vb uint16, key string, flags int, exp int, cas uint64, body []byte, context ...*ClientContext) (*gomemcached.MCResponse, error)
|
||||
Stats(key string) ([]StatValue, error)
|
||||
StatsFunc(key string, fn func(key, val []byte)) error
|
||||
StatsMap(key string) (map[string]string, error)
|
||||
StatsMapForSpecifiedStats(key string, statsMap map[string]string) error
|
||||
Transmit(req *gomemcached.MCRequest) error
|
||||
|
@ -74,6 +76,9 @@ type ClientContext struct {
|
|||
// Collection-based context
|
||||
CollId uint32
|
||||
|
||||
// Impersonate context
|
||||
User string
|
||||
|
||||
// VB-state related context
|
||||
// nil means not used in this context
|
||||
VbState *VbStateType
|
||||
|
@ -147,6 +152,7 @@ type Client struct {
|
|||
|
||||
collectionsEnabled uint32
|
||||
deadline time.Time
|
||||
bucket string
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -206,6 +212,13 @@ func (c *Client) SetDeadline(t time.Time) {
|
|||
c.deadline = t
|
||||
}
|
||||
|
||||
func (c *Client) getOpaque() uint32 {
|
||||
if c.opaque >= math.MaxInt32 {
|
||||
c.opaque = uint32(1)
|
||||
}
|
||||
return c.opaque + 1
|
||||
}
|
||||
|
||||
// Wrap an existing transport.
|
||||
func Wrap(conn memcachedConnection) (rv *Client, err error) {
|
||||
client := &Client{
|
||||
|
@ -356,12 +369,21 @@ func (c *Client) EnableFeatures(features Features) (*gomemcached.MCResponse, err
|
|||
return rv, err
|
||||
}
|
||||
|
||||
// Sets collection info for a request
|
||||
func (c *Client) setCollection(req *gomemcached.MCRequest, context ...*ClientContext) error {
|
||||
// Sets collection and user info for a request
|
||||
func (c *Client) setContext(req *gomemcached.MCRequest, context ...*ClientContext) error {
|
||||
req.CollIdLen = 0
|
||||
req.UserLen = 0
|
||||
collectionId := uint32(0)
|
||||
if len(context) > 0 {
|
||||
collectionId = context[0].CollId
|
||||
uLen := len(context[0].User)
|
||||
if uLen > 0 {
|
||||
if uLen > gomemcached.MAX_USER_LEN {
|
||||
uLen = gomemcached.MAX_USER_LEN
|
||||
}
|
||||
req.UserLen = uLen
|
||||
copy(req.Username[:uLen], context[0].User)
|
||||
}
|
||||
}
|
||||
|
||||
// if the optional collection is specified, it must be default for clients that haven't turned on collections
|
||||
|
@ -376,10 +398,16 @@ func (c *Client) setCollection(req *gomemcached.MCRequest, context ...*ClientCon
|
|||
}
|
||||
|
||||
// Sets collection info in extras
|
||||
func (c *Client) setExtrasCollection(req *gomemcached.MCRequest, context ...*ClientContext) error {
|
||||
func (c *Client) setExtrasContext(req *gomemcached.MCRequest, context ...*ClientContext) error {
|
||||
collectionId := uint32(0)
|
||||
req.UserLen = 0
|
||||
if len(context) > 0 {
|
||||
collectionId = context[0].CollId
|
||||
uLen := len(context[0].User)
|
||||
if uLen > 0 {
|
||||
req.UserLen = uLen
|
||||
copy(req.Username[:], context[0].User)
|
||||
}
|
||||
}
|
||||
|
||||
// if the optional collection is specified, it must be default for clients that haven't turned on collections
|
||||
|
@ -426,8 +454,9 @@ func (c *Client) Get(vb uint16, key string, context ...*ClientContext) (*gomemca
|
|||
Opcode: gomemcached.GET,
|
||||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Opaque: c.getOpaque(),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -443,8 +472,9 @@ func (c *Client) GetSubdoc(vb uint16, key string, subPaths []string, context ...
|
|||
Key: []byte(key),
|
||||
Extras: extraBuf,
|
||||
Body: valueBuf,
|
||||
Opaque: c.getOpaque(),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -462,6 +492,7 @@ func (c *Client) GetCollectionsManifest() (*gomemcached.MCResponse, error) {
|
|||
|
||||
res, err := c.Send(&gomemcached.MCRequest{
|
||||
Opcode: gomemcached.GET_COLLECTIONS_MANIFEST,
|
||||
Opaque: c.getOpaque(),
|
||||
})
|
||||
|
||||
if err != nil && IfResStatusError(res) {
|
||||
|
@ -476,6 +507,7 @@ func (c *Client) CollectionsGetCID(scope string, collection string) (*gomemcache
|
|||
res, err := c.Send(&gomemcached.MCRequest{
|
||||
Opcode: gomemcached.COLLECTIONS_GET_CID,
|
||||
Key: []byte(scope + "." + collection),
|
||||
Opaque: c.getOpaque(),
|
||||
})
|
||||
|
||||
if err != nil && IfResStatusError(res) {
|
||||
|
@ -497,8 +529,9 @@ func (c *Client) GetAndTouch(vb uint16, key string, exp int, context ...*ClientC
|
|||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Extras: extraBuf,
|
||||
Opaque: c.getOpaque(),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -511,8 +544,9 @@ func (c *Client) GetMeta(vb uint16, key string, context ...*ClientContext) (*gom
|
|||
Opcode: gomemcached.GET_META,
|
||||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Opaque: c.getOpaque(),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -525,8 +559,9 @@ func (c *Client) Del(vb uint16, key string, context ...*ClientContext) (*gomemca
|
|||
Opcode: gomemcached.DELETE,
|
||||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Opaque: c.getOpaque(),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -537,8 +572,9 @@ func (c *Client) Del(vb uint16, key string, context ...*ClientContext) (*gomemca
|
|||
func (c *Client) GetRandomDoc(context ...*ClientContext) (*gomemcached.MCResponse, error) {
|
||||
req := &gomemcached.MCRequest{
|
||||
Opcode: 0xB6,
|
||||
Opaque: c.getOpaque(),
|
||||
}
|
||||
err := c.setExtrasCollection(req, context...)
|
||||
err := c.setExtrasContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -638,9 +674,17 @@ func (c *Client) AuthPlain(user, pass string) (*gomemcached.MCResponse, error) {
|
|||
|
||||
// select bucket
|
||||
func (c *Client) SelectBucket(bucket string) (*gomemcached.MCResponse, error) {
|
||||
return c.Send(&gomemcached.MCRequest{
|
||||
res, err := c.Send(&gomemcached.MCRequest{
|
||||
Opcode: gomemcached.SELECT_BUCKET,
|
||||
Key: []byte(bucket)})
|
||||
if res != nil {
|
||||
c.bucket = bucket
|
||||
}
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (c *Client) LastBucket() string {
|
||||
return c.bucket
|
||||
}
|
||||
|
||||
func (c *Client) store(opcode gomemcached.CommandCode, vb uint16,
|
||||
|
@ -650,11 +694,11 @@ func (c *Client) store(opcode gomemcached.CommandCode, vb uint16,
|
|||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Cas: 0,
|
||||
Opaque: 0,
|
||||
Opaque: c.getOpaque(),
|
||||
Extras: []byte{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
Body: body}
|
||||
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -669,11 +713,11 @@ func (c *Client) storeCas(opcode gomemcached.CommandCode, vb uint16,
|
|||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Cas: cas,
|
||||
Opaque: 0,
|
||||
Opaque: c.getOpaque(),
|
||||
Extras: []byte{0, 0, 0, 0, 0, 0, 0, 0},
|
||||
Body: body}
|
||||
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -691,7 +735,7 @@ func (c *Client) Incr(vb uint16, key string,
|
|||
Key: []byte(key),
|
||||
Extras: make([]byte, 8+8+4),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -717,7 +761,7 @@ func (c *Client) Decr(vb uint16, key string,
|
|||
Key: []byte(key),
|
||||
Extras: make([]byte, 8+8+4),
|
||||
}
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
@ -759,10 +803,10 @@ func (c *Client) Append(vb uint16, key string, data []byte, context ...*ClientCo
|
|||
VBucket: vb,
|
||||
Key: []byte(key),
|
||||
Cas: 0,
|
||||
Opaque: 0,
|
||||
Opaque: c.getOpaque(),
|
||||
Body: data}
|
||||
|
||||
err := c.setCollection(req, context...)
|
||||
err := c.setContext(req, context...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -839,7 +883,7 @@ func (c *Client) GetBulk(vb uint16, keys []string, rv map[string]*gomemcached.MC
|
|||
Opcode: gomemcached.GET,
|
||||
VBucket: vb,
|
||||
}
|
||||
err := c.setCollection(memcachedReqPkt, context...)
|
||||
err := c.setContext(memcachedReqPkt, context...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -1216,6 +1260,34 @@ func (c *Client) Stats(key string) ([]StatValue, error) {
|
|||
return rv, nil
|
||||
}
|
||||
|
||||
// Stats requests server-side stats.
|
||||
//
|
||||
// Use "" as the stat key for toplevel stats.
|
||||
func (c *Client) StatsFunc(key string, fn func(key, val []byte)) error {
|
||||
req := &gomemcached.MCRequest{
|
||||
Opcode: gomemcached.STAT,
|
||||
Key: []byte(key),
|
||||
Opaque: 918494,
|
||||
}
|
||||
|
||||
err := c.Transmit(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for {
|
||||
res, _, err := getResponse(c.conn, c.hdrBuf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(res.Key) == 0 {
|
||||
break
|
||||
}
|
||||
fn(res.Key, res.Body)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// StatsMap requests server-side stats similarly to Stats, but returns
|
||||
// them as a map.
|
||||
//
|
||||
|
|
39
vendor/github.com/couchbase/gomemcached/flexibleFraming.go
generated
vendored
39
vendor/github.com/couchbase/gomemcached/flexibleFraming.go
generated
vendored
|
@ -12,8 +12,13 @@ const (
|
|||
FrameDurability FrameObjType = iota
|
||||
FrameDcpStreamId FrameObjType = iota
|
||||
FrameOpenTracing FrameObjType = iota
|
||||
FrameImpersonate FrameObjType = iota
|
||||
)
|
||||
|
||||
const MAX_USER_LEN = 15 // TODO half byte shifting to be implemented
|
||||
// it's not very efficient so we currently truncate user names
|
||||
const FAST_USER_LEN = 15
|
||||
|
||||
type FrameInfo struct {
|
||||
ObjId FrameObjType
|
||||
ObjLen int
|
||||
|
@ -44,11 +49,12 @@ func (f *FrameInfo) Validate() error {
|
|||
return ErrorObjLenNotMatch
|
||||
}
|
||||
case FrameOpenTracing:
|
||||
if f.ObjLen == 0 {
|
||||
return fmt.Errorf("Invalid FrameOpenTracing - length must be > 0")
|
||||
if f.ObjLen != 1 {
|
||||
return fmt.Errorf("Invalid FrameImpersonate - length is %v\n", f.ObjLen)
|
||||
} else if f.ObjLen != len(f.ObjData) {
|
||||
return ErrorObjLenNotMatch
|
||||
}
|
||||
case FrameImpersonate:
|
||||
default:
|
||||
return fmt.Errorf("Unknown FrameInfo type")
|
||||
}
|
||||
|
@ -108,16 +114,27 @@ func incrementMarker(bitsToBeIncremented, byteIncrementCnt *int, framingElen, cu
|
|||
return marker, nil
|
||||
}
|
||||
|
||||
// Right now, halfByteRemaining will always be false, because ObjID and Len haven't gotten that large yet
|
||||
func (f *FrameInfo) Bytes() (output []byte, halfByteRemaining bool) {
|
||||
// ObjIdentifier - 4 bits + ObjLength - 4 bits
|
||||
var idAndLen uint8
|
||||
idAndLen |= uint8(f.ObjId) << 4
|
||||
idAndLen |= uint8(f.ObjLen)
|
||||
output = append(output, byte(idAndLen))
|
||||
func (f *FrameInfo) Bytes() ([]byte, bool) {
|
||||
return obj2Bytes(f.ObjId, f.ObjLen, f.ObjData)
|
||||
}
|
||||
|
||||
// Rest is Data
|
||||
output = append(output, f.ObjData...)
|
||||
// TODO implement half byte shifting for impersonate user names
|
||||
// halfByteRemaining will always be false, because ObjID and Len haven't gotten that large yet
|
||||
// and user names are truncated
|
||||
func obj2Bytes(id FrameObjType, len int, data []byte) (output []byte, halfByteRemaining bool) {
|
||||
if len < 16 {
|
||||
|
||||
// ObjIdentifier - 4 bits + ObjLength - 4 bits
|
||||
var idAndLen uint8
|
||||
idAndLen |= uint8(id) << 4
|
||||
idAndLen |= uint8(len)
|
||||
output = append(output, byte(idAndLen))
|
||||
|
||||
// Rest is Data
|
||||
output = append(output, data[:len]...)
|
||||
|
||||
} else {
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
|
165
vendor/github.com/couchbase/gomemcached/mc_req.go
generated
vendored
165
vendor/github.com/couchbase/gomemcached/mc_req.go
generated
vendored
|
@ -33,6 +33,10 @@ type MCRequest struct {
|
|||
CollId [binary.MaxVarintLen32]byte
|
||||
// Length of collection id
|
||||
CollIdLen int
|
||||
// Impersonate user name - could go in FramingExtras, but for efficiency
|
||||
Username [MAX_USER_LEN]byte
|
||||
// Length of Impersonate user name
|
||||
UserLen int
|
||||
// Flexible Framing Extras
|
||||
FramingExtras []FrameInfo
|
||||
// Stored length of incoming framing extras
|
||||
|
@ -41,7 +45,24 @@ type MCRequest struct {
|
|||
|
||||
// Size gives the number of bytes this request requires.
|
||||
func (req *MCRequest) HdrSize() int {
|
||||
return HDR_LEN + len(req.Extras) + req.CollIdLen + req.FramingElen + len(req.Key)
|
||||
rv := HDR_LEN + len(req.Extras) + req.CollIdLen + req.FramingElen + len(req.Key)
|
||||
if req.UserLen != 0 {
|
||||
rv += req.UserLen + 1
|
||||
|
||||
// half byte shifting required
|
||||
if req.UserLen > FAST_USER_LEN {
|
||||
rv++
|
||||
}
|
||||
}
|
||||
for _, e := range req.FramingExtras {
|
||||
rv += e.ObjLen + 1
|
||||
|
||||
// half byte shifting required
|
||||
if e.ObjLen > FAST_USER_LEN {
|
||||
rv++
|
||||
}
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
func (req *MCRequest) Size() int {
|
||||
|
@ -125,6 +146,85 @@ func (req *MCRequest) fillRegularHeaderBytes(data []byte) int {
|
|||
return pos
|
||||
}
|
||||
|
||||
func (req *MCRequest) fillFastFlexHeaderBytes(data []byte) int {
|
||||
// Byte/ 0 | 1 | 2 | 3 |
|
||||
// / | | | |
|
||||
// |0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|0 1 2 3 4 5 6 7|
|
||||
// +---------------+---------------+---------------+---------------+
|
||||
// 0| Magic | Opcode | Framing extras| Key Length |
|
||||
// +---------------+---------------+---------------+---------------+
|
||||
// 4| Extras length | Data type | vbucket id |
|
||||
// +---------------+---------------+---------------+---------------+
|
||||
// 8| Total body length |
|
||||
// +---------------+---------------+---------------+---------------+
|
||||
// 12| Opaque |
|
||||
// +---------------+---------------+---------------+---------------+
|
||||
// 16| CAS |
|
||||
// | |
|
||||
// +---------------+---------------+---------------+---------------+
|
||||
// Total 24 bytes
|
||||
|
||||
pos := 0
|
||||
data[pos] = FLEX_MAGIC
|
||||
pos++
|
||||
data[pos] = byte(req.Opcode)
|
||||
pos++
|
||||
data[pos] = byte(req.UserLen + 1)
|
||||
pos++
|
||||
data[pos] = byte(len(req.Key) + req.CollIdLen)
|
||||
pos++
|
||||
|
||||
// 4
|
||||
data[pos] = byte(len(req.Extras))
|
||||
pos++
|
||||
// Data type
|
||||
if req.DataType != 0 {
|
||||
data[pos] = byte(req.DataType)
|
||||
}
|
||||
pos++
|
||||
binary.BigEndian.PutUint16(data[pos:pos+2], req.VBucket)
|
||||
pos += 2
|
||||
|
||||
// 8
|
||||
binary.BigEndian.PutUint32(data[pos:pos+4],
|
||||
uint32(len(req.Body)+req.CollIdLen+len(req.Key)+(req.UserLen+1)+len(req.Extras)+len(req.ExtMeta)))
|
||||
pos += 4
|
||||
|
||||
// 12
|
||||
binary.BigEndian.PutUint32(data[pos:pos+4], req.Opaque)
|
||||
pos += 4
|
||||
|
||||
// 16
|
||||
if req.Cas != 0 {
|
||||
binary.BigEndian.PutUint64(data[pos:pos+8], req.Cas)
|
||||
}
|
||||
pos += 8
|
||||
|
||||
// 24 Flexible extras
|
||||
if req.UserLen > 0 {
|
||||
data[pos] = byte((uint8(FrameImpersonate) << 4) | uint8(req.UserLen))
|
||||
pos++
|
||||
copy(data[pos:pos+req.UserLen], req.Username[:req.UserLen])
|
||||
pos += req.UserLen
|
||||
}
|
||||
|
||||
if len(req.Extras) > 0 {
|
||||
copy(data[pos:pos+len(req.Extras)], req.Extras)
|
||||
pos += len(req.Extras)
|
||||
}
|
||||
|
||||
if len(req.Key) > 0 {
|
||||
if req.CollIdLen > 0 {
|
||||
copy(data[pos:pos+req.CollIdLen], req.CollId[:])
|
||||
pos += req.CollIdLen
|
||||
}
|
||||
copy(data[pos:pos+len(req.Key)], req.Key)
|
||||
pos += len(req.Key)
|
||||
}
|
||||
|
||||
return pos
|
||||
}
|
||||
|
||||
// Returns pos and if trailing by half byte
|
||||
func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
|
||||
|
||||
|
@ -147,16 +247,13 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
|
|||
|
||||
data[0] = FLEX_MAGIC
|
||||
data[1] = byte(req.Opcode)
|
||||
data[2] = byte(req.FramingElen)
|
||||
data[3] = byte(req.Keylen + req.CollIdLen)
|
||||
data[3] = byte(len(req.Key) + req.CollIdLen)
|
||||
elen := len(req.Extras)
|
||||
data[4] = byte(elen)
|
||||
if req.DataType != 0 {
|
||||
data[5] = byte(req.DataType)
|
||||
}
|
||||
binary.BigEndian.PutUint16(data[6:8], req.VBucket)
|
||||
binary.BigEndian.PutUint32(data[8:12],
|
||||
uint32(len(req.Body)+req.Keylen+req.CollIdLen+elen+len(req.ExtMeta)+req.FramingElen))
|
||||
binary.BigEndian.PutUint32(data[12:16], req.Opaque)
|
||||
if req.Cas != 0 {
|
||||
binary.BigEndian.PutUint64(data[16:24], req.Cas)
|
||||
|
@ -197,12 +294,46 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// fast impersonate Flexible Extra
|
||||
if req.UserLen > 0 {
|
||||
if !mergeMode {
|
||||
outputBytes, halfByteMode = obj2Bytes(FrameImpersonate, req.UserLen, req.Username[:req.UserLen])
|
||||
if !halfByteMode {
|
||||
framingExtras = append(framingExtras, outputBytes...)
|
||||
frameBytes += len(outputBytes)
|
||||
} else {
|
||||
mergeMode = true
|
||||
mergeModeSrc = outputBytes
|
||||
}
|
||||
} else {
|
||||
outputBytes, halfByteMode = obj2Bytes(FrameImpersonate, req.UserLen, req.Username[:req.UserLen])
|
||||
outputBytes := ShiftByteSliceRight4Bits(outputBytes)
|
||||
if halfByteMode {
|
||||
// Previous halfbyte merge with this halfbyte will result in a complete byte
|
||||
mergeMode = false
|
||||
outputBytes = Merge2HalfByteSlices(mergeModeSrc, outputBytes)
|
||||
framingExtras = append(framingExtras, outputBytes...)
|
||||
frameBytes += len(outputBytes)
|
||||
} else {
|
||||
// Merge half byte with a non-half byte will result in a combined half-byte that will
|
||||
// become the source for the next iteration
|
||||
mergeModeSrc = Merge2HalfByteSlices(mergeModeSrc, outputBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if mergeMode {
|
||||
// Commit the temporary merge area into framingExtras
|
||||
framingExtras = append(framingExtras, mergeModeSrc...)
|
||||
frameBytes += len(mergeModeSrc)
|
||||
}
|
||||
|
||||
req.FramingElen = frameBytes
|
||||
|
||||
// these have to be set after we have worked out the size of the Flexible Extras
|
||||
data[2] = byte(req.FramingElen)
|
||||
binary.BigEndian.PutUint32(data[8:12],
|
||||
uint32(len(req.Body)+len(req.Key)+req.CollIdLen+elen+len(req.ExtMeta)+req.FramingElen))
|
||||
copy(data[pos:pos+frameBytes], framingExtras)
|
||||
|
||||
pos += frameBytes
|
||||
|
@ -219,19 +350,21 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
|
|||
}
|
||||
|
||||
// Add keys
|
||||
if req.Keylen > 0 {
|
||||
if len(req.Key) > 0 {
|
||||
if mergeMode {
|
||||
var key []byte
|
||||
var keylen int
|
||||
|
||||
if req.CollIdLen == 0 {
|
||||
key = req.Key
|
||||
keylen = req.Keylen
|
||||
keylen = len(req.Key)
|
||||
} else {
|
||||
key = append(key, req.CollId[:]...)
|
||||
key = append(key, req.Key...)
|
||||
keylen = req.Keylen + req.CollIdLen
|
||||
keylen = len(req.Key) + req.CollIdLen
|
||||
}
|
||||
outputBytes = ShiftByteSliceRight4Bits(req.Key)
|
||||
|
||||
outputBytes = ShiftByteSliceRight4Bits(key)
|
||||
data = Merge2HalfByteSlices(data, outputBytes)
|
||||
pos += keylen
|
||||
} else {
|
||||
|
@ -239,8 +372,8 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
|
|||
copy(data[pos:pos+req.CollIdLen], req.CollId[:])
|
||||
pos += req.CollIdLen
|
||||
}
|
||||
copy(data[pos:pos+req.Keylen], req.Key)
|
||||
pos += req.Keylen
|
||||
copy(data[pos:pos+len(req.Key)], req.Key)
|
||||
pos += len(req.Key)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,17 +381,19 @@ func (req *MCRequest) fillFlexHeaderBytes(data []byte) (int, bool) {
|
|||
}
|
||||
|
||||
func (req *MCRequest) FillHeaderBytes(data []byte) (int, bool) {
|
||||
if req.FramingElen == 0 {
|
||||
return req.fillRegularHeaderBytes(data), false
|
||||
} else {
|
||||
if len(req.FramingExtras) > 0 || req.UserLen > FAST_USER_LEN {
|
||||
return req.fillFlexHeaderBytes(data)
|
||||
} else if req.UserLen > 0 {
|
||||
return req.fillFastFlexHeaderBytes(data), false
|
||||
} else {
|
||||
return req.fillRegularHeaderBytes(data), false
|
||||
}
|
||||
}
|
||||
|
||||
// HeaderBytes will return the wire representation of the request header
|
||||
// (with the extras and key).
|
||||
func (req *MCRequest) HeaderBytes() []byte {
|
||||
data := make([]byte, HDR_LEN+len(req.Extras)+req.CollIdLen+len(req.Key)+req.FramingElen)
|
||||
data := make([]byte, req.HdrSize())
|
||||
|
||||
req.FillHeaderBytes(data)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue