xref: /6.0.3/couchstore/src/node_types.cc (revision e0680f06)
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
12#include <platform/cb_malloc.h>
13#include <stdlib.h>
14
15size_t read_kv(const void *buf, sized_buf *key, sized_buf *value)
16{
17    const raw_kv_length* kvlen = static_cast<const raw_kv_length*>(buf);
18    uint32_t klen, vlen;
19    decode_kv_length(kvlen, &klen, &vlen);
20    key->size = klen;
21    key->buf = (char*)(kvlen + 1);
22    value->size = vlen;
23    value->buf = key->buf + klen;
24    return sizeof(raw_kv_length) + klen + vlen;
25}
26
27void* write_kv(void *buf, sized_buf key, sized_buf value)
28{
29    uint8_t *dst = static_cast<uint8_t*>(buf);
30    *(raw_kv_length*)dst = encode_kv_length((uint32_t)key.size, (uint32_t)value.size);
31    dst += sizeof(raw_kv_length);
32    memcpy(dst, key.buf, key.size);
33    dst += key.size;
34    memcpy(dst, value.buf, value.size);
35    dst += value.size;
36    return dst;
37}
38
39node_pointer *read_root(void *buf, int size)
40{
41    if (size == 0) {
42        return NULL;
43    }
44
45    raw_btree_root *raw = (raw_btree_root*)buf;
46    node_pointer *ptr;
47    uint64_t position = decode_raw48(raw->pointer);
48    uint64_t subtreesize = decode_raw48(raw->subtreesize);
49    int redsize = size - sizeof(*raw);
50
51    ptr = (node_pointer *) cb_malloc(sizeof(node_pointer) + redsize);
52    if (redsize > 0) {
53        buf = (char *) memcpy(ptr + 1, raw + 1, redsize);
54    } else {
55        buf = NULL;
56    }
57    ptr->key.buf = NULL;
58    ptr->key.size = 0;
59    ptr->pointer = position;
60    ptr->subtreesize = subtreesize;
61    ptr->reduce_value.buf = static_cast<char*>(buf);
62    ptr->reduce_value.size = redsize;
63    return ptr;
64}
65
66size_t encode_root(void *buf, node_pointer *node)
67{
68    if (!node) {
69        return 0;
70    }
71    if (buf) {
72        raw_btree_root *root = static_cast<raw_btree_root*>(buf);
73        encode_raw48(node->pointer, &root->pointer);
74        encode_raw48(node->subtreesize, &root->subtreesize);
75        if (node->reduce_value.size > 0) {
76            memcpy(root + 1, node->reduce_value.buf, node->reduce_value.size);
77        }
78    }
79    return sizeof(raw_btree_root) + node->reduce_value.size;
80}
81
82void decode_kv_length(const raw_kv_length *kv, uint32_t *klen, uint32_t *vlen)
83{
84    /* 12, 28 bit */
85    *klen = (uint16_t) ((kv->raw_kv[0] << 4) | ((kv->raw_kv[1] & 0xf0) >> 4));
86    memcpy(vlen, &kv->raw_kv[1], 4);
87    *vlen = ntohl(*vlen) & 0x0FFFFFFF;
88}
89
90raw_kv_length encode_kv_length(size_t klen, size_t vlen)
91{
92    raw_kv_length kv;
93    uint32_t len = htonl((uint32_t)vlen);
94    memcpy(&kv.raw_kv[1], &len, 4);
95    kv.raw_kv[0] = (uint8_t)(klen >> 4);    /* upper 8 bits of klen */
96    kv.raw_kv[1] |= (klen & 0xF) << 4;     /* lower 4 bits of klen in upper half of byte */
97    return kv;
98}
99
100uint64_t decode_sequence_key(const sized_buf *buf)
101{
102    const raw_by_seq_key *key = (const raw_by_seq_key*)buf->buf;
103    return decode_raw48(key->sequence);
104}
105