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