1 | /* |
2 | * stream.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 | * This file implements stream parsing for rows. |
24 | */ |
25 | |
26 | #include <assert.h> |
27 | #include <limits.h> |
28 | #include <stdio.h> |
29 | #include <stdlib.h> |
30 | #include <string.h> |
31 | #include <strings.h> |
32 | |
33 | #include "ai_obj.h" |
34 | #include "bt.h" |
35 | #include "stream.h" |
36 | |
37 | #include <citrusleaf/alloc.h> |
38 | |
39 | /* COMPARE COMPARE COMPARE COMPARE COMPARE COMPARE COMPARE COMPARE */ |
40 | int u160Cmp(void *s1, void *s2) { |
41 | char *p1 = (char *)s1; |
42 | char *p2 = (char *)s2; |
43 | uint128 x1, x2; |
44 | memcpy(&x1, p1 + 4, 16); |
45 | memcpy(&x2, p2 + 4, 16); |
46 | if (x1 == x2) { |
47 | uint32 u1; |
48 | memcpy(&u1, p1, 4); |
49 | uint32 u2; |
50 | memcpy(&u2, p2, 4); |
51 | return u1 == u2 ? 0 : (u1 > u2) ? 1 : -1; |
52 | } else return (x1 > x2) ? 1 : -1; |
53 | } |
54 | |
55 | static inline int LCmp(void *s1, void *s2) { |
56 | llk *ll1 = (llk *)s1; |
57 | llk *ll2 = (llk *)s2; |
58 | long l1 = ll1->key; |
59 | long l2 = ll2->key; |
60 | return l1 == l2 ? 0 : (l1 > l2) ? 1 : -1; |
61 | } |
62 | |
63 | int llCmp(void *s1, void *s2) { |
64 | return LCmp(s1, s2); |
65 | } |
66 | |
67 | static inline int YCmp(void *s1, void *s2) { |
68 | ylk *yl1 = (ylk *)s1; |
69 | ylk *yl2 = (ylk *)s2; |
70 | uint160 y1 = yl1->key; |
71 | uint160 y2 = yl2->key; |
72 | return u160Cmp(&y1, &y2); |
73 | } |
74 | int ylCmp(void *s1, void *s2) { |
75 | return YCmp(s1, s2); |
76 | } |
77 | |
78 | void destroyBTKey(char *btkey, bool med) { |
79 | if (med) cf_free(btkey); |
80 | } |
81 | |
82 | char *createBTKey(ai_obj *akey, bool *med, uint32 *ksize, bt *btr, btk_t *btk) { |
83 | *med = 0; |
84 | *ksize = VOIDSIZE; |
85 | |
86 | if (NBT_DG(btr)) { |
87 | return (char *)&akey->y; |
88 | } else if (LL(btr)) { |
89 | btk->LL.key = akey->l; |
90 | return (char *)&btk->LL; |
91 | } else if (YL(btr)) { |
92 | btk->YL.key = akey->y; |
93 | return (char *)&btk->YL; |
94 | } |
95 | |
96 | assert(! "Unsupport Btree type" ); |
97 | return NULL; |
98 | } |
99 | |
100 | uchar *parseStream(uchar *stream, bt *btr) { |
101 | if (!stream || NBT_DG(btr)) { |
102 | return NULL; |
103 | } else if (LL(btr)) { |
104 | return (uchar *)(*(llk *)(stream)).val; |
105 | } else if (YL(btr)) { |
106 | return (uchar *)(long)(*(ylk *)(stream)).val; |
107 | } |
108 | assert(! "Unsupported Btree type" ); |
109 | return NULL; |
110 | } |
111 | |
112 | void convertStream2Key(uchar *stream, ai_obj *key, bt *btr) { |
113 | init_ai_obj(key); |
114 | if (NBT_DG(btr)) { |
115 | key->type = COL_TYPE_DIGEST; |
116 | memcpy(&key->y, stream, AS_DIGEST_KEY_SZ); |
117 | } else if (LL(btr)) { |
118 | key->type = COL_TYPE_LONG; |
119 | key->l = ((llk *)stream)->key; |
120 | } else if (YL(btr)) { |
121 | key->type = COL_TYPE_DIGEST; |
122 | key->y = ((ylk *)stream)->key; |
123 | } else { |
124 | assert(! "Unsupported Btree type" ); |
125 | } |
126 | } |
127 | |
128 | static void *OBT_createStream(bt *btr, void *val, char *btkey, crs_t *crs) { |
129 | |
130 | if (LL(btr)) { |
131 | llk *ll = (llk *)btkey; |
132 | crs->LL_StreamPtr.key = ll->key; |
133 | crs->LL_StreamPtr.val = (ulong) val; |
134 | return &crs->LL_StreamPtr; |
135 | } else if (YL(btr)) { |
136 | ylk *yl = (ylk *)btkey; |
137 | crs->YL_StreamPtr.key = yl->key; |
138 | crs->YL_StreamPtr.val = (ulong) val; |
139 | return &crs->YL_StreamPtr; |
140 | } |
141 | |
142 | assert(! "OBT_createStream ERROR" ); |
143 | return NULL; |
144 | } |
145 | |
146 | void *createStream(bt *btr, void *val, char *btkey, uint32 klen, uint32 *size, |
147 | crs_t *crs) { |
148 | *size = 0; |
149 | if (NBT(btr)) { |
150 | return btkey; |
151 | } else if (OTHER_BT(btr)) { |
152 | return OBT_createStream(btr, val, btkey, crs); |
153 | } |
154 | |
155 | assert(! "Unsupported Btree type" ); |
156 | return NULL; |
157 | } |
158 | |
159 | bool destroyStream(bt *btr, uchar *ostream) { |
160 | if (!ostream || NBT(btr) || OTHER_BT(btr)) { |
161 | return 0; |
162 | } |
163 | |
164 | assert(! "Unsupported Btree Type" ); |
165 | return 1; |
166 | } |
167 | |