Permalink
Browse files

New Blob type for storing data values.

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...
1 parent 05d7922 commit 897e542ebe78eb8f487ef97e0a7a70c82c8f5640 @dustin dustin committed Jun 19, 2010
Showing with 84 additions and 28 deletions.
  1. +6 −5 ep_engine.h
  2. +5 −1 ep_testsuite.c
  3. +71 −21 item.hh
  4. +1 −0 sizes.cc
  5. +1 −1 t/hash_table_test.cc
View
@@ -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;
View
@@ -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");
View
92 item.hh
@@ -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
@@ -60,7 +118,7 @@ public:
~Item() {}
const char *getData() const {
- return value->c_str();
+ return value->getData();
}
value_t getValue() const {
@@ -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;
}
/**
@@ -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:
@@ -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);
View
@@ -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));
View
@@ -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);
}
};

0 comments on commit 897e542

Please sign in to comment.