-
Notifications
You must be signed in to change notification settings - Fork 13
/
native_view.cc
363 lines (300 loc) · 10.5 KB
/
native_view.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
//
// native_view.cc
// CBForest
//
// Created by Jens Alfke on 9/17/15.
// Copyright © 2015 Couchbase. All rights reserved.
//
#include "com_couchbase_cbforest_View.h"
#include "native_glue.hh"
#include "c4View.h"
#include <algorithm>
#include <vector>
using namespace forestdb::jni;
#pragma mark - DATABASE:
static jfieldID kHandleField;
static inline C4View* getViewHandle(JNIEnv *env, jobject self) {
return (C4View*)env->GetLongField(self, kHandleField);
}
bool forestdb::jni::initView(JNIEnv *env) {
jclass viewClass = env->FindClass("com/couchbase/cbforest/View");
if (!viewClass)
return false;
kHandleField = env->GetFieldID(viewClass, "_handle", "J");
return (kHandleField != NULL);
}
//////// VIEWS:
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View__1open
(JNIEnv *env, jobject self, jlong dbHandle, jstring jpath,
jint flags, jint encryptionAlg, jbyteArray encryptionKey,
jstring jname, jstring jversion)
{
jstringSlice path(env, jpath), name(env, jname), version(env, jversion);
C4EncryptionKey key;
if (!getEncryptionKey(env, encryptionAlg, encryptionKey, &key))
return 0;
C4Error error;
C4View *view = c4view_open((C4Database*)dbHandle, path, name, version,
(C4DatabaseFlags)flags, &key, &error);
if (!view)
throwError(env, error);
return (jlong)view;
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_close
(JNIEnv *env, jobject self)
{
C4View* view = getViewHandle(env, self);
env->SetLongField(self, kHandleField, 0);
C4Error error;
if (!c4view_close(view, &error))
throwError(env, error);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_rekey
(JNIEnv *env, jobject self, jint encryptionAlg, jbyteArray encryptionKey){
C4EncryptionKey key;
if (!getEncryptionKey(env, encryptionAlg, encryptionKey, &key))
return;
auto view = getViewHandle(env, self);
if (view) {
C4Error error;
if(!c4view_rekey(view, &key, &error))
throwError(env, error);
}
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_eraseIndex
(JNIEnv *env, jobject self)
{
C4Error error;
if (!c4view_eraseIndex(getViewHandle(env, self), &error))
throwError(env, error);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_delete
(JNIEnv *env, jobject self)
{
C4View* view = getViewHandle(env, self);
env->SetLongField(self, kHandleField, 0);
C4Error error;
if (!c4view_delete(view, &error))
throwError(env, error);
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_getTotalRows
(JNIEnv *env, jobject self)
{
return c4view_getTotalRows(getViewHandle(env, self));
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_getLastSequenceIndexed
(JNIEnv *env, jobject self)
{
return c4view_getLastSequenceIndexed(getViewHandle(env, self));
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_getLastSequenceChangedAt
(JNIEnv *env, jobject self)
{
return c4view_getLastSequenceChangedAt(getViewHandle(env, self));
}
//////// INDEXING:
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_beginIndex
(JNIEnv *env, jobject self, jlong dbHandle, jlong viewHandle)
{
C4View* view = (C4View*)viewHandle;
C4Error error;
C4Indexer* indexer = c4indexer_begin((C4Database*)dbHandle, &view, 1, &error);
if (!indexer)
throwError(env, error);
return (jlong)indexer;
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_enumerateDocuments
(JNIEnv *env, jobject self, jlong indexerHandle){
C4Error error;
C4DocEnumerator* e = c4indexer_enumerateDocuments((C4Indexer*)indexerHandle, &error);
if(!e)
throwError(env, error);
return (jlong)e;
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_emit(JNIEnv *env, jobject self, jlong indexerHandle, jlong documentHandler, jlongArray jkeys, jobjectArray jvalues)
{
C4Indexer* indexer = (C4Indexer*)indexerHandle;
C4Document* doc = (C4Document*)documentHandler;
size_t count = env->GetArrayLength(jkeys);
jlong *keys = env->GetLongArrayElements(jkeys, NULL);
std::vector<C4Key*> c4keys(count);
std::vector<C4Slice> c4values(count);
std::vector<jbyteArraySlice> valueBufs;
for(int i = 0; i < count; i++) {
c4keys[i] = (C4Key*)keys[i];
jbyteArray jvalue = (jbyteArray) env->GetObjectArrayElement(jvalues, i);
if (jvalue) {
valueBufs.push_back(jbyteArraySlice(env, jvalue));
c4values[i] = valueBufs.back();
} else {
c4values[i] = kC4SliceNull;
}
}
C4Error error;
bool result = c4indexer_emit(indexer, doc, 0, (unsigned)count,
c4keys.data(), c4values.data(), &error);
for(int i = 0; i < count; i++)
c4key_free(c4keys[i]);
env->ReleaseLongArrayElements(jkeys, keys, JNI_ABORT);
if(!result)
throwError(env, error);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_endIndex
(JNIEnv *env, jobject self, jlong indexerHandle, jboolean commit)
{
C4Error error;
if(!c4indexer_end((C4Indexer *)indexerHandle, commit, &error))
throwError(env, error);
}
//////// QUERYING:
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_query__J
(JNIEnv *env, jclass clazz, jlong viewHandle)
{
C4Error error;
C4QueryEnumerator *e = c4view_query((C4View*)viewHandle, NULL, &error);
if (!e)
throwError(env, error);
return (jlong)e;
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_query__JJJZZZJJLjava_lang_String_2Ljava_lang_String_2
(JNIEnv *env, jclass clazz, jlong viewHandle,
jlong skip, jlong limit,
jboolean descending, jboolean inclusiveStart, jboolean inclusiveEnd,
jlong startKey, jlong endKey, jstring jstartKeyDocID, jstring jendKeyDocID)
{
jstringSlice startKeyDocID(env, jstartKeyDocID), endKeyDocID(env, jendKeyDocID);
C4QueryOptions options = {
(uint64_t)std::max((long long)skip, 0ll),
(uint64_t)std::max((long long)limit, 0ll),
(bool)descending,
(bool)inclusiveStart,
(bool)inclusiveEnd,
(C4Key*)startKey,
(C4Key*)endKey,
startKeyDocID,
endKeyDocID
};
C4Error error;
C4QueryEnumerator *e = c4view_query((C4View*)viewHandle, &options, &error);
if (!e)
throwError(env, error);
return (jlong)e;
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_query__JJJZZZ_3J
(JNIEnv *env, jclass clazz, jlong viewHandle,
jlong skip, jlong limit,
jboolean descending, jboolean inclusiveStart, jboolean inclusiveEnd,
jlongArray jkeys)
{
size_t keyCount = env->GetArrayLength(jkeys);
jboolean isCopy;
auto keys = env->GetLongArrayElements(jkeys, &isCopy);
std::vector<C4Key*> c4keys(keyCount);
for(int i = 0; i < keyCount; i++){
c4keys[i] = (C4Key *)keys[i];
}
C4QueryOptions options = {
(uint64_t)std::max((long long)skip, 0ll),
(uint64_t)std::max((long long)limit, 0ll),
(bool)descending,
(bool)inclusiveStart,
(bool)inclusiveEnd,
NULL,
NULL,
kC4SliceNull,
kC4SliceNull,
(const C4Key **)c4keys.data(),
keyCount
};
C4Error error;
C4QueryEnumerator *e = c4view_query((C4View*)viewHandle, &options, &error);
env->ReleaseLongArrayElements(jkeys, keys, JNI_ABORT);
if (!e)
throwError(env, error);
return (jlong)e;
}
#pragma mark - KEYS:
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_newKey
(JNIEnv *env, jclass clazz)
{
return (jlong)c4key_new();
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_freeKey
(JNIEnv *env, jclass clazz, jlong jkey)
{
c4key_free((C4Key*)jkey);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyAddNull
(JNIEnv *env, jclass clazz, jlong jkey)
{
c4key_addNull((C4Key*)jkey);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyAdd__JZ
(JNIEnv *env, jclass clazz, jlong jkey, jboolean b)
{
c4key_addBool((C4Key*)jkey, b);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyAdd__JD
(JNIEnv *env, jclass clazz, jlong jkey, jdouble d)
{
c4key_addNumber((C4Key*)jkey, d);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyAdd__JLjava_lang_String_2
(JNIEnv *env, jclass clazz, jlong jkey, jstring s)
{
jstringSlice str(env, s);
c4key_addString((C4Key*)jkey, str);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyBeginArray
(JNIEnv *env, jclass clazz, jlong jkey)
{
c4key_beginArray((C4Key*)jkey);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyEndArray
(JNIEnv *env, jclass clazz, jlong jkey)
{
c4key_endArray((C4Key*)jkey);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyBeginMap
(JNIEnv *env, jclass clazz, jlong jkey)
{
c4key_beginMap((C4Key*)jkey);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keyEndMap
(JNIEnv *env, jclass clazz, jlong jkey)
{
c4key_endMap((C4Key*)jkey);
}
JNIEXPORT jlong JNICALL Java_com_couchbase_cbforest_View_keyReader(JNIEnv *env, jclass clazz, jlong jkey)
{
return (jlong)c4key_newReader((C4Key*)jkey);
}
JNIEXPORT jstring JNICALL Java_com_couchbase_cbforest_View_keyToJSON(JNIEnv *env, jclass clazz, jlong jkey)
{
C4KeyReader reader = c4key_read((C4Key*)jkey);
C4SliceResult dump = c4key_toJSON(&reader);
jstring result = toJString(env, dump);
c4slice_free(dump);
return result;
}
JNIEXPORT jint JNICALL Java_com_couchbase_cbforest_View_keyPeek(JNIEnv *env, jclass clazz, jlong jreader){
return (jint)c4key_peek((C4KeyReader*)jreader);
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_keySkipToken(JNIEnv *env, jclass clazz, jlong jreader){
c4key_skipToken((C4KeyReader*)jreader);
}
JNIEXPORT jboolean JNICALL Java_com_couchbase_cbforest_View_keyReadBool(JNIEnv *env, jclass clazz, jlong jreader){
return (jboolean)c4key_readBool((C4KeyReader*)jreader);
}
JNIEXPORT jdouble JNICALL Java_com_couchbase_cbforest_View_keyReadNumber(JNIEnv *env, jclass clazz, jlong jreader){
return (jdouble)c4key_readNumber((C4KeyReader*)jreader);
}
JNIEXPORT jstring JNICALL Java_com_couchbase_cbforest_View_keyReadString(JNIEnv *env, jclass clazz, jlong jreader){
C4SliceResult dump = c4key_readString((C4KeyReader*)jreader);
jstring result = toJString(env, dump);
c4slice_free(dump);
return result;
}
JNIEXPORT void JNICALL Java_com_couchbase_cbforest_View_freeKeyReader(JNIEnv *env, jclass clazz, jlong jreader){
if(jreader != 0) c4key_freeReader((C4KeyReader*)jreader);
}