optimize datatuple in-memory layout

git-svn-id: svn+ssh://svn.corp.yahoo.com/yahoo/yrl/labs/pnuts/code/logstore@1590 8dad8b1f-cf64-0410-95b6-bcf113ffbcfe
This commit is contained in:
sears 2011-01-11 22:08:10 +00:00
parent 975410845f
commit f4936551bc
2 changed files with 26 additions and 23 deletions

View file

@ -17,8 +17,7 @@ public:
typedef unsigned char* data_t ;
private:
len_t datalen_;
byte* key_;
byte* data_; // aliases key. data_ - 1 should be the \0 terminating key_.
byte* data_; // aliases key(). data_ - 1 should be the \0 terminating key().
datatuple* sanity_check() {
assert(keylen() < 3000);
@ -27,7 +26,7 @@ private:
public:
inline len_t keylen() const {
return data_ - key_;
return data_ - key();
}
inline len_t datalen() const {
return (datalen_ == DELETE) ? 0 : datalen_;
@ -42,7 +41,7 @@ public:
}
inline key_t key() const {
return key_;
return (key_t)(this+1);
}
inline data_t data() const {
return data_;
@ -110,10 +109,9 @@ public:
return create(key, keylen, 0, DELETE);
}
static datatuple* create(const void* key, len_t keylen, const void* data, len_t datalen) {
datatuple *ret = (datatuple*)malloc(sizeof(datatuple));
ret->key_ = (byte*)malloc(length_from_header(keylen, datalen));
memcpy(ret->key_, key, keylen);
ret->data_ = ret->key_ + keylen; // need to set this even if delete, since it encodes the key length.
datatuple *ret = (datatuple*)malloc(sizeof(datatuple) + length_from_header(keylen,datalen));
memcpy(ret->key(), key, keylen);
ret->data_ = ret->key() + keylen; // need to set this even if delete, since it encodes the key length.
if(datalen != DELETE) {
memcpy(ret->data_, data, datalen);
}
@ -126,38 +124,36 @@ public:
byte *ret = (byte*)malloc(byte_length());
((len_t*)ret)[0] = keylen();
((len_t*)ret)[1] = datalen_;
memcpy(((len_t*)ret)+2, key_, length_from_header(keylen(), datalen_));
memcpy(((len_t*)ret)+2, key(), length_from_header(keylen(), datalen_));
return ret;
}
const byte* get_bytes(len_t *keylen, len_t *datalen) const {
*keylen = this->keylen();
*datalen = datalen_;
return key_;
return key();
}
//format of buf: key _ data. The caller needs to 'peel' off key length and data length for this call.
static datatuple* from_bytes(len_t keylen, len_t datalen, byte* buf) {
datatuple *dt = (datatuple*) malloc(sizeof(datatuple));
datatuple *dt = (datatuple*) malloc(sizeof(datatuple) + length_from_header(keylen,datalen));
dt->datalen_ = datalen;
dt->key_ = buf;
dt->data_ = dt->key_ + keylen;
memcpy(dt->key(),buf, length_from_header(keylen,datalen));
dt->data_ = dt->key() + keylen;
return dt->sanity_check();
}
static datatuple* from_bytes(byte* buf) {
datatuple *dt = (datatuple*) malloc(sizeof(datatuple));
len_t keylen = ((len_t*)buf)[0];
len_t buflen = length_from_header(keylen, ((len_t*)buf)[1]);
datatuple *dt = (datatuple*) malloc(sizeof(datatuple) + buflen);
dt->datalen_ = ((len_t*)buf)[1];
len_t buflen = length_from_header(keylen, dt->datalen_);
dt->key_ = (byte*)malloc(buflen);
memcpy(dt->key_,((len_t*)buf)+2,buflen);
dt->data_ = dt->key_ + keylen;
memcpy(dt->key(),((len_t*)buf)+2,buflen);
dt->data_ = dt->key() + keylen;
return dt->sanity_check();
}
static inline void freetuple(datatuple* dt) {
free(dt->key_);
free(dt);
}

View file

@ -264,7 +264,9 @@ static inline datatuple* readtuplefromsocket(FILE * sockf, int * err) {
if(( *err = readfromsocket(sockf, bytes, buflen) )) { free(bytes); return NULL; }
return datatuple::from_bytes(keylen, datalen, bytes); // from_bytes consumes the buffer.
datatuple * ret = datatuple::from_bytes(keylen, datalen, bytes);
free(bytes);
return ret;
}
/**
@ -281,11 +283,16 @@ static inline datatuple* readtuplefromsocket(int sockd, int * err) {
if(( *err = readfromsocket(sockd, &datalen, sizeof(datalen)) )) return NULL;
buflen = datatuple::length_from_header(keylen, datalen);
// TODO remove the malloc / free in readtuplefromsocket, either with a
// two-stage API for datatuple::create, or with realloc.
byte* bytes = (byte*) malloc(buflen);
if(( *err = readfromsocket(sockd, bytes, buflen) )) return NULL;
return datatuple::from_bytes(keylen, datalen, bytes); // from_bytes consumes the buffer.
datatuple * ret = datatuple::from_bytes(keylen, datalen, bytes);
free(bytes);
return ret;
}
static inline int writeendofiteratortosocket(FILE * sockf) {