1/*
2 * bt.c
3 *
4 * Copyright (C) 2012-2014 Aerospike, Inc.
5 *
6 * Portions may be licensed to Aerospike, Inc. under one or more contributor
7 * license agreements.
8 *
9 * This program is free software: you can redistribute it and/or modify it under
10 * the terms of the GNU Affero General Public License as published by the Free
11 * Software Foundation, either version 3 of the License, or (at your option) any
12 * later version.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see http://www.gnu.org/licenses/
21 */
22/*
23 * Creation of different btree types and
24 * Public B-tree operations w/ stream abstractions under the covers.
25 */
26
27#include <assert.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <strings.h>
32
33#include "bt.h"
34#include "bt_iterator.h"
35#include "stream.h"
36
37#include <citrusleaf/alloc.h>
38
39bt *createIBT(col_type_t ktype, int imatch) {
40 bt_cmp_t cmp;
41 bts_t bts;
42 bts.ktype = ktype;
43 bts.btype = INDEX_BTREE;
44 bts.num = imatch;
45 if (C_IS_L(ktype)) { /* NOTE: under the covers: LL */
46 bts.ksize = LL_SIZE;
47 cmp = llCmp;
48 bts.bflag = BTFLAG_ULONG_ULONG;
49 } else if (C_IS_G(ktype)) { /* NOTE: under the covers: LL */
50 bts.ksize = LL_SIZE;
51 cmp = llCmp;
52 bts.bflag = BTFLAG_ULONG_ULONG;
53 } else if (C_IS_DG(ktype)) { /* NOTE: under the covers: YL */
54 bts.ksize = YL_SIZE;
55 cmp = ylCmp;
56 bts.bflag = BTFLAG_U160_ULONG;
57 } else { /* STRING or FLOAT */
58 assert(!"Unsupport Key Type");
59 }
60
61 return bt_create(cmp, &bts, 0);
62}
63
64bt *createNBT(col_type_t ktype) {
65 bt_cmp_t cmp;
66 bts_t bts;
67 bts.ktype = ktype;
68 bts.btype = NODE_BTREE;
69 bts.num = -1;
70 if (C_IS_DG(ktype)) {
71 cmp = u160Cmp;
72 bts.ksize = U160SIZE;
73 bts.bflag = BTFLAG_U160;
74 } else {
75 assert(!"Unsupport Key Type");
76 }
77
78 return bt_create(cmp, &bts, 0);
79}
80
81static void *abt_find(bt *btr, ai_obj *akey) {
82 DECLARE_BT_KEY(akey, 0)
83 uchar *stream = bt_find(btr, btkey, akey);
84 destroyBTKey(btkey, med); /* FREED 026 */
85 return parseStream(stream, btr);
86}
87static bool abt_exist(bt *btr, ai_obj *akey) { //NOTE: Evicted Indexes are NULL
88 DECLARE_BT_KEY(akey, 0)
89 bool ret = bt_exist(btr, btkey, akey);
90 destroyBTKey(btkey, med); /* FREED 026 */
91 return ret;
92}
93static bool abt_del(bt *btr, ai_obj *akey, bool leafd) { // DELETE the row
94 DECLARE_BT_KEY(akey, 0)
95 dwd_t dwd = bt_delete(btr, btkey, leafd); /* FREED 028 */
96 if (!dwd.k) return 0;
97 uchar *stream = dwd.k;
98 destroyBTKey(btkey, med); /* FREED 026 */
99 return destroyStream(btr, stream); /* DESTROYED 027 */
100}
101static uint32 abt_insert(bt *btr, ai_obj *akey, void *val) {
102 crs_t crs;
103 uint32 ssize;
104 DECLARE_BT_KEY(akey, 0)
105 char *stream = createStream(btr, val, btkey, ksize, &ssize, &crs); // D 027
106 if (!stream) return 0;
107 destroyBTKey(btkey, med); /* FREED 026 */
108 if (!bt_insert(btr, stream, 0)) return 0; /* FREE ME 028 */
109 return 1;
110}
111
112/* INDEX INDEX INDEX INDEX INDEX INDEX INDEX INDEX INDEX INDEX INDEX INDEX */
113void btIndAdd (bt *ibtr, ai_obj *ikey, bt *nbtr) {
114 abt_insert (ibtr, ikey, nbtr);
115}
116bt *btIndFind (bt *ibtr, ai_obj *ikey) {
117 return abt_find (ibtr, ikey);
118}
119int btIndDelete(bt *ibtr, ai_obj *ikey) {
120 abt_del (ibtr, ikey, 0);
121 return ibtr->numkeys;
122}
123
124bool btIndNodeExist(bt *nbtr, ai_obj *apk) {
125 return abt_exist(nbtr, apk);
126}
127bool btIndNodeAdd(bt *nbtr, ai_obj *apk) { //DEBUG_NBT_ADD
128 return abt_insert(nbtr, apk, NULL);
129}
130int btIndNodeDelete(bt *nbtr, ai_obj *apk, ai_obj *ocol) {
131 abt_del (nbtr, ocol ? ocol : apk, 0);
132 return nbtr->numkeys;
133}
134