Changeset 686

Show
Ignore:
Timestamp:
12/19/07 08:34:45 (1 year ago)
Author:
dormando
Message:

Updates for the new binary protocol (draft-stone-memcache-binary-01). (Dustin Sallings)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/binary/server/memcached.c

    r674 r686  
    828828} 
    829829 
    830 static void add_bin_header(conn *c, int err, int body_len) { 
     830static void add_bin_header(conn *c, int err, int hdr_len, int body_len) { 
    831831    int i=0; 
    832832    uint32_t res_header[BIN_PKT_HDR_WORDS]; 
     
    846846    res_header[0] = BIN_RES_MAGIC << 24; 
    847847    res_header[0] |= ((0xff & c->cmd) << 16); 
    848     res_header[0] |= (err << 8); 
    849  
    850     res_header[1] = c->opaque; 
     848    res_header[0] |= err & 0xffff; 
     849 
     850    res_header[1] = hdr_len << 24; 
     851    /* TODO:  Support datatype */ 
    851852    res_header[2] = body_len; 
     853    res_header[3] = c->opaque; 
    852854 
    853855    if(settings.verbose > 1) { 
    854         fprintf(stderr, "Writing bin response:  %08x %08x %08x\n", 
    855             res_header[0], res_header[1], res_header[2]); 
     856        fprintf(stderr, "Writing bin response:  %08x %08x %08x %08x\n", 
     857            res_header[0], res_header[1], res_header[2], res_header[3]); 
    856858    } 
    857859 
     
    893895        fprintf(stderr, "Writing an error:  %s\n", errstr); 
    894896    } 
    895     add_bin_header(c, err, strlen(errstr)); 
     897    add_bin_header(c, err, 0, strlen(errstr)); 
    896898    add_iov(c, errstr, strlen(errstr)); 
    897899 
     
    906908 
    907909/* Form and send a response to a command over the binary protocol */ 
    908 static void write_bin_response(conn *c, void *d, int dlen) { 
    909     add_bin_header(c, 0, dlen); 
     910static void write_bin_response(conn *c, void *d, int hlen, int dlen) { 
     911    add_bin_header(c, 0, hlen, dlen); 
    910912    if(dlen > 0) { 
    911913        add_iov(c, d, dlen); 
     
    981983        memset(responseBuf, ' ', 32); 
    982984        responseBuf[32]=0x00; 
    983         add_delta(it, true, delta, responseBuf); 
     985        add_delta(it, c->cmd == CMD_INCR, delta, responseBuf); 
    984986        res = strlen(responseBuf); 
    985987         
    986988        assert(res > 0); 
    987         write_bin_response(c, responseBuf, res); 
     989        write_bin_response(c, responseBuf, BIN_INCR_HDR_LEN, res); 
    988990        item_remove(it);         /* release our reference */ 
    989991    } else { 
     
    9991001             
    10001002            if(store_item(it, NREAD_SET)) { 
    1001                 write_bin_response(c, responseBuf, res); 
     1003                write_bin_response(c, responseBuf, BIN_INCR_HDR_LEN, res); 
    10021004            } else { 
    10031005                write_bin_error(c, ERR_NOT_STORED, 0); 
     
    10281030        case 1: 
    10291031            /* Stored */ 
    1030             write_bin_response(c, NULL, 0); 
     1032            write_bin_response(c, NULL, BIN_SET_HDR_LEN, 0); 
    10311033            break; 
    10321034        case 2: 
     
    10571059    if (it) { 
    10581060        int *flags; 
     1061        uint64_t* identifier; 
    10591062 
    10601063        assert(c->rsize >= MIN_BIN_PKT_LENGTH + 4); 
     
    10661069 
    10671070        /* the length has two unnecessary bytes, and then we write four more */ 
    1068         add_bin_header(c, 0, it->nbytes - 2 + 4 + (c->cmd == CMD_GETS?8:0)); 
     1071        add_bin_header(c, 0, GET_RES_HDR_LEN, it->nbytes - 2 + GET_RES_HDR_LEN); 
    10691072        /* Flags */ 
    10701073        add_iov(c, flags, 4); 
    1071         /* if it's a gets, add the identifier */ 
    1072         if(c->cmd == CMD_GETS) { 
    1073             uint64_t* identifier; 
    1074             identifier=(uint64_t*)(c->wbuf + MIN_BIN_PKT_LENGTH + 4); 
    1075             *identifier=swap64((uint32_t)it->cas_id); 
    1076             add_iov(c, identifier, 8); 
    1077         } 
     1074        identifier=(uint64_t*)(c->wbuf + MIN_BIN_PKT_LENGTH + 4); 
     1075        *identifier=swap64((uint32_t)it->cas_id); 
     1076        add_iov(c, identifier, 8); 
    10781077        /* bytes minus the CRLF */ 
    10791078        add_iov(c, ITEM_data(it), it->nbytes - 2); 
     
    11011100    switch(c->cmd) { 
    11021101        case CMD_VERSION: 
    1103             write_bin_response(c, VERSION, strlen(VERSION)); 
     1102            write_bin_response(c, VERSION, 0, strlen(VERSION)); 
    11041103            break; 
    11051104        case CMD_FLUSH: 
     
    11081107            settings.oldest_live = current_time - 1; 
    11091108            item_flush_expired(); 
    1110             write_bin_response(c, NULL, 0); 
     1109            write_bin_response(c, NULL, 0, 0); 
    11111110            break; 
    11121111        case CMD_NOOP: 
    1113             write_bin_response(c, NULL, 0); 
     1112            write_bin_response(c, NULL, 0, 0); 
    11141113            break; 
    11151114        case CMD_SET: 
     
    11201119            bin_read_key(c, bin_reading_set_header, BIN_SET_HDR_LEN); 
    11211120            break; 
    1122         case CMD_CAS: 
    1123             bin_read_key(c, bin_reading_cas_header, BIN_CAS_HDR_LEN); 
    1124             break; 
    1125         case CMD_GETS: 
    11261121        case CMD_GETQ: 
    11271122        case CMD_GET: 
     
    11321127            break; 
    11331128        case CMD_INCR: 
     1129        case CMD_DECR: 
    11341130            bin_read_key(c, bin_reading_incr_header, BIN_INCR_HDR_LEN); 
    11351131            break; 
     
    11391135} 
    11401136 
    1141 static void process_bin_update(conn *c, bool cas) { 
     1137static void process_bin_update(conn *c) { 
    11421138    char *key; 
    11431139    int nkey; 
     
    11471143    item *it; 
    11481144    int comm; 
    1149     int hdrlen=cas ? BIN_CAS_HDR_LEN : BIN_SET_HDR_LEN; 
     1145    int hdrlen=BIN_SET_HDR_LEN; 
    11501146 
    11511147    assert(c != NULL); 
     
    11831179 
    11841180    it = item_alloc(key, nkey, flags, realtime(exptime), vlen+2); 
    1185     if(cas) { 
    1186         it->cas_id = (uint64_t)swap64(*((int64_t*)(c->rbuf + 8))); 
    1187     } 
    11881181 
    11891182    if (it == 0) { 
     
    11981191    } 
    11991192 
     1193    it->cas_id = (uint64_t)swap64(*((int64_t*)(c->rbuf + 8))); 
     1194 
    12001195    switch(c->cmd) { 
    12011196        case CMD_ADD: 
    12021197            c->item_comm = NREAD_ADD; 
    12031198            break; 
    1204         case CMD_CAS: 
    1205             c->item_comm = NREAD_CAS; 
    1206             break; 
    12071199        case CMD_SET: 
    12081200            c->item_comm = NREAD_SET; 
     
    12131205        default: 
    12141206            assert(0); 
     1207    } 
     1208 
     1209    if(it->cas_id != 0) { 
     1210        c->item_comm = NREAD_CAS; 
    12151211    } 
    12161212 
     
    12631259            item_unlink(it); 
    12641260            item_remove(it);      /* release our reference */ 
    1265             write_bin_response(c, NULL, 0); 
     1261            write_bin_response(c, NULL, 0, 0); 
    12661262        } else { 
    12671263            /* XXX:  This is really lame, but defer_delete returns a string */ 
    12681264            char *res=defer_delete(it, exptime); 
    12691265            if(res[0] == 'D') { 
    1270                 write_bin_response(c, NULL, 0); 
     1266                write_bin_response(c, NULL, 0, 0); 
    12711267            } else { 
    12721268                write_bin_error(c, ERR_OUT_OF_MEMORY, 0); 
     
    12901286        } 
    12911287        if(settings.verbose) { 
    1292             fprintf(stderr, "Read binary protocol data:  %08x %08x %08x\n", 
    1293                 c->bin_header[0], c->bin_header[1], c->bin_header[2]); 
     1288            fprintf(stderr, "Read binary protocol data:  %08x %08x %08x %08x\n", 
     1289                c->bin_header[0], c->bin_header[1], c->bin_header[2], 
     1290                c->bin_header[3]); 
    12941291        } 
    12951292        if((c->bin_header[0] >> 24) != BIN_REQ_MAGIC) { 
     
    13101307     
    13111308        c->cmd = (c->bin_header[0] >> 16) & 0xff; 
    1312         c->keylen = (c->bin_header[0] >> 8) & 0xff; 
    1313         c->opaque = c->bin_header[1]; 
     1309        c->keylen = c->bin_header[0] & 0xffff; 
     1310        c->opaque = c->bin_header[3]; 
    13141311        if(settings.verbose > 1) { 
    13151312            fprintf(stderr, 
     
    13211318        switch(c->substate) { 
    13221319            case bin_reading_set_header: 
    1323                 process_bin_update(c, false); 
    1324                 break; 
    1325             case bin_reading_cas_header: 
    1326                 process_bin_update(c, true); 
     1320                process_bin_update(c); 
    13271321                break; 
    13281322            case bin_read_set_value: 
     
    13991393          if(settings.verbose > 1) { 
    14001394            fprintf(stderr, "CAS:  failure: expected %llu, got %llu\n", 
    1401                                old_it->cas_id, it->cas_id); 
     1395                old_it->cas_id, it->cas_id); 
    14021396          } 
    14031397          stored = 2; 
  • branches/binary/server/memcached.h

    r674 r686  
    4040 
    4141/* Binary protocol stuff */ 
    42 #define MIN_BIN_PKT_LENGTH 12 
    43 /* flags:32, expiration:32 */ 
    44 #define BIN_SET_HDR_LEN 8 
    45 /* Same as set, but with another 64 bits for the CAS identifier */ 
    46 #define BIN_CAS_HDR_LEN (BIN_SET_HDR_LEN + 8) 
     42#define MIN_BIN_PKT_LENGTH 16 
     43/* flags:32, expiration:32, cas:64 */ 
     44#define BIN_SET_HDR_LEN 16 
    4745/* incr:64, initial:64, expiration:32 */ 
    4846#define BIN_INCR_HDR_LEN 20 
     47/* flags:32, cas:64 */ 
     48#define GET_RES_HDR_LEN (4+8) 
    4949/* timeout:32 */ 
    5050#define BIN_DEL_HDR_LEN 4 
    5151#define BIN_PKT_HDR_WORDS (MIN_BIN_PKT_LENGTH/sizeof(uint32_t)) 
    5252 
    53 #define BIN_REQ_MAGIC 0x0f 
    54 #define BIN_RES_MAGIC 0xf
     53#define BIN_REQ_MAGIC 0x80 
     54#define BIN_RES_MAGIC 0x8
    5555 
    5656#define CMD_GET 0 
     
    6060#define CMD_DELETE 4 
    6161#define CMD_INCR 5 
    62 #define CMD_QUIT 6 
    63 #define CMD_FLUSH 7 
    64 #define CMD_GETQ 8 
    65 #define CMD_NOOP 9 
    66 #define CMD_VERSION 10 
    67  
    68 #define CMD_GETS 50 
    69 #define CMD_CAS 51 
     62#define CMD_DECR 6 
     63#define CMD_QUIT 7 
     64#define CMD_FLUSH 8 
     65#define CMD_GETQ 9 
     66#define CMD_NOOP 10 
     67#define CMD_VERSION 11 
    7068 
    7169#define ERR_UNKNOWN_CMD 0x81