Skip to content

Commit

Permalink
New Blob type for storing data values.
Browse files Browse the repository at this point in the history
Change-Id: If2ae62073f94c4b661037c8ab5cf729e697c8b30
Reviewed-on: http://review.northscale.com/770
Tested-by: Dustin Sallings <dustin@spy.net>
Reviewed-by: Sean Lynch <seanl@literati.org>
  • Loading branch information
dustin committed Jun 25, 2010
1 parent 05d7922 commit 897e542
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 28 deletions.
11 changes: 6 additions & 5 deletions ep_engine.h
Expand Up @@ -937,12 +937,13 @@ friend class LookupCallback;
// possible.

std::string k(static_cast<const char *>(key), nkey);
shared_ptr<std::string> s(new std::string);
s->reserve(ndata+2);
s->append(static_cast<const char*>(data), ndata);
s->append("\r\n");
std::string v;
v.reserve(ndata+2);
v.append(static_cast<const char*>(data), ndata);
v.append("\r\n");
shared_ptr<const Blob> vblob(Blob::New(v));

Item *item = new Item(k, flags, exptime, s);
Item *item = new Item(k, flags, exptime, vblob);

/* @TODO we don't have CAS now.. we might in the future.. */
(void)cas;
Expand Down
6 changes: 5 additions & 1 deletion ep_testsuite.c
Expand Up @@ -139,7 +139,11 @@ static enum test_result check_key_value(ENGINE_HANDLE *h, ENGINE_HANDLE_V1 *h1,
check(h1->get_item_info(h, i, &info), "check_key_value");

assert(info.nvalue == 1);
check(vlen == info.value[0].iov_len, "Length mismatch.");
if (vlen != info.value[0].iov_len) {
fprintf(stderr, "Expected length of %zd, got %zd\n",
vlen, info.value[0].iov_len);
abort();
}

check(memcmp(info.value[0].iov_base, val, vlen) == 0, "Data mismatch");

Expand Down
92 changes: 71 additions & 21 deletions item.hh
Expand Up @@ -12,7 +12,65 @@
#include "locks.hh"
#include "atomic.hh"

typedef shared_ptr<const std::string> value_t;
class Blob {
public:

// Constructors.

static Blob* New(const char *start, const size_t len) {
size_t total_len = len + sizeof(Blob);
Blob *t = new (::operator new(total_len)) Blob(start, len);
assert(t->length() == len);
return t;
}

static Blob* New(const std::string& s) {
return New(s.data(), s.length());
}

static Blob* New(const size_t len, const char c) {
size_t total_len = len + sizeof(Blob);
Blob *t = new (::operator new(total_len)) Blob(c, len);
assert(t->length() == len);
return t;
}

// Actual accessorish things.

const char* getData() const {
return data;
}

size_t length() const {
return size;
}

const std::string to_s() const {
return std::string(data, size);
}

// This is necessary for making C++ happy when I'm doing a
// placement new on fairly "normal" c++ heap allocations, just
// with variable-sized objects.
void operator delete(void* p) { ::operator delete(p); }

private:

explicit Blob(const char *start, const size_t len) : size(static_cast<uint32_t>(len)) {
std::memcpy(data, start, len);
}

explicit Blob(const char c, const size_t len) : size(static_cast<uint32_t>(len)) {
std::memset(data, c, len);
}

const uint32_t size;
char data[1];

DISALLOW_COPY_AND_ASSIGN(Blob);
};

typedef shared_ptr<const Blob> value_t;

/**
* The Item structure we use to pass information between the memcached
Expand Down Expand Up @@ -60,7 +118,7 @@ public:
~Item() {}

const char *getData() const {
return value->c_str();
return value->getData();
}

value_t getValue() const {
Expand Down Expand Up @@ -110,14 +168,10 @@ public:
* @return true if success
*/
bool append(const Item &item) {
std::string *newValue = new std::string(*value, 0, value->length() - 2);
if (newValue != NULL) {
newValue->append(*item.getValue());
value.reset(newValue);
return true;
} else {
return false;
}
std::string newValue(value->getData(), 0, value->length() - 2);
newValue.append(item.getValue()->to_s());
value.reset(Blob::New(newValue));
return true;
}

/**
Expand All @@ -127,14 +181,10 @@ public:
* @return true if success
*/
bool prepend(const Item &item) {
std::string *newValue = new std::string(*item.getValue(), 0, item.getNBytes() - 2);
if (newValue != NULL) {
newValue->append(*value);
value.reset(newValue);
return true;
} else {
return false;
}
std::string newValue(item.getValue()->to_s(), 0, item.getNBytes() - 2);
newValue.append(value->to_s());
value.reset(Blob::New(newValue));
return true;
}

private:
Expand All @@ -143,11 +193,11 @@ private:
* make it private.
*/
void setData(const char *dta, const size_t nb) {
std::string *data;
Blob *data;
if (dta == NULL) {
data = new std::string(nb, '\0');
data = Blob::New(nb, '\0');
} else {
data = new std::string(dta, nb);
data = Blob::New(dta, nb);
}

assert(data);
Expand Down
1 change: 1 addition & 0 deletions sizes.cc
Expand Up @@ -16,6 +16,7 @@ int main(int argc, char **argv) {
display("Stored Value", sizeof(StoredValue));
display("Featured Stored Value", sizeof(FeaturedStoredValue));
display("Stored Value Factory", sizeof(StoredValueFactory));
display("Blob", sizeof(Blob));
display("HashTable", sizeof(HashTable));
display("Item", sizeof(Item));
display("QueuedItem", sizeof(QueuedItem));
Expand Down
2 changes: 1 addition & 1 deletion t/hash_table_test.cc
Expand Up @@ -25,7 +25,7 @@ class Counter : public HashTableVisitor {
count += 1;
std::string key = v->getKey();
value_t val = v->getValue();
assert(key.compare(*val) == 0);
assert(key.compare(val->to_s()) == 0);
}
};

Expand Down

0 comments on commit 897e542

Please sign in to comment.