func addToMap(m map[string]uint64, i int, counters [257]uint64) { v := atomic.LoadUint64(&counters[i]) if v > 0 { k := "unknown" if i < 256 { k = gomemcached.CommandCode(i).String() } m[k] = v m["total"] += v } }
func setState(client *memcached.Client, vb int, to uint32) { extras := []byte{0, 0, 0, 0} binary.BigEndian.PutUint32(extras, to) req := gomemcached.MCRequest{ Opcode: gomemcached.CommandCode(0x3d), VBucket: uint16(vb), Key: []byte{}, Body: []byte{}, Extras: extras, } client.Transmit(&req) }
func report(tdiff int64) { var total float32 = 0 trailer := []string{} for i, v := range stats { total += float32(v) if v > 0 { trailer = append(trailer, fmt.Sprintf("%s: %v", gomemcached.CommandCode(i), v)) atomic.AddInt64(&stats[i], 0-v) } } log.Printf("%.2f ops/s (%s)", total/float32(tdiff), strings.Join(trailer, ", ")) }
func grokHeader(hdrBytes []byte) (rv *gomemcached.MCResponse, err error) { if hdrBytes[0] != gomemcached.RES_MAGIC { return rv, fmt.Errorf("Bad magic: 0x%02x", hdrBytes[0]) } rv = &gomemcached.MCResponse{ Opcode: gomemcached.CommandCode(hdrBytes[1]), Key: make([]byte, binary.BigEndian.Uint16(hdrBytes[2:4])), Extras: make([]byte, hdrBytes[4]), Status: gomemcached.Status(binary.BigEndian.Uint16(hdrBytes[6:8])), Opaque: binary.BigEndian.Uint32(hdrBytes[12:16]), Cas: binary.BigEndian.Uint64(hdrBytes[16:24]), } bodyLen := binary.BigEndian.Uint32(hdrBytes[8:12]) - uint32(len(rv.Key)+len(rv.Extras)) rv.Body = make([]byte, bodyLen) return }
func grokHeader(hdrBytes []byte) (rv gomemcached.MCRequest, err error) { if hdrBytes[0] != gomemcached.REQ_MAGIC { return rv, &BadMagic{was: hdrBytes[0]} } rv.Opcode = gomemcached.CommandCode(hdrBytes[1]) rv.Key = make([]byte, binary.BigEndian.Uint16(hdrBytes[2:])) rv.Extras = make([]byte, hdrBytes[4]) // Vbucket at 6:7 rv.VBucket = binary.BigEndian.Uint16(hdrBytes[6:]) bodyLen := binary.BigEndian.Uint32(hdrBytes[8:]) - uint32(len(rv.Key)) - uint32(len(rv.Extras)) if bodyLen > MaxBodyLen { return rv, errors.New(fmt.Sprintf("%d is too big (max %s)", bodyLen, humanize.Bytes(uint64(MaxBodyLen)))) } rv.Body = make([]byte, bodyLen) rv.Opaque = binary.BigEndian.Uint32(hdrBytes[12:]) rv.Cas = binary.BigEndian.Uint64(hdrBytes[16:]) return rv, nil }
func report(ch <-chan reportMsg, wg *sync.WaitGroup) { counts := [256]uint64{} var dnu uint64 vbuckets := map[string][]int{} for msg := range ch { if msg.req != nil { counts[int(msg.req.Opcode)]++ vb := int(msg.req.VBucket) ops := msg.req.Opcode.String() if l, ok := vbuckets[ops]; ok { if !has(l, vb) { vbuckets[ops] = append(l, vb) } } else { vbuckets[ops] = []int{vb} } } else { dnu += msg.dnu } } tw := tabwriter.NewWriter(os.Stdout, 8, 4, 2, ' ', 0) for id, count := range counts { if count > 0 { cmd := gomemcached.CommandCode(id).String() fmt.Fprintf(tw, "%s\t%d\n", cmd, count) } } tw.Flush() if *dumpJson { log.Printf("Vbuckets in use:") err := json.NewEncoder(os.Stdout).Encode(vbuckets) if err != nil { log.Printf("Error in JSON encoding: %v", err) } } log.Printf("Did not understand %s bytes", humanize.Bytes(dnu)) wg.Done() }
func BenchmarkInvalidCommand(b *testing.B) { testBucketDir, _ := ioutil.TempDir("./tmp", "test") defer os.RemoveAll(testBucketDir) testBucket, _ := NewBucket(testBucketDir, &BucketSettings{ NumPartitions: MAX_VBUCKETS, }) defer testBucket.Close() testBucket.CreateVBucket(0) rh := reqHandler{currentBucket: testBucket} req := &gomemcached.MCRequest{ Opcode: gomemcached.CommandCode(255), } // Ignore time from above. b.ResetTimer() for i := 0; i < b.N; i++ { rh.HandleMessage(nil, nil, req) } }
func TestInvalidCommand(t *testing.T) { testBucketDir, _ := ioutil.TempDir("./tmp", "test") defer os.RemoveAll(testBucketDir) testBucket, _ := NewBucket(testBucketDir, &BucketSettings{ NumPartitions: MAX_VBUCKETS, }) defer testBucket.Close() testBucket.CreateVBucket(0) rh := reqHandler{currentBucket: testBucket} req := &gomemcached.MCRequest{ Opcode: gomemcached.CommandCode(255), } res := rh.HandleMessage(nil, nil, req) if res.Status != gomemcached.UNKNOWN_COMMAND { t.Fatalf("Expected unknown command, got %v", res) } }
// Memcached binary protocol packet formats and constants. package goupr import ( "github.com/dustin/gomemcached" ) const ( // Opcodes for UPR UPR_OPEN = gomemcached.CommandCode(0x50) UPR_ADD_STREAM = gomemcached.CommandCode(0x51) UPR_CLOSE_STREAM = gomemcached.CommandCode(0x52) UPR_FAILOVER_LOG = gomemcached.CommandCode(0x54) UPR_STREAM_REQ = gomemcached.CommandCode(0x53) UPR_STREAM_END = gomemcached.CommandCode(0x55) UPR_SNAPSHOTM = gomemcached.CommandCode(0x56) UPR_MUTATION = gomemcached.CommandCode(0x57) UPR_DELETION = gomemcached.CommandCode(0x58) UPR_EXPIRATION = gomemcached.CommandCode(0x59) UPR_FLUSH = gomemcached.CommandCode(0x5a) ) const ( // UPR Status ROLLBACK = gomemcached.Status(0x23) ) func init() { gomemcached.CommandNames[UPR_OPEN] = "UPR_OPEN" gomemcached.CommandNames[UPR_ADD_STREAM] = "UPR_ADD_STREAM" gomemcached.CommandNames[UPR_CLOSE_STREAM] = "UPR_CLOSE_STREAM"
"errors" "fmt" "hash/crc32" "io" "log" "sync" "sync/atomic" "time" "unsafe" "github.com/dustin/go-broadcast" "github.com/dustin/gomemcached" ) const ( CHANGES_SINCE = gomemcached.CommandCode(0x60) GET_VBMETA = gomemcached.CommandCode(0x61) SET_VBMETA = gomemcached.CommandCode(0x62) COLL_SUFFIX_KEYS = ".k" // This suffix sorts before CHANGES suffix. COLL_SUFFIX_CHANGES = ".s" // The changes is like a "sequence" stream. COLL_VBMETA = "vbm" MAX_VBID = 0x0000ffff // Due to uint16. MAX_ITEM_KEY_LENGTH = 250 MAX_ITEM_DATA_LENGTH = 1024 * 1024 MAX_ITEM_EXP = 0x7fffffff DELETION_EXP = 0x80000000 // Deletion sentinel exp. DELETION_FLAG = 0xffffffff // Deletion sentinel flag. ) var ignore = errors.New("not-an-error/sentinel")
"encoding/json" "errors" "fmt" "hash/crc32" "io" "sync" "sync/atomic" "time" "unsafe" "github.com/dustin/go-broadcast" "github.com/dustin/gomemcached" ) const ( GET_VBMETA = gomemcached.CommandCode(0x61) SET_VBMETA = gomemcached.CommandCode(0x62) COLL_SUFFIX_KEYS = ".k" // This suffix sorts before CHANGES suffix. COLL_SUFFIX_CHANGES = ".s" // The changes is like a "sequence" stream. COLL_VBMETA = "vbm" MAX_VBID = 0x0000ffff // Due to uint16. MAX_ITEM_KEY_LENGTH = 250 MAX_ITEM_DATA_LENGTH = 1024 * 1024 MAX_ITEM_EXP = 0x7fffffff ) const ( // TODO: Graduate these to gomemcached/couchbase one day. GET_META = gomemcached.CommandCode(0xa0) GETQ_META = gomemcached.CommandCode(0xa1) SET_WITH_META = gomemcached.CommandCode(0xa2)
// TODO: // performance consideration, // try to adjust buffer size for feed.C channel import ( "encoding/binary" "fmt" mcd "github.com/dustin/gomemcached" mc "github.com/dustin/gomemcached/client" "log" "time" ) // constants used for memcached protocol const ( uprOPEN = mcd.CommandCode(0x50) // Open a upr connection with `name` uprAddSTREAM = mcd.CommandCode(0x51) // Sent by ebucketmigrator to upr consumer uprCloseSTREAM = mcd.CommandCode(0x52) // Sent by ebucketmigrator to upr consumer uprFailoverLOG = mcd.CommandCode(0x54) // Request all known failover ids for restart uprStreamREQ = mcd.CommandCode(0x53) // Stream request from consumer to producer uprStreamEND = mcd.CommandCode(0x55) // Sent by producer when it is going to end stream uprSnapshotM = mcd.CommandCode(0x56) // Sent by producer for a new snapshot uprMUTATION = mcd.CommandCode(0x57) // Notifies SET/ADD/REPLACE/etc. on the server uprDELETION = mcd.CommandCode(0x58) // Notifies DELETE on the server uprEXPIRATION = mcd.CommandCode(0x59) // Notifies key expiration uprFLUSH = mcd.CommandCode(0x5a) // Notifies vbucket flush ) const ( rollBack = mcd.Status(0x23) )
"encoding/json" "errors" "fmt" "hash/crc32" "io" "sync" "sync/atomic" "time" "unsafe" "github.com/dustin/go-broadcast" "github.com/dustin/gomemcached" ) const ( GET_VBMETA = gomemcached.CommandCode(0x61) SET_VBMETA = gomemcached.CommandCode(0x62) COLL_SUFFIX_KEYS = ".k" // This suffix sorts before CHANGES suffix. COLL_SUFFIX_CHANGES = ".s" // The changes is like a "sequence" stream. COLL_VBMETA = "vbm" MAX_VBID = 0x0000ffff // Due to uint16. MAX_ITEM_KEY_LENGTH = 250 MAX_ITEM_DATA_LENGTH = 1024 * 1024 MAX_ITEM_EXP = 0x7fffffff DELETION_EXP = 0x80000000 // Deletion sentinel exp. DELETION_FLAG = 0xffffffff // Deletion sentinel flag. ) var ignore = errors.New("not-an-error/sentinel") func VBucketIdForKey(key []byte, numVBuckets int) uint16 {
package main import ( "io" "log" "net" "time" "github.com/dustin/gomemcached" "github.com/dustin/gomemcached/server" ) const ( CREATE_BUCKET = gomemcached.CommandCode(0x85) DELETE_BUCKET = gomemcached.CommandCode(0x86) LIST_BUCKETS = gomemcached.CommandCode(0x87) SELECT_BUCKET = gomemcached.CommandCode(0x89) ) type MCSession struct { dbname string } func (sess *MCSession) HandleMessage( w io.Writer, req *gomemcached.MCRequest) *gomemcached.MCResponse { switch req.Opcode { case SELECT_BUCKET: log.Printf("Selecting bucket %s", req.Key) sess.dbname = string(req.Key) case gomemcached.SETQ, gomemcached.SET: