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 */
40int 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
55static 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
63int llCmp(void *s1, void *s2) {
64 return LCmp(s1, s2);
65}
66
67static 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}
74int ylCmp(void *s1, void *s2) {
75 return YCmp(s1, s2);
76}
77
78void destroyBTKey(char *btkey, bool med) {
79 if (med) cf_free(btkey);
80}
81
82char *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
100uchar *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
112void 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
128static 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
146void *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
159bool 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