Permalink
Browse files

lib: use 64 bit sizes and offsets

  • Loading branch information...
1 parent 1dab468 commit bb303bf90b7bac874c5bd81af4f6851e7e55a44e @indutny committed Jan 20, 2012
Showing with 127 additions and 75 deletions.
  1. +2 −1 Makefile
  2. +2 −2 include/bplus.h
  3. +9 −9 include/private/pages.h
  4. +4 −4 include/private/tree.h
  5. +5 −12 include/private/utils.h
  6. +7 −7 include/private/writer.h
  7. +12 −12 src/bplus.c
  8. +21 −18 src/pages.c
  9. +55 −0 src/utils.c
  10. +10 −10 src/writer.c
View
@@ -1,4 +1,4 @@
-CSTDFLAG = --std=c89 -pedantic -Wall -Wextra -Wno-unused-parameter
+CSTDFLAG = --std=c99 -pedantic -Wall -Wextra -Wno-unused-parameter
CFLAGS = -g
CPPFLAGS += -Iinclude -Ideps/snappy
CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
@@ -17,6 +17,7 @@ OBJS =
OBJS += deps/snappy/snappy-sinksource.o
OBJS += deps/snappy/snappy.o
OBJS += deps/snappy/snappy-c.o
+OBJS += src/utils.o
OBJS += src/writer.o
OBJS += src/pages.o
OBJS += src/bplus.o
View
@@ -9,15 +9,15 @@ extern "C" {
#define BP_USE_SNAPPY 0
#endif /* BP_USE_SNAPPY */
-#define BP_PADDING 32
+#define BP_PADDING 64
typedef struct bp_tree_s bp_tree_t;
typedef struct bp_key_s bp_key_t;
typedef struct bp_key_s bp_value_t;
typedef int (*bp_compare_cb)(const bp_key_t* a, const bp_key_t* b);
#define BP_KEY_FIELDS \
- uint32_t length;\
+ uint64_t length;\
char* value;
#include "private/tree.h"
View
@@ -7,7 +7,7 @@ extern "C" {
#include "private/tree.h"
-#define BP__KV_HEADER_SIZE 12
+#define BP__KV_HEADER_SIZE 24
#define BP__KV_SIZE(kv) BP__KV_HEADER_SIZE + kv.length
typedef struct bp__page_s bp__page_t;
@@ -21,8 +21,8 @@ enum page_type {
int bp__page_create(bp_tree_t* t,
const enum page_type type,
- const uint32_t offset,
- const uint32_t config,
+ const uint64_t offset,
+ const uint64_t config,
bp__page_t** page);
int bp__page_destroy(bp_tree_t* t, bp__page_t* page);
@@ -52,20 +52,20 @@ void bp__page_shiftl(bp_tree_t* t, bp__page_t* page, const uint32_t index);
struct bp__kv_s {
BP_KEY_FIELDS
- uint32_t offset;
- uint32_t config;
+ uint64_t offset;
+ uint64_t config;
uint8_t allocated;
};
struct bp__page_s {
enum page_type type;
- uint32_t length;
- uint32_t byte_size;
+ uint64_t length;
+ uint64_t byte_size;
- uint32_t offset;
- uint32_t config;
+ uint64_t offset;
+ uint64_t config;
void* buff_;
View
@@ -21,10 +21,10 @@ int bp__tree_write_head(bp__writer_t* w, void* data);
struct bp__tree_head_s {
- uint32_t offset;
- uint32_t config;
- uint32_t page_size;
- uint32_t hash;
+ uint64_t offset;
+ uint64_t config;
+ uint64_t page_size;
+ uint64_t hash;
};
#ifdef __cplusplus
View
@@ -5,18 +5,11 @@
extern "C" {
#endif
-/* Thomas Wang, Integer Hash Functions. */
-/* http://www.concentric.net/~Ttwang/tech/inthash.htm */
-uint32_t bp__compute_hash(uint32_t key) {
- uint32_t hash = key;
- hash = ~hash + (hash << 15); /* hash = (hash << 15) - hash - 1; */
- hash = hash ^ (hash >> 12);
- hash = hash + (hash << 2);
- hash = hash ^ (hash >> 4);
- hash = hash * 2057; /* hash = (hash + (hash << 3)) + (hash << 11); */
- hash = hash ^ (hash >> 16);
- return hash;
-}
+#include <stdint.h> /* uint64_t */
+
+uint64_t bp__compute_hashl(uint64_t key);
+uint64_t htonll(uint64_t value);
+uint64_t ntohll(uint64_t value);
#ifdef __cplusplus
} // extern "C"
View
@@ -10,7 +10,7 @@ extern "C" {
#define BP_WRITER_PRIVATE \
int fd;\
- uint32_t filesize;\
+ uint64_t filesize;\
char padding[BP_PADDING];
typedef struct bp__writer_s bp__writer_t;
@@ -26,19 +26,19 @@ int bp__writer_destroy(bp__writer_t* w);
int bp__writer_read(bp__writer_t* w,
const enum comp_type comp,
- const uint32_t offset,
- uint32_t* size,
+ const uint64_t offset,
+ uint64_t* size,
void** data);
int bp__writer_write(bp__writer_t* w,
const enum comp_type comp,
- const uint32_t size,
+ const uint64_t size,
const void* data,
- uint32_t* offset,
- uint32_t* csize);
+ uint64_t* offset,
+ uint64_t* csize);
int bp__writer_find(bp__writer_t* w,
const enum comp_type comp,
- const uint32_t size,
+ const uint64_t size,
void* data,
bp__writer_cb seek,
bp__writer_cb miss);
View
@@ -130,16 +130,16 @@ int bp__tree_read_head(bp__writer_t* w, void* data) {
bp_tree_t* t = (bp_tree_t*) w;
bp__tree_head_t* head = (bp__tree_head_t*) data;
- t->head.offset = ntohl(head->offset);
- t->head.config = ntohl(head->config);
- t->head.page_size = ntohl(head->page_size);
- t->head.hash = ntohl(head->hash);
+ t->head.offset = ntohll(head->offset);
+ t->head.config = ntohll(head->config);
+ t->head.page_size = ntohll(head->page_size);
+ t->head.hash = ntohll(head->hash);
/* we've copied all data - free it */
free(data);
/* Check hash first */
- if (bp__compute_hash(t->head.offset) != t->head.hash) return 1;
+ if (bp__compute_hashl(t->head.offset) != t->head.hash) return 1;
if (t->head_page == NULL) {
bp__page_create(t, 1, t->head.offset, t->head.config, &t->head_page);
@@ -152,8 +152,8 @@ int bp__tree_write_head(bp__writer_t* w, void* data) {
int ret;
bp_tree_t* t = (bp_tree_t*) w;
bp__tree_head_t nhead;
- uint32_t offset;
- uint32_t csize;
+ uint64_t offset;
+ uint64_t csize;
if (t->head_page == NULL) {
/* TODO: page size should be configurable */
@@ -168,13 +168,13 @@ int bp__tree_write_head(bp__writer_t* w, void* data) {
t->head.offset = t->head_page->offset;
t->head.config = t->head_page->config;
- t->head.hash = bp__compute_hash(t->head.offset);
+ t->head.hash = bp__compute_hashl(t->head.offset);
/* Create temporary head with fields in network byte order */
- nhead.offset = htonl(t->head.offset);
- nhead.config = htonl(t->head.config);
- nhead.page_size = htonl(t->head.page_size);
- nhead.hash = htonl(t->head.hash);
+ nhead.offset = htonll(t->head.offset);
+ nhead.config = htonll(t->head.config);
+ nhead.page_size = htonll(t->head.page_size);
+ nhead.hash = htonll(t->head.hash);
ret = bp__writer_write(w,
kNotCompressed,
View
@@ -3,12 +3,13 @@
#include "bplus.h"
#include "private/pages.h"
+#include "private/utils.h"
#include <stdio.h>
int bp__page_create(bp_tree_t* t,
const enum page_type type,
- const uint32_t offset,
- const uint32_t config,
+ const uint64_t offset,
+ const uint64_t config,
bp__page_t** page) {
/* Allocate space for page + keys */
bp__page_t* p = malloc(sizeof(*p) +
@@ -63,14 +64,15 @@ int bp__page_destroy(bp_tree_t* t, bp__page_t* page) {
int bp__page_load(bp_tree_t* t, bp__page_t* page) {
int ret;
- uint32_t size, i, o;
+ uint64_t size, o;
+ uint32_t i;
bp__writer_t* w = (bp__writer_t*) t;
char* buff;
/* Read page size and leaf flag */
- size = page->config & 0x7fffffff;
- page->type = page->config >> 31 == 1 ? kLeaf : kPage;
+ size = page->config >> 1;
+ page->type = page->config & 1 ? kLeaf : kPage;
/* Read page data */
ret = bp__writer_read(w, kCompressed, page->offset, &size, (void**) &buff);
@@ -80,10 +82,10 @@ int bp__page_load(bp_tree_t* t, bp__page_t* page) {
i = 0;
o = 0;
while (o < size) {
- page->keys[i].length = ntohl(*(uint32_t*) (buff + o));
- page->keys[i].offset = ntohl(*(uint32_t*) (buff + o + 4));
- page->keys[i].config = ntohl(*(uint32_t*) (buff + o + 8));
- page->keys[i].value = buff + o + 12;
+ page->keys[i].length = ntohll(*(uint64_t*) (buff + o));
+ page->keys[i].offset = ntohll(*(uint64_t*) (buff + o + 8));
+ page->keys[i].config = ntohll(*(uint64_t*) (buff + o + 16));
+ page->keys[i].value = buff + o + 24;
page->keys[i].allocated = 0;
o += BP__KV_SIZE(page->keys[i]);
@@ -104,7 +106,8 @@ int bp__page_load(bp_tree_t* t, bp__page_t* page) {
int bp__page_save(bp_tree_t* t, bp__page_t* page) {
int ret;
bp__writer_t* w = (bp__writer_t*) t;
- uint32_t i, o;
+ uint32_t i;
+ uint64_t o;
char* buff;
assert(page->type == kLeaf || page->length != 0);
@@ -117,11 +120,11 @@ int bp__page_save(bp_tree_t* t, bp__page_t* page) {
for (i = 0; i < page->length; i++) {
assert(o + BP__KV_SIZE(page->keys[i]) <= page->byte_size);
- *(uint32_t*) (buff + o) = htonl(page->keys[i].length);
- *(uint32_t*) (buff + o + 4) = htonl(page->keys[i].offset);
- *(uint32_t*) (buff + o + 8) = htonl(page->keys[i].config);
+ *(uint64_t*) (buff + o) = htonll(page->keys[i].length);
+ *(uint64_t*) (buff + o + 8) = htonll(page->keys[i].offset);
+ *(uint64_t*) (buff + o + 16) = htonll(page->keys[i].config);
- memcpy(buff + o + 12, page->keys[i].value, page->keys[i].length);
+ memcpy(buff + o + 24, page->keys[i].value, page->keys[i].length);
o += BP__KV_SIZE(page->keys[i]);
}
@@ -133,7 +136,7 @@ int bp__page_save(bp_tree_t* t, bp__page_t* page) {
buff,
&page->offset,
&page->config);
- if (page->type == kLeaf) page->config |= 0x80000000;
+ page->config = (page->config << 1) | (page->type == kLeaf);
free(buff);
if (ret) return ret;
@@ -258,7 +261,7 @@ int bp__page_insert(bp_tree_t* t, bp__page_t* page, const bp__kv_t* kv) {
if (page->length == t->head.page_size) {
if (page == t->head_page) {
/* split root */
- bp__page_t* new_root;
+ bp__page_t* new_root = NULL;
bp__page_create(t, 0, 0, 0, &new_root);
ret = bp__page_split(t, new_root, 0, page);
@@ -362,8 +365,8 @@ int bp__page_split(bp_tree_t* t,
bp__page_t* child) {
int ret;
uint32_t i, middle;
- bp__page_t* left;
- bp__page_t* right;
+ bp__page_t* left = NULL;
+ bp__page_t* right = NULL;
bp__kv_t middle_key;
bp__page_create(t, child->type, 0, 0, &left);
View
@@ -0,0 +1,55 @@
+#include "private/utils.h"
+
+#include <stdint.h> /* uint64_t */
+#include <arpa/inet.h> /* nothl, htonl */
+
+
+/* Thomas Wang, Integer Hash Functions. */
+/* http://www.concentric.net/~Ttwang/tech/inthash.htm */
+uint32_t bp__compute_hash(uint32_t key) {
+ uint32_t hash = key;
+ hash = ~hash + (hash << 15); /* hash = (hash << 15) - hash - 1; */
+ hash = hash ^ (hash >> 12);
+ hash = hash + (hash << 2);
+ hash = hash ^ (hash >> 4);
+ hash = hash * 2057; /* hash = (hash + (hash << 3)) + (hash << 11); */
+ hash = hash ^ (hash >> 16);
+ return hash;
+}
+
+
+uint64_t bp__compute_hashl(uint64_t key) {
+ uint32_t keyh = key >> 32;
+ uint32_t keyl = key & 0xffffffffLL;
+
+ return ((uint64_t) bp__compute_hash(keyh) << 32) |
+ bp__compute_hash(keyl);
+}
+
+
+uint64_t htonll(uint64_t value) {
+ static const int num = 23;
+
+ if (*(const char*)(&num) == num) {
+ uint32_t high_part = htonl((uint32_t) (value >> 32));
+ uint32_t low_part = htonl((uint32_t) (value & 0xffffffffLL));
+
+ return ((uint64_t) low_part << 32) | high_part;
+ } else {
+ return value;
+ }
+}
+
+
+uint64_t ntohll(uint64_t value) {
+ static const int num = 23;
+
+ if (*(const char*)(&num) == num) {
+ uint32_t high_part = ntohl((uint32_t) (value >> 32));
+ uint32_t low_part = ntohl((uint32_t) (value & 0xffffffffLL));
+
+ return ((uint64_t) low_part << 32) | high_part;
+ } else {
+ return value;
+ }
+}
Oops, something went wrong.

0 comments on commit bb303bf

Please sign in to comment.