1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 //
3 // node_types.c
4 // couchstore
5 //
6 // Created by Jens Alfke on 4/25/12.
7 // Copyright (c) 2012 Couchbase, Inc. All rights reserved.
8 //
9
10 #include "node_types.h"
11 #include <stdlib.h>
12
read_kv(const void *buf, sized_buf *key, sized_buf *value)13 size_t read_kv(const void *buf, sized_buf *key, sized_buf *value)
14 {
15 const raw_kv_length* kvlen = static_cast<const raw_kv_length*>(buf);
16 uint32_t klen, vlen;
17 decode_kv_length(kvlen, &klen, &vlen);
18 key->size = klen;
19 key->buf = (char*)(kvlen + 1);
20 value->size = vlen;
21 value->buf = key->buf + klen;
22 return sizeof(raw_kv_length) + klen + vlen;
23 }
24
write_kv(void *buf, sized_buf key, sized_buf value)25 void* write_kv(void *buf, sized_buf key, sized_buf value)
26 {
27 uint8_t *dst = static_cast<uint8_t*>(buf);
28 *(raw_kv_length*)dst = encode_kv_length((uint32_t)key.size, (uint32_t)value.size);
29 dst += sizeof(raw_kv_length);
30 memcpy(dst, key.buf, key.size);
31 dst += key.size;
32 memcpy(dst, value.buf, value.size);
33 dst += value.size;
34 return dst;
35 }
36
read_root(void *buf, int size)37 node_pointer *read_root(void *buf, int size)
38 {
39 if (size == 0) {
40 return NULL;
41 }
42
43 raw_btree_root *raw = (raw_btree_root*)buf;
44 node_pointer *ptr;
45 uint64_t position = decode_raw48(raw->pointer);
46 uint64_t subtreesize = decode_raw48(raw->subtreesize);
47 int redsize = size - sizeof(*raw);
48
49 ptr = (node_pointer *) malloc(sizeof(node_pointer) + redsize);
50 if (redsize > 0) {
51 buf = (char *) memcpy(ptr + 1, raw + 1, redsize);
52 } else {
53 buf = NULL;
54 }
55 ptr->key.buf = NULL;
56 ptr->key.size = 0;
57 ptr->pointer = position;
58 ptr->subtreesize = subtreesize;
59 ptr->reduce_value.buf = static_cast<char*>(buf);
60 ptr->reduce_value.size = redsize;
61 return ptr;
62 }
63
encode_root(void *buf, node_pointer *node)64 size_t encode_root(void *buf, node_pointer *node)
65 {
66 if (!node) {
67 return 0;
68 }
69 if (buf) {
70 raw_btree_root *root = static_cast<raw_btree_root*>(buf);
71 encode_raw48(node->pointer, &root->pointer);
72 encode_raw48(node->subtreesize, &root->subtreesize);
73 memcpy(root + 1, node->reduce_value.buf, node->reduce_value.size);
74 }
75 return sizeof(raw_btree_root) + node->reduce_value.size;
76 }
77
decode_kv_length(const raw_kv_length *kv, uint32_t *klen, uint32_t *vlen)78 void decode_kv_length(const raw_kv_length *kv, uint32_t *klen, uint32_t *vlen)
79 {
80 /* 12, 28 bit */
81 *klen = (uint16_t) ((kv->raw_kv[0] << 4) | ((kv->raw_kv[1] & 0xf0) >> 4));
82 memcpy(vlen, &kv->raw_kv[1], 4);
83 *vlen = ntohl(*vlen) & 0x0FFFFFFF;
84 }
85
encode_kv_length(size_t klen, size_t vlen)86 raw_kv_length encode_kv_length(size_t klen, size_t vlen)
87 {
88 raw_kv_length kv;
89 uint32_t len = htonl((uint32_t)vlen);
90 memcpy(&kv.raw_kv[1], &len, 4);
91 kv.raw_kv[0] = (uint8_t)(klen >> 4); /* upper 8 bits of klen */
92 kv.raw_kv[1] |= (klen & 0xF) << 4; /* lower 4 bits of klen in upper half of byte */
93 return kv;
94 }
95
decode_sequence_key(const sized_buf *buf)96 uint64_t decode_sequence_key(const sized_buf *buf)
97 {
98 const raw_by_seq_key *key = (const raw_by_seq_key*)buf->buf;
99 return decode_raw48(key->sequence);
100 }
101