mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'master' of https://github.com/triAGENS/AvocadoDB
Conflicts: SkipLists/skiplist.c SkipLists/sl-operator.c VocBase/index.c
This commit is contained in:
commit
a0306acaf0
|
@ -1,3 +1,7 @@
|
|||
* Prerequisites
|
||||
|
||||
1. Make sure you have bison (http://www.gnu.org/software/bison/) installed in your system.
|
||||
|
||||
* Compilation and Installation
|
||||
|
||||
1. Run make in the top directory.
|
||||
|
|
|
@ -49,11 +49,11 @@ IOSDEVCC := xcrun -sdk iphoneos llvm-gcc-4.2 -arch armv7 -isysroot "/Developer/P
|
|||
CC = gcc
|
||||
LL = gcc
|
||||
YACC = bison
|
||||
DEBUG_MODE = 0
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O2 -g
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL)
|
||||
|
|
|
@ -8,12 +8,19 @@
|
|||
#define MRUBYCONF_H
|
||||
|
||||
#include <stdint.h>
|
||||
#define MRB_USE_FLOAT
|
||||
|
||||
#ifdef MRB_USE_FLOAT
|
||||
typedef float mrb_float;
|
||||
#define readfloat(p) strtof((p),NULL)
|
||||
#else
|
||||
typedef double mrb_float;
|
||||
#define readfloat(p) strtod((p),NULL)
|
||||
#endif
|
||||
|
||||
typedef int32_t mrb_int;
|
||||
typedef intptr_t mrb_sym;
|
||||
|
||||
#define readint(p,base) strtol((p),NULL,(base))
|
||||
#define readfloat(p) strtod((p),NULL)
|
||||
|
||||
#undef INCLUDE_ENCODING /* not use encoding classes (ascii only) */
|
||||
#define INCLUDE_ENCODING /* use UTF-8 encoding classes */
|
||||
|
|
|
@ -349,6 +349,7 @@ mrb_state* mrb_open_allocf(mrb_allocf);
|
|||
void mrb_close(mrb_state*);
|
||||
int mrb_checkstack(mrb_state*,int);
|
||||
|
||||
mrb_value mrb_top_self(mrb_state *);
|
||||
mrb_value mrb_run(mrb_state*, struct RProc*, mrb_value);
|
||||
|
||||
mrb_value mrb_p(mrb_state*, mrb_value);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
|
||||
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
|
||||
|
||||
mrb_value mrb_dbl2big(mrb_state *mrb, float d);
|
||||
mrb_value mrb_flt2big(mrb_state *mrb, float d);
|
||||
void mrb_num_zerodiv(mrb_state *mrb);
|
||||
mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base);
|
||||
|
||||
|
|
|
@ -16,11 +16,11 @@ MRBS := $(MRB1)
|
|||
# C compiler (gcc)
|
||||
CC = gcc
|
||||
LL = gcc
|
||||
DEBUG_MODE = 0
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O2
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
INCLUDES = -I../src -I../include
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
|
|
|
@ -38,11 +38,11 @@ LL = gcc
|
|||
AR = ar
|
||||
YACC = bison
|
||||
|
||||
DEBUG_MODE = 0
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
CFLAGS = -g -O3
|
||||
else
|
||||
CFLAGS = -O2 -g
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL)
|
||||
|
|
|
@ -213,8 +213,10 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id
|
|||
if (!c) {
|
||||
struct RClass *s = 0;
|
||||
|
||||
mrb_check_type(mrb, super, MRB_TT_CLASS);
|
||||
if (!mrb_nil_p(super)) s = mrb_class_ptr(super);
|
||||
if (!mrb_nil_p(super)) {
|
||||
mrb_check_type(mrb, super, MRB_TT_CLASS);
|
||||
s = mrb_class_ptr(super);
|
||||
}
|
||||
c = mrb_class_new(mrb, s);
|
||||
setup_class(mrb, outer, c, id);
|
||||
}
|
||||
|
|
|
@ -686,17 +686,13 @@ mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
|
|||
mrb_get_args(mrb, "o", &arg);
|
||||
mrb_sym mid = mrb_to_id(mrb, arg);
|
||||
|
||||
//if (!mrb_is_instance_id(id)) {
|
||||
// mrb_name_error(id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id));
|
||||
//}
|
||||
//return mrb_ivar_defined(self, id);
|
||||
k = kh_get(iv, h, mid);
|
||||
if (k != kh_end(h)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
else {
|
||||
return mrb_false_value();
|
||||
if (h) {
|
||||
k = kh_get(iv, h, mid);
|
||||
if (k != kh_end(h)) {
|
||||
return mrb_true_value();
|
||||
}
|
||||
}
|
||||
return mrb_false_value();
|
||||
}
|
||||
|
||||
/* 15.3.1.3.21 */
|
||||
|
@ -795,16 +791,15 @@ mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
|
|||
const char* p;
|
||||
|
||||
ary = mrb_ary_new(mrb);
|
||||
//if (mrb_is_instance_id(key)) {
|
||||
// mrb_ary_push(mrb, ary, mrb_sym2name(mrb, key));
|
||||
//}
|
||||
for (i=0;i<kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
if (h) {
|
||||
for (i=0;i<kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
p = mrb_sym2name(mrb, kh_key(h,i));
|
||||
if (*p == '@') {
|
||||
if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
|
||||
mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ary;
|
||||
|
@ -922,6 +917,7 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary)
|
|||
int i;
|
||||
|
||||
khash_t(mt) *h = klass->mt;
|
||||
if (!h) return;
|
||||
for (i=0;i<kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(h,i)));
|
||||
|
@ -1244,6 +1240,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
|
|||
case MRB_TT_MODULE:
|
||||
if (!mrb_obj_ptr(self)->iv) break;
|
||||
h = mrb_obj_ptr(self)->iv;
|
||||
if (!h) break;
|
||||
k = kh_get(iv, h, sym);
|
||||
if (k != kh_end(h)) {
|
||||
val = kh_value(h, k);
|
||||
|
|
|
@ -101,29 +101,14 @@ const unsigned char mrb_nan[] = "\x00\x00\xc0\x7f";
|
|||
const unsigned char mrb_nan[] = "\x7f\xc0\x00\x00";
|
||||
#endif
|
||||
|
||||
extern double round(double);
|
||||
|
||||
#ifndef HAVE_ROUND
|
||||
double
|
||||
round(double x)
|
||||
{
|
||||
double f;
|
||||
|
||||
if (x > 0.0) {
|
||||
f = floor(x);
|
||||
x = f + (x - f >= 0.5);
|
||||
}
|
||||
else if (x < 0.0) {
|
||||
f = ceil(x);
|
||||
x = f - (f - x >= 0.5);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
#ifdef MRB_USE_FLOAT
|
||||
#define round(f) roundf(f)
|
||||
#define floor(f) floorf(f)
|
||||
#define ceil(f) ceilf(f)
|
||||
#define floor(f) floorf(f)
|
||||
#define fmod(x,y) fmodf(x,y)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void mrb_cmperr(mrb_state *mrb, mrb_value x, mrb_value y);
|
||||
|
||||
void
|
||||
|
@ -274,7 +259,7 @@ num_quo(mrb_state *mrb, mrb_value x)
|
|||
mrb_value y;
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
return mrb_funcall(mrb, mrb_float_value((double)mrb_fixnum(x)), "/", 1, y);
|
||||
return mrb_funcall(mrb, mrb_float_value((mrb_float)mrb_fixnum(x)), "/", 1, y);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -308,7 +293,7 @@ num_abs(mrb_state *mrb, mrb_value num)
|
|||
*/
|
||||
|
||||
mrb_value
|
||||
mrb_float_new(double d)
|
||||
mrb_float_new(mrb_float d)
|
||||
{
|
||||
//NEWOBJ(flt, struct RFloat);
|
||||
//OBJSETUP(flt, mrb_cFloat, MRB_TT_FLOAT);
|
||||
|
@ -333,7 +318,7 @@ static mrb_value
|
|||
flo_to_s(mrb_state *mrb, mrb_value flt)
|
||||
{
|
||||
char buf[32];
|
||||
double value = mrb_float(flt);
|
||||
mrb_float value = mrb_float(flt);
|
||||
char *p, *e;
|
||||
|
||||
if (isinf(value))
|
||||
|
@ -376,7 +361,7 @@ flo_minus(mrb_state *mrb, mrb_value x)
|
|||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb_float_value(mrb_float(x) - (double)mrb_fixnum(y));
|
||||
return mrb_float_value(mrb_float(x) - (mrb_float)mrb_fixnum(y));
|
||||
case MRB_TT_FLOAT:
|
||||
return mrb_float_value(mrb_float(x) - mrb_float(y));
|
||||
default:
|
||||
|
@ -402,7 +387,7 @@ flo_mul(mrb_state *mrb, mrb_value x)
|
|||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
return mrb_float_value(mrb_float(x) * (double)mrb_fixnum(y));
|
||||
return mrb_float_value(mrb_float(x) * (mrb_float)mrb_fixnum(y));
|
||||
case MRB_TT_FLOAT:
|
||||
return mrb_float_value(mrb_float(x) * mrb_float(y));
|
||||
default:
|
||||
|
@ -424,14 +409,13 @@ flo_div(mrb_state *mrb, mrb_value x)
|
|||
{
|
||||
mrb_value y;
|
||||
long f_y;
|
||||
//double d;
|
||||
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
f_y = mrb_fixnum(y);
|
||||
return mrb_float_value(mrb_float(x) / (double)f_y);
|
||||
return mrb_float_value(mrb_float(x) / (mrb_float)f_y);
|
||||
case MRB_TT_FLOAT:
|
||||
return mrb_float_value(mrb_float(x) / mrb_float(y));
|
||||
default:
|
||||
|
@ -455,21 +439,12 @@ flo_quo(mrb_state *mrb, mrb_value x)
|
|||
}
|
||||
|
||||
static void
|
||||
flodivmod(mrb_state *mrb, double x, double y, double *divp, double *modp)
|
||||
flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float *modp)
|
||||
{
|
||||
double div, mod;
|
||||
mrb_float div, mod;
|
||||
|
||||
if (y == 0.0) mrb_num_zerodiv(mrb);
|
||||
#ifdef HAVE_FMOD
|
||||
mod = fmod(x, y);
|
||||
#else
|
||||
{
|
||||
double z;
|
||||
|
||||
modf(x/y, &z);
|
||||
mod = x - z * y;
|
||||
}
|
||||
#endif
|
||||
if (isinf(x) && !isinf(y) && !isnan(y))
|
||||
div = x;
|
||||
else
|
||||
|
@ -498,12 +473,12 @@ static mrb_value
|
|||
flo_mod(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
double fy, mod;
|
||||
mrb_float fy, mod;
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
fy = (double)mrb_fixnum(y);
|
||||
fy = (mrb_float)mrb_fixnum(y);
|
||||
break;
|
||||
case MRB_TT_FLOAT:
|
||||
fy = mrb_float(y);
|
||||
|
@ -516,13 +491,13 @@ flo_mod(mrb_state *mrb, mrb_value x)
|
|||
}
|
||||
|
||||
static mrb_value
|
||||
dbl2ival(double d)
|
||||
flt2ival(mrb_float d)
|
||||
{
|
||||
if (FIXABLE(d)) {
|
||||
d = round(d);
|
||||
return mrb_fixnum_value((long)d);
|
||||
}
|
||||
return mrb_nil_value(); /* range over */ //mrb_dbl2big(d);
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
|
||||
|
@ -576,12 +551,12 @@ static mrb_value
|
|||
flo_eq(mrb_state *mrb, mrb_value x)
|
||||
{
|
||||
mrb_value y;
|
||||
volatile double a, b;
|
||||
volatile mrb_float a, b;
|
||||
mrb_get_args(mrb, "o", &y);
|
||||
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FIXNUM:
|
||||
b = (double)mrb_fixnum(y);
|
||||
b = (mrb_float)mrb_fixnum(y);
|
||||
break;
|
||||
case MRB_TT_FLOAT:
|
||||
b = mrb_float(y);
|
||||
|
@ -609,14 +584,14 @@ flo_eq(mrb_state *mrb, mrb_value x)
|
|||
static mrb_value
|
||||
flo_hash(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double d;
|
||||
mrb_float d;
|
||||
char *c;
|
||||
int i, hash;
|
||||
|
||||
d = (double)mrb_fixnum(num);
|
||||
d = (mrb_float)mrb_fixnum(num);
|
||||
if (d == 0) d = fabs(d);
|
||||
c = (char*)&d;
|
||||
for (hash=0, i=0; i<sizeof(double);i++) {
|
||||
for (hash=0, i=0; i<sizeof(mrb_float);i++) {
|
||||
hash = (hash * 971) ^ (unsigned char)c[i];
|
||||
}
|
||||
if (hash < 0) hash = -hash;
|
||||
|
@ -624,7 +599,7 @@ flo_hash(mrb_state *mrb, mrb_value num)
|
|||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dbl_cmp(double a, double b)
|
||||
mrb_flt_cmp(double a, double b)
|
||||
{
|
||||
if (isnan(a) || isnan(b)) return mrb_nil_value();
|
||||
if (a == b) return mrb_fixnum_value(0);
|
||||
|
@ -663,7 +638,7 @@ flo_to_f(mrb_state *mrb, mrb_value num)
|
|||
static mrb_value
|
||||
flo_is_infinite_p(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double value = mrb_float(num);
|
||||
mrb_float value = mrb_float(num);
|
||||
|
||||
if (isinf(value)) {
|
||||
return mrb_fixnum_value( value < 0 ? -1 : 1 );
|
||||
|
@ -686,7 +661,7 @@ flo_is_infinite_p(mrb_state *mrb, mrb_value num)
|
|||
static mrb_value
|
||||
flo_is_finite_p(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double value = mrb_float(num);
|
||||
mrb_float value = mrb_float(num);
|
||||
|
||||
#if HAVE_FINITE
|
||||
if (!finite(value))
|
||||
|
@ -715,11 +690,11 @@ flo_is_finite_p(mrb_state *mrb, mrb_value num)
|
|||
static mrb_value
|
||||
flo_floor(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double f = floor(mrb_float(num));
|
||||
mrb_float f = floor(mrb_float(num));
|
||||
long val;
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
return mrb_dbl2big(mrb, f);
|
||||
return mrb_flt2big(mrb, f);
|
||||
}
|
||||
val = (long)f;
|
||||
return mrb_fixnum_value(val);
|
||||
|
@ -742,11 +717,11 @@ flo_floor(mrb_state *mrb, mrb_value num)
|
|||
static mrb_value
|
||||
flo_ceil(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double f = ceil(mrb_float(num));
|
||||
mrb_float f = ceil(mrb_float(num));
|
||||
long val;
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
return mrb_dbl2big(mrb, f);
|
||||
return mrb_flt2big(mrb, f);
|
||||
}
|
||||
val = (long)f;
|
||||
return mrb_fixnum_value(val);
|
||||
|
@ -787,7 +762,7 @@ static mrb_value
|
|||
flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
|
||||
{
|
||||
mrb_value nd;
|
||||
double number, f;
|
||||
mrb_float number, f;
|
||||
int ndigits = 0, i;
|
||||
long val;
|
||||
mrb_value *argv;
|
||||
|
@ -819,7 +794,7 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
|
|||
if (ndigits > 0) return mrb_float_value(number);
|
||||
|
||||
if (!FIXABLE(number)) {
|
||||
return mrb_dbl2big(mrb, number);
|
||||
return mrb_flt2big(mrb, number);
|
||||
}
|
||||
val = (long)number;
|
||||
return mrb_fixnum_value(val);
|
||||
|
@ -839,14 +814,14 @@ flo_round(mrb_state *mrb, /*int argc, mrb_value *argv,*/ mrb_value num)
|
|||
static mrb_value
|
||||
flo_truncate(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double f = mrb_float(num);
|
||||
mrb_float f = mrb_float(num);
|
||||
long val;
|
||||
|
||||
if (f > 0.0) f = floor(f);
|
||||
if (f < 0.0) f = ceil(f);
|
||||
|
||||
if (!FIXABLE(f)) {
|
||||
return mrb_dbl2big(mrb, f);
|
||||
return mrb_flt2big(mrb, f);
|
||||
}
|
||||
val = (long)f;
|
||||
return mrb_fixnum_value(val);
|
||||
|
@ -900,8 +875,8 @@ mrb_num2long(mrb_state *mrb, mrb_value val)
|
|||
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_FLOAT:
|
||||
if (mrb_float(val) <= (double)LONG_MAX
|
||||
&& mrb_float(val) >= (double)LONG_MIN) {
|
||||
if (mrb_float(val) <= (mrb_float)LONG_MAX
|
||||
&& mrb_float(val) >= (mrb_float)LONG_MIN) {
|
||||
return (SIGNED_VALUE)(mrb_float(val));
|
||||
}
|
||||
else {
|
||||
|
@ -931,8 +906,8 @@ mrb_num2ulong(mrb_state *mrb, mrb_value val)
|
|||
|
||||
switch (mrb_type(val)) {
|
||||
case MRB_TT_FLOAT:
|
||||
if (mrb_float(val) <= (double)LONG_MAX
|
||||
&& mrb_float(val) >= (double)LONG_MIN) {
|
||||
if (mrb_float(val) <= (mrb_float)LONG_MAX
|
||||
&& mrb_float(val) >= (mrb_float)LONG_MIN) {
|
||||
return mrb_fixnum_value(mrb_float(val));
|
||||
}
|
||||
else {
|
||||
|
@ -1121,7 +1096,7 @@ fix_mul(mrb_state *mrb, mrb_value x)
|
|||
}
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FLOAT:
|
||||
return mrb_float_value((double)mrb_fixnum(x) * mrb_float(y));
|
||||
return mrb_float_value((mrb_float)mrb_fixnum(x) * mrb_float(y));
|
||||
default:
|
||||
return mrb_num_coerce_bin(mrb, x, y, "*");
|
||||
}
|
||||
|
@ -1170,16 +1145,16 @@ fix_divide(mrb_state *mrb, mrb_value x, mrb_value y, char* op)
|
|||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
double div;
|
||||
mrb_float div;
|
||||
|
||||
if (*op == '/') {
|
||||
div = (double)mrb_fixnum(x) / mrb_float(y);
|
||||
div = (mrb_float)mrb_fixnum(x) / mrb_float(y);
|
||||
return mrb_float_value(div);
|
||||
}
|
||||
else {
|
||||
if (mrb_float(y) == 0) mrb_num_zerodiv(mrb);
|
||||
div = (double)mrb_fixnum(x) / mrb_float(y);
|
||||
return mrb_dbl2big(mrb, floor(div));
|
||||
div = (mrb_float)mrb_fixnum(x) / mrb_float(y);
|
||||
return mrb_flt2big(mrb, floor(div));
|
||||
}
|
||||
}
|
||||
//case MRB_TT_RATIONAL:
|
||||
|
@ -1235,9 +1210,9 @@ fix_mod(mrb_state *mrb, mrb_value x)
|
|||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
double mod;
|
||||
mrb_float mod;
|
||||
|
||||
flodivmod(mrb, (double)mrb_fixnum(x), mrb_float(y), 0, &mod);
|
||||
flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_float(y), 0, &mod);
|
||||
return mrb_float_value(mod);
|
||||
}
|
||||
default:
|
||||
|
@ -1267,11 +1242,11 @@ fix_divmod(mrb_state *mrb, mrb_value x)
|
|||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FLOAT:
|
||||
{
|
||||
double div, mod;
|
||||
mrb_float div, mod;
|
||||
volatile mrb_value a, b;
|
||||
|
||||
flodivmod(mrb, (double)mrb_fixnum(x), mrb_float(y), &div, &mod);
|
||||
a = dbl2ival(div);
|
||||
flodivmod(mrb, (mrb_float)mrb_fixnum(x), mrb_float(y), &div, &mod);
|
||||
a = flt2ival(div);
|
||||
b = mrb_float_value(mod);
|
||||
return mrb_assoc_new(mrb, a, b);
|
||||
}
|
||||
|
@ -1302,7 +1277,7 @@ fix_equal(mrb_state *mrb, mrb_value x)
|
|||
if (FIXNUM_P(y)) return mrb_false_value();
|
||||
switch (mrb_type(y)) {
|
||||
case MRB_TT_FLOAT:
|
||||
return (double)mrb_fixnum(x) == mrb_float(y) ? mrb_true_value() : mrb_false_value();
|
||||
return (mrb_float)mrb_fixnum(x) == mrb_float(y) ? mrb_true_value() : mrb_false_value();
|
||||
default:
|
||||
return num_equal(mrb, x, y);
|
||||
}
|
||||
|
@ -1507,9 +1482,9 @@ fix_rshift(long val, unsigned long i)
|
|||
static mrb_value
|
||||
fix_to_f(mrb_state *mrb, mrb_value num)
|
||||
{
|
||||
double val;
|
||||
mrb_float val;
|
||||
|
||||
val = (double)mrb_fixnum(num);
|
||||
val = (mrb_float)mrb_fixnum(num);
|
||||
|
||||
return mrb_float_value(val);
|
||||
}
|
||||
|
@ -1547,13 +1522,12 @@ fix_to_f(mrb_state *mrb, mrb_value num)
|
|||
*/
|
||||
/* ------------------------------------------------------------------------*/
|
||||
static mrb_int
|
||||
dbl2big(mrb_state *mrb, float d)
|
||||
flt2big(mrb_state *mrb, float d)
|
||||
{
|
||||
//long i = 0;
|
||||
//BDIGIT c;
|
||||
//BDIGIT *digits;
|
||||
mrb_int z;
|
||||
//double u = (d < 0)?-d:d;
|
||||
|
||||
if (isinf(d)) {
|
||||
mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity");
|
||||
|
@ -1566,9 +1540,9 @@ dbl2big(mrb_state *mrb, float d)
|
|||
}
|
||||
|
||||
mrb_value
|
||||
mrb_dbl2big(mrb_state *mrb, float d)
|
||||
mrb_flt2big(mrb_state *mrb, float d)
|
||||
{
|
||||
return mrb_fixnum_value(dbl2big(mrb, d));//bignorm(dbl2big(d));
|
||||
return mrb_fixnum_value(flt2big(mrb, d));
|
||||
}
|
||||
|
||||
/* 15.2.8.3.1 */
|
||||
|
|
|
@ -569,7 +569,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
|
|||
&& mrb_float(val) >= (double)FIXNUM_MIN) {
|
||||
break;
|
||||
}
|
||||
return mrb_dbl2big(mrb, mrb_float(val));
|
||||
return mrb_flt2big(mrb, mrb_float(val));
|
||||
|
||||
case MRB_TT_FIXNUM:
|
||||
if (base != 0) goto arg_error;
|
||||
|
|
|
@ -3038,8 +3038,11 @@ skip(parser_state *p, char term)
|
|||
{
|
||||
int c;
|
||||
|
||||
while ((c = nextc(p)) != term)
|
||||
;
|
||||
for (;;) {
|
||||
c = nextc(p);
|
||||
if (c < 0) break;
|
||||
if (c == term) break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -42,14 +42,14 @@ static mrb_value
|
|||
p_m(mrb_state *mrb, mrb_value self)
|
||||
{
|
||||
int argc, i;
|
||||
mrb_value *argv;
|
||||
mrb_value *argv = NULL;
|
||||
|
||||
mrb_get_args(mrb, "*", &argv, &argc);
|
||||
for (i=0; i<argc; i++) {
|
||||
mrb_p(mrb, argv[i]);
|
||||
}
|
||||
|
||||
return argv[0];
|
||||
return argv ? argv[0] : mrb_nil_value();
|
||||
}
|
||||
|
||||
mrb_value
|
||||
|
|
|
@ -811,7 +811,7 @@ bin_retry:
|
|||
val = mrb_fixnum_value((mrb_int)mrb_float(val));
|
||||
goto bin_retry;
|
||||
}
|
||||
val = mrb_dbl2big(mrb, mrb_float(val));
|
||||
val = mrb_flt2big(mrb, mrb_float(val));
|
||||
if (FIXNUM_P(val)) goto bin_retry;
|
||||
break;
|
||||
case MRB_TT_STRING:
|
||||
|
|
|
@ -347,9 +347,11 @@ mrb_f_global_variables(mrb_state *mrb, mrb_value self)
|
|||
struct kh_iv *h = mrb->globals;
|
||||
mrb_value ary = mrb_ary_new(mrb);
|
||||
|
||||
for (i=0;i< kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(h,i)));
|
||||
if (h) {
|
||||
for (i=0;i < kh_end(h);i++) {
|
||||
if (kh_exist(h, i)) {
|
||||
mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(h,i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
buf[0] = '$';
|
||||
|
|
|
@ -30,11 +30,11 @@ INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
|
|||
CC = gcc
|
||||
LL = gcc
|
||||
YACC = bison
|
||||
DEBUG_MODE = 0
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O2 -g
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL)
|
||||
|
|
|
@ -38,11 +38,11 @@ INCLUDES = -I$(BASEDIR) -I$(BASEDIR)/../include
|
|||
CC = gcc
|
||||
LL = gcc
|
||||
YACC = bison
|
||||
DEBUG_MODE = 0
|
||||
DEBUG_MODE = 1
|
||||
ifeq ($(DEBUG_MODE),1)
|
||||
CFLAGS = -g
|
||||
else
|
||||
CFLAGS = -O2 -g
|
||||
CFLAGS = -O3
|
||||
endif
|
||||
ALL_CFLAGS = -Wall -Werror-implicit-function-declaration $(CFLAGS)
|
||||
MAKE_FLAGS = --no-print-directory CC=$(CC) LL=$(LL)
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "mruby.h"
|
||||
#include "mruby/proc.h"
|
||||
#include "mruby/array.h"
|
||||
#include "mruby/string.h"
|
||||
#include "compile.h"
|
||||
#include "mruby/dump.h"
|
||||
#include <stdio.h>
|
||||
|
@ -12,9 +14,12 @@ void codedump_all(mrb_state*, int);
|
|||
|
||||
struct _args {
|
||||
FILE *rfp;
|
||||
char* cmdline;
|
||||
int mrbfile : 1;
|
||||
int check_syntax : 1;
|
||||
int verbose : 1;
|
||||
int argc;
|
||||
char** argv;
|
||||
};
|
||||
|
||||
static void
|
||||
|
@ -24,6 +29,7 @@ usage(const char *name)
|
|||
"switches:",
|
||||
"-b load and execute RiteBinary (mrb) file",
|
||||
"-c check syntax only",
|
||||
"-e 'command' one line of script",
|
||||
"-v print version number, then run in verbose mode",
|
||||
"--verbose run in verbose mode",
|
||||
"--version print the version",
|
||||
|
@ -45,52 +51,80 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct _args *args)
|
|||
memset(args, 0, sizeof(*args));
|
||||
|
||||
for (argc--,argv++; argc > 0; argc--,argv++) {
|
||||
if (**argv == '-') {
|
||||
if (strlen(*argv) <= 1)
|
||||
return -1;
|
||||
if (argv[0][0] != '-') break;
|
||||
|
||||
switch ((*argv)[1]) {
|
||||
case 'b':
|
||||
args->mrbfile = 1;
|
||||
break;
|
||||
case 'c':
|
||||
args->check_syntax = 1;
|
||||
break;
|
||||
case 'v':
|
||||
ruby_show_version(mrb);
|
||||
args->verbose = 1;
|
||||
break;
|
||||
case '-':
|
||||
if (strcmp((*argv) + 2, "version") == 0) {
|
||||
ruby_show_version(mrb);
|
||||
}
|
||||
else if (strcmp((*argv) + 2, "verbose") == 0) {
|
||||
args->verbose = 1;
|
||||
break;
|
||||
}
|
||||
else if (strcmp((*argv) + 2, "copyright") == 0) {
|
||||
ruby_show_copyright(mrb);
|
||||
}
|
||||
else return -3;
|
||||
return 0;
|
||||
if (strlen(*argv) <= 1)
|
||||
return -1;
|
||||
|
||||
switch ((*argv)[1]) {
|
||||
case 'b':
|
||||
args->mrbfile = 1;
|
||||
break;
|
||||
case 'c':
|
||||
args->check_syntax = 1;
|
||||
break;
|
||||
case 'e':
|
||||
if (argc > 1) {
|
||||
argc--; argv++;
|
||||
if (!args->cmdline) {
|
||||
char *buf;
|
||||
|
||||
buf = mrb_malloc(mrb, strlen(argv[0])+1);
|
||||
strcpy(buf, argv[0]);
|
||||
args->cmdline = buf;
|
||||
}
|
||||
else {
|
||||
args->cmdline = mrb_realloc(mrb, args->cmdline, strlen(args->cmdline)+strlen(argv[0])+2);
|
||||
strcat(args->cmdline, "\n");
|
||||
strcat(args->cmdline, argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (args->rfp == NULL) {
|
||||
if ((args->rfp = fopen(*argv, args->mrbfile ? "rb" : "r")) == NULL) {
|
||||
printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
|
||||
return 0;
|
||||
else {
|
||||
printf("%s: No code specified for -e\n", *origargv);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
ruby_show_version(mrb);
|
||||
args->verbose = 1;
|
||||
break;
|
||||
case '-':
|
||||
if (strcmp((*argv) + 2, "version") == 0) {
|
||||
ruby_show_version(mrb);
|
||||
}
|
||||
else if (strcmp((*argv) + 2, "verbose") == 0) {
|
||||
args->verbose = 1;
|
||||
break;
|
||||
}
|
||||
else if (strcmp((*argv) + 2, "copyright") == 0) {
|
||||
ruby_show_copyright(mrb);
|
||||
}
|
||||
else return -3;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (args->rfp == NULL && args->cmdline == NULL && (args->rfp = fopen(*argv, args->mrbfile ? "rb" : "r")) == NULL) {
|
||||
printf("%s: Cannot open program file. (%s)\n", *origargv, *argv);
|
||||
return 0;
|
||||
}
|
||||
args->argv = mrb_realloc(mrb, args->argv, sizeof(char*) * (argc + 1));
|
||||
memcpy(args->argv, argv, (argc+1) * sizeof(char*));
|
||||
args->argc = argc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(struct _args *args)
|
||||
cleanup(mrb_state *mrb, struct _args *args)
|
||||
{
|
||||
if (args->rfp)
|
||||
fclose(args->rfp);
|
||||
if (args->cmdline)
|
||||
mrb_free(mrb, args->cmdline);
|
||||
if (args->argv)
|
||||
mrb_free(mrb, args->argv);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -98,12 +132,13 @@ main(int argc, char **argv)
|
|||
{
|
||||
mrb_state *mrb = mrb_open();
|
||||
int n = -1;
|
||||
int i;
|
||||
struct _args args;
|
||||
struct mrb_parser_state *p;
|
||||
|
||||
n = parse_args(mrb, argc, argv, &args);
|
||||
if (n < 0 || args.rfp == NULL) {
|
||||
cleanup(&args);
|
||||
if (n < 0 || (args.cmdline == NULL && args.rfp == NULL)) {
|
||||
cleanup(mrb, &args);
|
||||
usage(argv[0]);
|
||||
return n;
|
||||
}
|
||||
|
@ -112,9 +147,14 @@ main(int argc, char **argv)
|
|||
n = mrb_load_irep(mrb, args.rfp);
|
||||
}
|
||||
else {
|
||||
p = mrb_parse_file(mrb, args.rfp);
|
||||
if (args.cmdline) {
|
||||
p = mrb_parse_string(mrb, (char*)args.cmdline);
|
||||
}
|
||||
else {
|
||||
p = mrb_parse_file(mrb, args.rfp);
|
||||
}
|
||||
if (!p || !p->tree || p->nerr) {
|
||||
cleanup(&args);
|
||||
cleanup(mrb, &args);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -126,18 +166,24 @@ main(int argc, char **argv)
|
|||
}
|
||||
|
||||
if (n >= 0) {
|
||||
mrb_value ARGV = mrb_ary_new(mrb);
|
||||
for (i = 0; i < args.argc; i++) {
|
||||
mrb_ary_push(mrb, ARGV, mrb_str_new(mrb, args.argv[i], strlen(args.argv[i])));
|
||||
}
|
||||
mrb_define_global_const(mrb, "ARGV", ARGV);
|
||||
|
||||
if (args.verbose)
|
||||
codedump_all(mrb, n);
|
||||
|
||||
if (!args.check_syntax) {
|
||||
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_nil_value());
|
||||
mrb_run(mrb, mrb_proc_new(mrb, mrb->irep[n]), mrb_top_self(mrb));
|
||||
if (mrb->exc) {
|
||||
mrb_funcall(mrb, mrb_nil_value(), "p", 1, mrb_obj_value(mrb->exc));
|
||||
mrb_p(mrb, mrb_obj_value(mrb->exc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup(&args);
|
||||
cleanup(mrb, &args);
|
||||
|
||||
return n;
|
||||
return n > 0 ? 0 : 1;
|
||||
}
|
||||
|
|
|
@ -347,7 +347,6 @@ static void RunShell (mrb_state* mrb) {
|
|||
char* input = console->prompt("avocirb> ");
|
||||
|
||||
if (input == 0) {
|
||||
printf("\nBye Bye! Auf Wiedersehen! さようなら\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -386,6 +385,9 @@ static void RunShell (mrb_state* mrb) {
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
console->close();
|
||||
printf("\nBye Bye! Auf Wiedersehen! さようなら\n");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -36,10 +36,12 @@
|
|||
#define completion_matches rl_completion_matches
|
||||
#endif
|
||||
|
||||
#ifdef TRI_ENABLE_MRUBY
|
||||
extern "C" {
|
||||
#include "mruby.h"
|
||||
#include "compile.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -278,6 +280,8 @@ bool MRLineEditor::open (const bool autoComplete) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool MRLineEditor::isComplete (string const& source, size_t lineno, size_t column) {
|
||||
|
||||
#ifdef TRI_ENABLE_MRUBY
|
||||
char const* msg = "syntax error, unexpected $end";
|
||||
char* text = TRI_DuplicateString(source.c_str());
|
||||
|
||||
|
@ -300,6 +304,7 @@ bool MRLineEditor::isComplete (string const& source, size_t lineno, size_t colum
|
|||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,781 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compare methods used for skiplist indexes
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright by triAGENS GmbH - All rights reserved.
|
||||
///
|
||||
/// The Programs (which include both the software and documentation)
|
||||
/// contain proprietary information of triAGENS GmbH; they are
|
||||
/// provided under a license agreement containing restrictions on use and
|
||||
/// disclosure and are also protected by copyright, patent and other
|
||||
/// intellectual and industrial property laws. Reverse engineering,
|
||||
/// disassembly or decompilation of the Programs, except to the extent
|
||||
/// required to obtain interoperability with other independently created
|
||||
/// software or as specified by law, is prohibited.
|
||||
///
|
||||
/// The Programs are not intended for use in any nuclear, aviation, mass
|
||||
/// transit, medical, or other inherently dangerous applications. It shall
|
||||
/// be the licensee's responsibility to take all appropriate fail-safe,
|
||||
/// backup, redundancy, and other measures to ensure the safe use of such
|
||||
/// applications if the Programs are used for such purposes, and triAGENS
|
||||
/// GmbH disclaims liability for any damages caused by such use of
|
||||
/// the Programs.
|
||||
///
|
||||
/// This software is the confidential and proprietary information of
|
||||
/// triAGENS GmbH. You shall not disclose such confidential and
|
||||
/// proprietary information and shall use it only in accordance with the
|
||||
/// terms of the license agreement you entered into with triAGENS GmbH.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Dr. O
|
||||
/// @author Copyright 2011, triagens GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef TRIAGENS_DURHAM_VOC_BASE_SKIPLIST_COMPARE_H
|
||||
#define TRIAGENS_DURHAM_VOC_BASE_SKIPLIST_COMPARE_H 1
|
||||
|
||||
#include "ShapedJson/json-shaper.h"
|
||||
#include "ShapedJson/shaped-json.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
|
||||
#define USE_STATIC_SKIPLIST_COMPARE 1
|
||||
|
||||
#define SKIPLIST_ELEMENT_TYPE(a,b) \
|
||||
struct a { \
|
||||
size_t numFields; \
|
||||
TRI_shaped_json_t* fields; \
|
||||
void* data; \
|
||||
void* collection; \
|
||||
} b
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Helper method for recursion for CompareShapedJsonShapedJson
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
static int CompareShapeTypes (const TRI_shaped_json_t* left, const TRI_shaped_json_t* right, TRI_shaper_t* leftShaper, TRI_shaper_t* rightShaper) {
|
||||
|
||||
int result;
|
||||
size_t j;
|
||||
TRI_shape_type_t leftType;
|
||||
TRI_shape_type_t rightType;
|
||||
const TRI_shape_t* leftShape;
|
||||
const TRI_shape_t* rightShape;
|
||||
size_t leftListLength;
|
||||
size_t rightListLength;
|
||||
size_t listLength;
|
||||
TRI_shaped_json_t leftElement;
|
||||
TRI_shaped_json_t rightElement;
|
||||
char* leftString;
|
||||
char* rightString;
|
||||
|
||||
|
||||
leftShape = leftShaper->lookupShapeId(leftShaper, left->_sid);
|
||||
rightShape = rightShaper->lookupShapeId(rightShaper, right->_sid);
|
||||
leftType = leftShape->_type;
|
||||
rightType = rightShape->_type;
|
||||
|
||||
switch (leftType) {
|
||||
|
||||
case TRI_SHAPE_ILLEGAL: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_NULL: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_NULL:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_BOOLEAN: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
{
|
||||
// check which is false and which is true!
|
||||
if ( *((TRI_shape_boolean_t*)(left->_data.data)) == *((TRI_shape_boolean_t*)(right->_data.data)) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( *((TRI_shape_boolean_t*)(left->_data.data)) < *((TRI_shape_boolean_t*)(right->_data.data)) ) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_NUMBER: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_NUMBER:
|
||||
{
|
||||
// compare the numbers.
|
||||
if ( *((TRI_shape_number_t*)(left->_data.data)) == *((TRI_shape_number_t*)(right->_data.data)) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( *((TRI_shape_number_t*)(left->_data.data)) < *((TRI_shape_number_t*)(right->_data.data)) ) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
{
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
{
|
||||
// compare strings
|
||||
// extract the strings
|
||||
if (leftType == TRI_SHAPE_SHORT_STRING) {
|
||||
leftString = (char*)(sizeof(TRI_shape_length_short_string_t) + left->_data.data);
|
||||
}
|
||||
else {
|
||||
leftString = (char*)(sizeof(TRI_shape_length_long_string_t) + left->_data.data);
|
||||
}
|
||||
|
||||
if (rightType == TRI_SHAPE_SHORT_STRING) {
|
||||
rightString = (char*)(sizeof(TRI_shape_length_short_string_t) + right->_data.data);
|
||||
}
|
||||
else {
|
||||
rightString = (char*)(sizeof(TRI_shape_length_long_string_t) + right->_data.data);
|
||||
}
|
||||
|
||||
result = strcmp(leftString,rightString);
|
||||
return result;
|
||||
}
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
case TRI_SHAPE_LIST:
|
||||
{
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
case TRI_SHAPE_LIST:
|
||||
{
|
||||
// unfortunately recursion: check the types of all the entries
|
||||
leftListLength = *((TRI_shape_length_list_t*)(left->_data.data));
|
||||
rightListLength = *((TRI_shape_length_list_t*)(right->_data.data));
|
||||
|
||||
// determine the smallest list
|
||||
if (leftListLength > rightListLength) {
|
||||
listLength = rightListLength;
|
||||
}
|
||||
else {
|
||||
listLength = leftListLength;
|
||||
}
|
||||
|
||||
for (j = 0; j < listLength; ++j) {
|
||||
|
||||
if (leftType == TRI_SHAPE_HOMOGENEOUS_LIST) {
|
||||
TRI_AtHomogeneousListShapedJson((const TRI_homogeneous_list_shape_t*)(leftShape),
|
||||
left,j,&leftElement);
|
||||
}
|
||||
else if (leftType == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) {
|
||||
TRI_AtHomogeneousSizedListShapedJson((const TRI_homogeneous_sized_list_shape_t*)(leftShape),
|
||||
left,j,&leftElement);
|
||||
}
|
||||
else {
|
||||
TRI_AtListShapedJson((const TRI_list_shape_t*)(leftShape),left,j,&leftElement);
|
||||
}
|
||||
|
||||
|
||||
if (rightType == TRI_SHAPE_HOMOGENEOUS_LIST) {
|
||||
TRI_AtHomogeneousListShapedJson((const TRI_homogeneous_list_shape_t*)(rightShape),
|
||||
right,j,&rightElement);
|
||||
}
|
||||
else if (rightType == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) {
|
||||
TRI_AtHomogeneousSizedListShapedJson((const TRI_homogeneous_sized_list_shape_t*)(rightShape),
|
||||
right,j,&rightElement);
|
||||
}
|
||||
else {
|
||||
TRI_AtListShapedJson((const TRI_list_shape_t*)(rightShape),right,j,&rightElement);
|
||||
}
|
||||
|
||||
result = CompareShapeTypes (&leftElement, &rightElement, leftShaper, rightShaper);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// up to listLength everything matches
|
||||
if (leftListLength < rightListLength) {
|
||||
return -1;
|
||||
}
|
||||
else if (leftListLength > rightListLength) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case TRI_SHAPE_ARRAY:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_ARRAY:
|
||||
{
|
||||
/* start oreste:
|
||||
char* shape = (char*)(leftShape);
|
||||
uint64_t fixedEntries;
|
||||
uint64_t variableEntries;
|
||||
uint64_t ssid;
|
||||
uint64_t aaid;
|
||||
char* name;
|
||||
TRI_shape_t* newShape;
|
||||
|
||||
shape = shape + sizeof(TRI_shape_t);
|
||||
fixedEntries = *((TRI_shape_size_t*)(shape));
|
||||
shape = shape + sizeof(TRI_shape_size_t);
|
||||
variableEntries = *((TRI_shape_size_t*)(shape));
|
||||
shape = shape + sizeof(TRI_shape_size_t);
|
||||
ssid = *((TRI_shape_sid_t*)(shape));
|
||||
shape = shape + (sizeof(TRI_shape_sid_t) * (fixedEntries + variableEntries));
|
||||
aaid = *((TRI_shape_aid_t*)(shape));
|
||||
shape = shape + (sizeof(TRI_shape_aid_t) * (fixedEntries + variableEntries));
|
||||
|
||||
name = leftShaper->lookupAttributeId(leftShaper,aaid);
|
||||
newShape = leftShaper->lookupShapeId(leftShaper, ssid);
|
||||
|
||||
|
||||
printf("%s:%u:_fixedEntries:%u\n",__FILE__,__LINE__,fixedEntries);
|
||||
printf("%s:%u:_variableEntries:%u\n",__FILE__,__LINE__,variableEntries);
|
||||
printf("%s:%u:_sids[0]:%u\n",__FILE__,__LINE__,ssid);
|
||||
printf("%s:%u:_aids[0]:%u\n",__FILE__,__LINE__,aaid);
|
||||
printf("%s:%u:name:%s\n",__FILE__,__LINE__,name);
|
||||
printf("%s:%u:type:%d\n",__FILE__,__LINE__,newShape->_type);
|
||||
|
||||
end oreste */
|
||||
assert(false);
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
case TRI_SHAPE_LIST:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_ARRAY:
|
||||
{
|
||||
assert(false);
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Compare a shapded json object recursively if necessary
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CompareShapedJsonShapedJson (const TRI_shaped_json_t* left, const TRI_shaped_json_t* right, TRI_shaper_t* leftShaper, TRI_shaper_t* rightShaper) {
|
||||
|
||||
int result;
|
||||
|
||||
// ............................................................................
|
||||
// the following order is currently defined for placing an order on documents
|
||||
// undef < null < boolean < number < strings < lists < hash arrays
|
||||
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
|
||||
// within each type class we have the following order
|
||||
// boolean: false < true
|
||||
// number: natural order
|
||||
// strings: lexicographical
|
||||
// lists: lexicorgraphically and within each slot according to these rules.
|
||||
// ............................................................................
|
||||
|
||||
|
||||
if (left == NULL && right == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left == NULL && right != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (left != NULL && right == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
result = CompareShapeTypes (left, right, leftShaper, rightShaper);
|
||||
|
||||
return result;
|
||||
|
||||
} // end of function CompareShapedJsonShapedJson
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compares two elements in a skip list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int IndexStaticCompareElementElement (struct TRI_skiplist_s* skiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
|
||||
// .............................................................................
|
||||
// Compare two elements and determines:
|
||||
// left < right : return -1
|
||||
// left == right : return 0
|
||||
// left > right : return 1
|
||||
// .............................................................................
|
||||
int compareResult;
|
||||
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
|
||||
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
// ............................................................................
|
||||
// the following order is currently defined for placing an order on documents
|
||||
// undef < null < boolean < number < strings < lists < hash arrays
|
||||
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
|
||||
// within each type class we have the following order
|
||||
// boolean: false < true
|
||||
// number: natural order
|
||||
// strings: lexicographical
|
||||
// lists: lexicographically and within each slot according to these rules.
|
||||
// ............................................................................
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// This call back function is used when we insert and remove unique skip
|
||||
// list entries.
|
||||
// ............................................................................
|
||||
|
||||
if (hLeftElement->numFields != hRightElement->numFields) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// The document could be the same -- so no further comparison is required.
|
||||
// ............................................................................
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < hLeftElement->numFields; j++) {
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// This is where the difference between CompareKeyElement (below) and
|
||||
// CompareElementElement comes into play. Here if the 'keys' are the same,
|
||||
// but the doc ptr is different (which it is since we are here), then
|
||||
// we return what was requested to be returned: 0,-1 or 1. What is returned
|
||||
// depends on the purpose of calling this callback.
|
||||
// ............................................................................
|
||||
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compares a key and an element
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int IndexStaticCompareKeyElement (struct TRI_skiplist_s* skiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
|
||||
|
||||
// .............................................................................
|
||||
// Compare two elements and determines:
|
||||
// left < right : return -1
|
||||
// left == right : return 0
|
||||
// left > right : return 1
|
||||
// .............................................................................
|
||||
int compareResult;
|
||||
size_t numFields;
|
||||
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
|
||||
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
// ............................................................................
|
||||
// the following order is currently defined for placing an order on documents
|
||||
// undef < null < boolean < number < strings < lists < hash arrays
|
||||
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
|
||||
// within each type class we have the following order
|
||||
// boolean: false < true
|
||||
// number: natural order
|
||||
// strings: lexicographical
|
||||
// lists: lexicorgraphically and within each slot according to these rules.
|
||||
// associative array: ordered keys followed by value of key
|
||||
// ............................................................................
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// The document could be the same -- so no further comparison is required.
|
||||
// ............................................................................
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// This call back function is used when we query the index, as such
|
||||
// the number of fields which we are using for the query may be less than
|
||||
// the number of fields that the index is defined with.
|
||||
// ............................................................................
|
||||
|
||||
|
||||
if (hLeftElement->numFields < hRightElement->numFields) {
|
||||
numFields = hLeftElement->numFields;
|
||||
}
|
||||
else {
|
||||
numFields = hRightElement->numFields;
|
||||
}
|
||||
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < numFields; j++) {
|
||||
/*
|
||||
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
|
||||
*((double*)((j + hLeftElement->fields)->_data.data)),
|
||||
*((double*)((j + hRightElement->fields)->_data.data)),
|
||||
(uint64_t)(hLeftElement->data),
|
||||
(uint64_t)(hRightElement->data)
|
||||
);
|
||||
*/
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields),
|
||||
(j + hRightElement->fields),
|
||||
leftShaper,
|
||||
rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// The 'keys' match -- however, we may only have a partial match in reality
|
||||
// if not all keys comprising index have been used.
|
||||
// ............................................................................
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------
|
||||
// Non-unique skiplist
|
||||
//--------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief used to determine the order of two elements
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int IndexStaticMultiCompareElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
|
||||
|
||||
int compareResult;
|
||||
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
|
||||
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_GREATER;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_LESS;
|
||||
}
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
|
||||
}
|
||||
|
||||
if (hLeftElement->numFields != hRightElement->numFields) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
|
||||
}
|
||||
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < hLeftElement->numFields; j++) {
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief used to determine the order of two keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int IndexStaticMultiCompareKeyElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
|
||||
|
||||
int compareResult;
|
||||
size_t numFields;
|
||||
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
|
||||
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// The document could be the same -- so no further comparison is required.
|
||||
// ............................................................................
|
||||
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// This call back function is used when we query the index, as such
|
||||
// the number of fields which we are using for the query may be less than
|
||||
// the number of fields that the index is defined with.
|
||||
// ............................................................................
|
||||
|
||||
if (hLeftElement->numFields < hRightElement->numFields) {
|
||||
numFields = hLeftElement->numFields;
|
||||
}
|
||||
else {
|
||||
numFields = hRightElement->numFields;
|
||||
}
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < numFields; j++) {
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief used to determine the order of two keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool IndexStaticMultiEqualElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement) {
|
||||
|
||||
typedef SKIPLIST_ELEMENT_TYPE(LocalElement_s,LocalElement_t);
|
||||
|
||||
LocalElement_t* hLeftElement = (LocalElement_t*)(leftElement);
|
||||
LocalElement_t* hRightElement = (LocalElement_t*)(rightElement);
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
|
||||
*((double*)((hLeftElement->fields)->_data.data)),
|
||||
*((double*)((hRightElement->fields)->_data.data)),
|
||||
(uint64_t)(hLeftElement->data),
|
||||
(uint64_t)(hRightElement->data)
|
||||
);
|
||||
*/
|
||||
return (hLeftElement->data == hRightElement->data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||
// End:
|
||||
|
|
@ -28,6 +28,8 @@
|
|||
#include "skiplist.h"
|
||||
#include <BasicsC/random.h>
|
||||
|
||||
#include "compare.h"
|
||||
|
||||
#define SKIPLIST_ABSOLUTE_MAX_HEIGHT 100
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -89,18 +91,26 @@ static void TRI_DestroySkipListNode (TRI_skiplist_node_t* node) {
|
|||
/// @brief Grow the node at the height specified.
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void GrowNodeHeight(TRI_skiplist_node_t* node, uint32_t newHeight) {
|
||||
static bool GrowNodeHeight(TRI_skiplist_node_t* node, uint32_t newHeight) {
|
||||
|
||||
TRI_skiplist_nb_t* oldColumn = node->_column;
|
||||
uint32_t j;
|
||||
|
||||
if (node->_colLength >= newHeight) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
node->_column = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_skiplist_node_t) * newHeight, false);
|
||||
/* FIXME: memory allocation might fail */
|
||||
memcpy(node->_column, oldColumn, node->_colLength * sizeof(TRI_skiplist_node_t) );
|
||||
node->_column = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_skiplist_nb_t) * newHeight, false);
|
||||
|
||||
if (node->_column == NULL) {
|
||||
// out of memory?
|
||||
return false;
|
||||
}
|
||||
|
||||
if (oldColumn != NULL) {
|
||||
memcpy(node->_column, oldColumn, node->_colLength * sizeof(TRI_skiplist_nb_t) );
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, oldColumn);
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Initialise the storage
|
||||
|
@ -111,8 +121,9 @@ static void GrowNodeHeight(TRI_skiplist_node_t* node, uint32_t newHeight) {
|
|||
(node->_column)[j]._next = NULL;
|
||||
}
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, oldColumn);
|
||||
node->_colLength = newHeight;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
@ -323,6 +334,7 @@ void TRI_InitSkipList (TRI_skiplist_t* skiplist, size_t elementSize,
|
|||
int (*compareKeyElement) (TRI_skiplist_t*, void*, void*, int),
|
||||
TRI_skiplist_prob_e probability, uint32_t maximumHeight) {
|
||||
|
||||
bool growResult;
|
||||
if (skiplist == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -334,6 +346,12 @@ void TRI_InitSkipList (TRI_skiplist_t* skiplist, size_t elementSize,
|
|||
skiplist->compareElementElement = compareElementElement;
|
||||
skiplist->compareKeyElement = compareKeyElement;
|
||||
|
||||
#ifndef USE_STATIC_SKIPLIST_COMPARE
|
||||
if (compareElementElement == NULL || compareKeyElement == NULL) {
|
||||
printf("%s:%d:Compare function pointers have a value of NULL\n",__FILE__,__LINE__);
|
||||
assert(0);
|
||||
#endif
|
||||
|
||||
// ..........................................................................
|
||||
// Assign the maximum height of the skip list. This maximum height must be
|
||||
// no greater than the absolute max height defined as a compile time parameter
|
||||
|
@ -413,8 +431,12 @@ void TRI_InitSkipList (TRI_skiplist_t* skiplist, size_t elementSize,
|
|||
// each node will have a height of two. So initialise the start and end nodes
|
||||
// with this 'average' height
|
||||
// ..........................................................................
|
||||
GrowNodeHeight(&(skiplist->_base._startNode), 2);
|
||||
GrowNodeHeight(&(skiplist->_base._endNode), 2);
|
||||
growResult = GrowNodeHeight(&(skiplist->_base._startNode), 2); // may fail
|
||||
growResult = growResult && GrowNodeHeight(&(skiplist->_base._endNode), 2); // may fail
|
||||
if (!growResult) {
|
||||
// todo: undo growth by cutting down the node height
|
||||
return;
|
||||
}
|
||||
|
||||
// ..........................................................................
|
||||
// Join the empty lists together
|
||||
|
@ -502,6 +524,7 @@ bool TRI_InsertKeySkipList (TRI_skiplist_t* skiplist, void* key, void* element,
|
|||
TRI_skiplist_node_t* tempLeftNode;
|
||||
TRI_skiplist_node_t* tempRightNode;
|
||||
int compareResult;
|
||||
bool growResult;
|
||||
int j;
|
||||
|
||||
// ...........................................................................
|
||||
|
@ -539,8 +562,12 @@ bool TRI_InsertKeySkipList (TRI_skiplist_t* skiplist, void* key, void* element,
|
|||
// ...........................................................................
|
||||
oldColLength = skiplist->_base._startNode._colLength;
|
||||
if ((uint32_t)(newHeight) > oldColLength) {
|
||||
GrowNodeHeight(&(skiplist->_base._startNode), newHeight);
|
||||
GrowNodeHeight(&(skiplist->_base._endNode), newHeight);
|
||||
growResult = GrowNodeHeight(&(skiplist->_base._startNode), newHeight);
|
||||
growResult = growResult && GrowNodeHeight(&(skiplist->_base._endNode), newHeight);
|
||||
if (!growResult) {
|
||||
// todo: undo growth by cutting down the node height
|
||||
return false;
|
||||
}
|
||||
JoinNodes(&(skiplist->_base._startNode),&(skiplist->_base._endNode), oldColLength , newHeight - 1);
|
||||
}
|
||||
|
||||
|
@ -559,11 +586,15 @@ bool TRI_InsertKeySkipList (TRI_skiplist_t* skiplist, void* key, void* element,
|
|||
// Copy the contents of element into the new node to be inserted.
|
||||
// If a duplicate has been found, then we destroy the allocated memory.
|
||||
// ...........................................................................
|
||||
newNode->_extraData = NULL;
|
||||
newNode->_column = NULL;
|
||||
newNode->_colLength = 0;
|
||||
newNode->_extraData = NULL;
|
||||
memcpy(&(newNode->_element),element,skiplist->_base._elementSize);
|
||||
GrowNodeHeight(newNode, newHeight);
|
||||
|
||||
growResult = GrowNodeHeight(newNode, newHeight);
|
||||
if (!growResult) {
|
||||
TRI_FreeSkipListNode(&(skiplist->_base), newNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Determine the path where the new item is to be inserted. If the item
|
||||
|
@ -639,7 +670,12 @@ bool TRI_InsertKeySkipList (TRI_skiplist_t* skiplist, void* key, void* element,
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticCompareKeyElement(skiplist,key,&(nextNode->_element), 0);
|
||||
#else
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(nextNode->_element), 0);
|
||||
#endif
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// The element matches the next element. Overwrite if possible and return.
|
||||
|
@ -794,7 +830,12 @@ void* TRI_LeftLookupByKeySkipList (TRI_skiplist_t* skiplist, void* key) {
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticCompareKeyElement(skiplist,key,&(nextNode->_element), -1);
|
||||
#else
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(nextNode->_element), -1);
|
||||
#endif
|
||||
|
||||
|
||||
// .......................................................................
|
||||
// -1 is returned if the number of fields (attributes) in the key is LESS
|
||||
|
@ -940,7 +981,11 @@ void* TRI_LookupByKeySkipList (TRI_skiplist_t* skiplist, void* key) {
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticCompareKeyElement(skiplist,key,&(nextNode->_element), 0);
|
||||
#else
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(nextNode->_element), 0);
|
||||
#endif
|
||||
|
||||
// .......................................................................
|
||||
// We have found the item!
|
||||
|
@ -1095,7 +1140,11 @@ bool TRI_RemoveElementSkipList (TRI_skiplist_t* skiplist, void* element, void* o
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticCompareElementElement(skiplist,element,&(nextNode->_element), -1);
|
||||
#else
|
||||
compareResult = skiplist->compareElementElement(skiplist,element,&(nextNode->_element), -1);
|
||||
#endif
|
||||
|
||||
// .......................................................................
|
||||
// We have found the item!
|
||||
|
@ -1260,7 +1309,11 @@ void* TRI_RightLookupByKeySkipList (TRI_skiplist_t* skiplist, void* key) {
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(prevNode->_element),1);
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticCompareKeyElement(skiplist,key,&(prevNode->_element), 1);
|
||||
#else
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(prevNode->_element), 1);
|
||||
#endif
|
||||
|
||||
|
||||
// .......................................................................
|
||||
|
@ -1359,6 +1412,8 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
|
|||
TRI_skiplist_prob_e probability,
|
||||
uint32_t maximumHeight) {
|
||||
|
||||
bool growResult;
|
||||
|
||||
if (skiplist == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -1370,6 +1425,12 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
|
|||
skiplist->compareElementElement = compareElementElement;
|
||||
skiplist->compareKeyElement = compareKeyElement;
|
||||
skiplist->equalElementElement = equalElementElement;
|
||||
|
||||
#ifndef USE_STATIC_SKIPLIST_COMPARE
|
||||
if (compareElementElement == NULL || compareKeyElement == NULL || equalElementElement == NULL) {
|
||||
printf("%s:%d:Compare function pointers have a value of NULL\n",__FILE__,__LINE__);
|
||||
assert(0);
|
||||
#endif
|
||||
|
||||
// ..........................................................................
|
||||
// Assign the maximum height of the skip list. This maximum height must be
|
||||
|
@ -1451,9 +1512,13 @@ void TRI_InitSkipListMulti (TRI_skiplist_multi_t* skiplist,
|
|||
// each node will have a height of two. So initialise the start and end nodes
|
||||
// with this 'average' height
|
||||
// ..........................................................................
|
||||
GrowNodeHeight(&(skiplist->_base._startNode), 2);
|
||||
GrowNodeHeight(&(skiplist->_base._endNode), 2);
|
||||
|
||||
growResult = GrowNodeHeight(&(skiplist->_base._startNode), 2);
|
||||
growResult = growResult && GrowNodeHeight(&(skiplist->_base._endNode), 2);
|
||||
if (!growResult) {
|
||||
// todo: truncate he nodes and return
|
||||
return;
|
||||
}
|
||||
|
||||
// ..........................................................................
|
||||
// Join the empty lists together
|
||||
// [N]<----------------------------------->[N]
|
||||
|
@ -1603,7 +1668,11 @@ void* TRI_LeftLookupByKeySkipListMulti(TRI_skiplist_multi_t* skiplist, void* key
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticMultiCompareKeyElement(skiplist,key,&(nextNode->_element), -1);
|
||||
#else
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(nextNode->_element), -1);
|
||||
#endif
|
||||
|
||||
|
||||
// .......................................................................
|
||||
|
@ -1685,6 +1754,7 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
|
|||
TRI_skiplist_node_t* newNode;
|
||||
TRI_skiplist_node_t* tempLeftNode;
|
||||
TRI_skiplist_node_t* tempRightNode;
|
||||
bool growResult;
|
||||
int compareResult;
|
||||
int j;
|
||||
|
||||
|
@ -1723,8 +1793,12 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
|
|||
// ...........................................................................
|
||||
oldColLength = skiplist->_base._startNode._colLength;
|
||||
if ((uint32_t)(newHeight) > oldColLength) {
|
||||
GrowNodeHeight(&(skiplist->_base._startNode), newHeight);
|
||||
GrowNodeHeight(&(skiplist->_base._endNode), newHeight);
|
||||
growResult = GrowNodeHeight(&(skiplist->_base._startNode), newHeight);
|
||||
growResult = growResult && GrowNodeHeight(&(skiplist->_base._endNode), newHeight);
|
||||
if (!growResult) {
|
||||
// todo: truncate the nodes and return;
|
||||
return false;
|
||||
}
|
||||
JoinNodes(&(skiplist->_base._startNode),&(skiplist->_base._endNode), oldColLength , newHeight - 1);
|
||||
}
|
||||
|
||||
|
@ -1743,11 +1817,15 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
|
|||
// Copy the contents of element into the new node to be inserted.
|
||||
// If a duplicate has been found, then we destroy the allocated memory.
|
||||
// ...........................................................................
|
||||
newNode->_extraData = NULL;
|
||||
newNode->_column = NULL;
|
||||
newNode->_colLength = 0;
|
||||
newNode->_extraData = NULL;
|
||||
memcpy(&(newNode->_element),element,skiplist->_base._elementSize);
|
||||
GrowNodeHeight(newNode, newHeight);
|
||||
|
||||
growResult = GrowNodeHeight(newNode, newHeight);
|
||||
if (!growResult) {
|
||||
TRI_FreeSkipListNode(&(skiplist->_base), newNode);
|
||||
return false;
|
||||
}
|
||||
|
||||
// ...........................................................................
|
||||
// Determine the path where the new item is to be inserted. If the item
|
||||
|
@ -1823,7 +1901,11 @@ bool TRI_InsertElementSkipListMulti(TRI_skiplist_multi_t* skiplist, void* elemen
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticMultiCompareElementElement(skiplist,element,&(nextNode->_element), -1);
|
||||
#else
|
||||
compareResult = skiplist->compareElementElement(skiplist, element, &(nextNode->_element), -1);
|
||||
#endif
|
||||
|
||||
|
||||
// .......................................................................
|
||||
|
@ -2030,7 +2112,11 @@ bool TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* eleme
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticMultiCompareElementElement(skiplist,element,&(nextNode->_element), TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS);
|
||||
#else
|
||||
compareResult = skiplist->compareElementElement(skiplist,element,&(nextNode->_element), TRI_SKIPLIST_COMPARE_SLIGHTLY_LESS);
|
||||
#endif
|
||||
|
||||
// .......................................................................
|
||||
// We have found an item which matches the key
|
||||
|
@ -2091,9 +2177,15 @@ bool TRI_RemoveElementSkipListMulti (TRI_skiplist_multi_t* skiplist, void* eleme
|
|||
// ..........................................................................
|
||||
|
||||
while (currentNode != NULL) {
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
if (IndexStaticMultiEqualElementElement(skiplist, element, &(currentNode->_element))) {
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (skiplist->equalElementElement(skiplist, element, &(currentNode->_element))) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
currentNode = TRI_NextNodeBaseSkipList(&(skiplist->_base), currentNode);
|
||||
}
|
||||
|
||||
|
@ -2230,7 +2322,11 @@ void* TRI_RightLookupByKeySkipListMulti(TRI_skiplist_multi_t* skiplist, void* ke
|
|||
// Use the callback to determine if the element is less or greater than
|
||||
// the next node element.
|
||||
// .......................................................................
|
||||
#ifdef USE_STATIC_SKIPLIST_COMPARE
|
||||
compareResult = IndexStaticMultiCompareKeyElement(skiplist,key,&(prevNode->_element), 1);
|
||||
#else
|
||||
compareResult = skiplist->compareKeyElement(skiplist,key,&(prevNode->_element), 1);
|
||||
#endif
|
||||
|
||||
|
||||
// .......................................................................
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "skiplistIndex.h"
|
||||
#include "VocBase/document-collection.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -50,365 +49,6 @@
|
|||
static bool skiplistIndex_findHelperIntervalValid(SkiplistIndex*, TRI_skiplist_iterator_interval_t*);
|
||||
static bool multiSkiplistIndex_findHelperIntervalValid(SkiplistIndex*, TRI_skiplist_iterator_interval_t*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Helper method for recursion for CompareShapedJsonShapedJson
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CompareShapeTypes (const TRI_shaped_json_t* left, const TRI_shaped_json_t* right, TRI_shaper_t* leftShaper, TRI_shaper_t* rightShaper) {
|
||||
|
||||
int result;
|
||||
size_t j;
|
||||
TRI_shape_type_t leftType;
|
||||
TRI_shape_type_t rightType;
|
||||
const TRI_shape_t* leftShape;
|
||||
const TRI_shape_t* rightShape;
|
||||
size_t leftListLength;
|
||||
size_t rightListLength;
|
||||
size_t listLength;
|
||||
TRI_shaped_json_t leftElement;
|
||||
TRI_shaped_json_t rightElement;
|
||||
char* leftString;
|
||||
char* rightString;
|
||||
|
||||
|
||||
leftShape = leftShaper->lookupShapeId(leftShaper, left->_sid);
|
||||
rightShape = rightShaper->lookupShapeId(rightShaper, right->_sid);
|
||||
leftType = leftShape->_type;
|
||||
rightType = rightShape->_type;
|
||||
|
||||
switch (leftType) {
|
||||
|
||||
case TRI_SHAPE_ILLEGAL: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_NULL: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_NULL:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_BOOLEAN: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
{
|
||||
// check which is false and which is true!
|
||||
if ( *((TRI_shape_boolean_t*)(left->_data.data)) == *((TRI_shape_boolean_t*)(right->_data.data)) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( *((TRI_shape_boolean_t*)(left->_data.data)) < *((TRI_shape_boolean_t*)(right->_data.data)) ) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_NUMBER: {
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_NUMBER:
|
||||
{
|
||||
// compare the numbers.
|
||||
if ( *((TRI_shape_number_t*)(left->_data.data)) == *((TRI_shape_number_t*)(right->_data.data)) ) {
|
||||
return 0;
|
||||
}
|
||||
if ( *((TRI_shape_number_t*)(left->_data.data)) < *((TRI_shape_number_t*)(right->_data.data)) ) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
{
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
{
|
||||
// compare strings
|
||||
// extract the strings
|
||||
if (leftType == TRI_SHAPE_SHORT_STRING) {
|
||||
leftString = (char*)(sizeof(TRI_shape_length_short_string_t) + left->_data.data);
|
||||
}
|
||||
else {
|
||||
leftString = (char*)(sizeof(TRI_shape_length_long_string_t) + left->_data.data);
|
||||
}
|
||||
|
||||
if (rightType == TRI_SHAPE_SHORT_STRING) {
|
||||
rightString = (char*)(sizeof(TRI_shape_length_short_string_t) + right->_data.data);
|
||||
}
|
||||
else {
|
||||
rightString = (char*)(sizeof(TRI_shape_length_long_string_t) + right->_data.data);
|
||||
}
|
||||
|
||||
result = strcmp(leftString,rightString);
|
||||
return result;
|
||||
}
|
||||
case TRI_SHAPE_ARRAY:
|
||||
case TRI_SHAPE_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
case TRI_SHAPE_LIST:
|
||||
{
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
case TRI_SHAPE_LIST:
|
||||
{
|
||||
// unfortunately recursion: check the types of all the entries
|
||||
leftListLength = *((TRI_shape_length_list_t*)(left->_data.data));
|
||||
rightListLength = *((TRI_shape_length_list_t*)(right->_data.data));
|
||||
|
||||
// determine the smallest list
|
||||
if (leftListLength > rightListLength) {
|
||||
listLength = rightListLength;
|
||||
}
|
||||
else {
|
||||
listLength = leftListLength;
|
||||
}
|
||||
|
||||
for (j = 0; j < listLength; ++j) {
|
||||
|
||||
if (leftType == TRI_SHAPE_HOMOGENEOUS_LIST) {
|
||||
TRI_AtHomogeneousListShapedJson((const TRI_homogeneous_list_shape_t*)(leftShape),
|
||||
left,j,&leftElement);
|
||||
}
|
||||
else if (leftType == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) {
|
||||
TRI_AtHomogeneousSizedListShapedJson((const TRI_homogeneous_sized_list_shape_t*)(leftShape),
|
||||
left,j,&leftElement);
|
||||
}
|
||||
else {
|
||||
TRI_AtListShapedJson((const TRI_list_shape_t*)(leftShape),left,j,&leftElement);
|
||||
}
|
||||
|
||||
|
||||
if (rightType == TRI_SHAPE_HOMOGENEOUS_LIST) {
|
||||
TRI_AtHomogeneousListShapedJson((const TRI_homogeneous_list_shape_t*)(rightShape),
|
||||
right,j,&rightElement);
|
||||
}
|
||||
else if (rightType == TRI_SHAPE_HOMOGENEOUS_SIZED_LIST) {
|
||||
TRI_AtHomogeneousSizedListShapedJson((const TRI_homogeneous_sized_list_shape_t*)(rightShape),
|
||||
right,j,&rightElement);
|
||||
}
|
||||
else {
|
||||
TRI_AtListShapedJson((const TRI_list_shape_t*)(rightShape),right,j,&rightElement);
|
||||
}
|
||||
|
||||
result = CompareShapeTypes (&leftElement, &rightElement, leftShaper, rightShaper);
|
||||
if (result != 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// up to listLength everything matches
|
||||
if (leftListLength < rightListLength) {
|
||||
return -1;
|
||||
}
|
||||
else if (leftListLength > rightListLength) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case TRI_SHAPE_ARRAY:
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
case TRI_SHAPE_ARRAY:
|
||||
{
|
||||
/* start oreste:
|
||||
char* shape = (char*)(leftShape);
|
||||
uint64_t fixedEntries;
|
||||
uint64_t variableEntries;
|
||||
uint64_t ssid;
|
||||
uint64_t aaid;
|
||||
char* name;
|
||||
TRI_shape_t* newShape;
|
||||
|
||||
shape = shape + sizeof(TRI_shape_t);
|
||||
fixedEntries = *((TRI_shape_size_t*)(shape));
|
||||
shape = shape + sizeof(TRI_shape_size_t);
|
||||
variableEntries = *((TRI_shape_size_t*)(shape));
|
||||
shape = shape + sizeof(TRI_shape_size_t);
|
||||
ssid = *((TRI_shape_sid_t*)(shape));
|
||||
shape = shape + (sizeof(TRI_shape_sid_t) * (fixedEntries + variableEntries));
|
||||
aaid = *((TRI_shape_aid_t*)(shape));
|
||||
shape = shape + (sizeof(TRI_shape_aid_t) * (fixedEntries + variableEntries));
|
||||
|
||||
name = leftShaper->lookupAttributeId(leftShaper,aaid);
|
||||
newShape = leftShaper->lookupShapeId(leftShaper, ssid);
|
||||
|
||||
|
||||
printf("%s:%u:_fixedEntries:%u\n",__FILE__,__LINE__,fixedEntries);
|
||||
printf("%s:%u:_variableEntries:%u\n",__FILE__,__LINE__,variableEntries);
|
||||
printf("%s:%u:_sids[0]:%u\n",__FILE__,__LINE__,ssid);
|
||||
printf("%s:%u:_aids[0]:%u\n",__FILE__,__LINE__,aaid);
|
||||
printf("%s:%u:name:%s\n",__FILE__,__LINE__,name);
|
||||
printf("%s:%u:type:%d\n",__FILE__,__LINE__,newShape->_type);
|
||||
|
||||
end oreste */
|
||||
assert(false);
|
||||
switch (rightType) {
|
||||
case TRI_SHAPE_ILLEGAL:
|
||||
case TRI_SHAPE_NULL:
|
||||
case TRI_SHAPE_BOOLEAN:
|
||||
case TRI_SHAPE_NUMBER:
|
||||
case TRI_SHAPE_SHORT_STRING:
|
||||
case TRI_SHAPE_LONG_STRING:
|
||||
case TRI_SHAPE_HOMOGENEOUS_LIST:
|
||||
case TRI_SHAPE_HOMOGENEOUS_SIZED_LIST:
|
||||
case TRI_SHAPE_LIST:
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
case TRI_SHAPE_ARRAY:
|
||||
{
|
||||
assert(false);
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
} // end of switch (rightType)
|
||||
}
|
||||
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Compare a shapded json object recursively if necessary
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CompareShapedJsonShapedJson (const TRI_shaped_json_t* left, const TRI_shaped_json_t* right, TRI_shaper_t* leftShaper, TRI_shaper_t* rightShaper) {
|
||||
|
||||
int result;
|
||||
|
||||
// ............................................................................
|
||||
// the following order is currently defined for placing an order on documents
|
||||
// undef < null < boolean < number < strings < lists < hash arrays
|
||||
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
|
||||
// within each type class we have the following order
|
||||
// boolean: false < true
|
||||
// number: natural order
|
||||
// strings: lexicographical
|
||||
// lists: lexicorgraphically and within each slot according to these rules.
|
||||
// ............................................................................
|
||||
|
||||
|
||||
if (left == NULL && right == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (left == NULL && right != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (left != NULL && right == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
result = CompareShapeTypes (left, right, leftShaper, rightShaper);
|
||||
|
||||
return result;
|
||||
|
||||
} // end of function CompareShapedJsonShapedJson
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -898,191 +538,6 @@ void SkiplistIndexFree(SkiplistIndex* slIndex) {
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compares two elements in a skip list
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CompareElementElement (struct TRI_skiplist_s* skiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
// .............................................................................
|
||||
// Compare two elements and determines:
|
||||
// left < right : return -1
|
||||
// left == right : return 0
|
||||
// left > right : return 1
|
||||
// .............................................................................
|
||||
int compareResult;
|
||||
SkiplistIndexElement* hLeftElement = (SkiplistIndexElement*)(leftElement);
|
||||
SkiplistIndexElement* hRightElement = (SkiplistIndexElement*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
// ............................................................................
|
||||
// the following order is currently defined for placing an order on documents
|
||||
// undef < null < boolean < number < strings < lists < hash arrays
|
||||
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
|
||||
// within each type class we have the following order
|
||||
// boolean: false < true
|
||||
// number: natural order
|
||||
// strings: lexicographical
|
||||
// lists: lexicorgraphically and within each slot according to these rules.
|
||||
// ............................................................................
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// This call back function is used when we insert and remove unique skip
|
||||
// list entries.
|
||||
// ............................................................................
|
||||
|
||||
if (hLeftElement->numFields != hRightElement->numFields) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// The document could be the same -- so no further comparison is required.
|
||||
// ............................................................................
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < hLeftElement->numFields; j++) {
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// This is where the difference between CompareKeyElement (below) and
|
||||
// CompareElementElement comes into play. Here if the 'keys' are the same,
|
||||
// but the doc ptr is different (which it is since we are here), then
|
||||
// we return what was requested to be returned: 0,-1 or 1. What is returned
|
||||
// depends on the purpose of calling this callback.
|
||||
// ............................................................................
|
||||
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief compares a key and an element
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int CompareKeyElement (struct TRI_skiplist_s* skiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
// .............................................................................
|
||||
// Compare two elements and determines:
|
||||
// left < right : return -1
|
||||
// left == right : return 0
|
||||
// left > right : return 1
|
||||
// .............................................................................
|
||||
int compareResult;
|
||||
size_t numFields;
|
||||
SkiplistIndexElement* hLeftElement = (SkiplistIndexElement*)(leftElement);
|
||||
SkiplistIndexElement* hRightElement = (SkiplistIndexElement*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
// ............................................................................
|
||||
// the following order is currently defined for placing an order on documents
|
||||
// undef < null < boolean < number < strings < lists < hash arrays
|
||||
// note: undefined will be treated as NULL pointer not NULL JSON OBJECT
|
||||
// within each type class we have the following order
|
||||
// boolean: false < true
|
||||
// number: natural order
|
||||
// strings: lexicographical
|
||||
// lists: lexicorgraphically and within each slot according to these rules.
|
||||
// associative array: ordered keys followed by value of key
|
||||
// ............................................................................
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// The document could be the same -- so no further comparison is required.
|
||||
// ............................................................................
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// This call back function is used when we query the index, as such
|
||||
// the number of fields which we are using for the query may be less than
|
||||
// the number of fields that the index is defined with.
|
||||
// ............................................................................
|
||||
|
||||
|
||||
if (hLeftElement->numFields < hRightElement->numFields) {
|
||||
numFields = hLeftElement->numFields;
|
||||
}
|
||||
else {
|
||||
numFields = hRightElement->numFields;
|
||||
}
|
||||
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < numFields; j++) {
|
||||
/*
|
||||
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
|
||||
*((double*)((j + hLeftElement->fields)->_data.data)),
|
||||
*((double*)((j + hRightElement->fields)->_data.data)),
|
||||
(uint64_t)(hLeftElement->data),
|
||||
(uint64_t)(hRightElement->data)
|
||||
);
|
||||
*/
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields),
|
||||
(j + hRightElement->fields),
|
||||
leftShaper,
|
||||
rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
// ............................................................................
|
||||
// The 'keys' match -- however, we may only have a partial match in reality
|
||||
// if not all keys comprising index have been used.
|
||||
// ............................................................................
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -1108,12 +563,16 @@ SkiplistIndex* SkiplistIndex_new() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
TRI_InitSkipList(skiplistIndex->skiplist.uniqueSkiplist,
|
||||
sizeof(SkiplistIndexElement),
|
||||
NULL,NULL,TRI_SKIPLIST_PROB_HALF, 40);
|
||||
/*
|
||||
TRI_InitSkipList(skiplistIndex->skiplist.uniqueSkiplist,
|
||||
sizeof(SkiplistIndexElement),
|
||||
CompareElementElement,
|
||||
CompareKeyElement,
|
||||
TRI_SKIPLIST_PROB_HALF, 40);
|
||||
|
||||
*/
|
||||
return skiplistIndex;
|
||||
}
|
||||
|
||||
|
@ -1503,147 +962,6 @@ bool SkiplistIndex_update(SkiplistIndex* skiplistIndex, const SkiplistIndexEleme
|
|||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief used to determine the order of two elements
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int MultiCompareElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
|
||||
int compareResult;
|
||||
SkiplistIndexElement* hLeftElement = (SkiplistIndexElement*)(leftElement);
|
||||
SkiplistIndexElement* hRightElement = (SkiplistIndexElement*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_GREATER;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_LESS;
|
||||
}
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
|
||||
}
|
||||
|
||||
if (hLeftElement->numFields != hRightElement->numFields) {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return TRI_SKIPLIST_COMPARE_STRICTLY_EQUAL;
|
||||
}
|
||||
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < hLeftElement->numFields; j++) {
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief used to determine the order of two keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static int MultiCompareKeyElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement, int defaultEqual) {
|
||||
|
||||
int compareResult;
|
||||
size_t numFields;
|
||||
SkiplistIndexElement* hLeftElement = (SkiplistIndexElement*)(leftElement);
|
||||
SkiplistIndexElement* hRightElement = (SkiplistIndexElement*)(rightElement);
|
||||
TRI_shaper_t* leftShaper;
|
||||
TRI_shaper_t* rightShaper;
|
||||
size_t j;
|
||||
|
||||
if (leftElement == NULL && rightElement == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (leftElement != NULL && rightElement == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (leftElement == NULL && rightElement != NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// The document could be the same -- so no further comparison is required.
|
||||
// ............................................................................
|
||||
|
||||
if (hLeftElement->data == hRightElement->data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ............................................................................
|
||||
// This call back function is used when we query the index, as such
|
||||
// the number of fields which we are using for the query may be less than
|
||||
// the number of fields that the index is defined with.
|
||||
// ............................................................................
|
||||
|
||||
if (hLeftElement->numFields < hRightElement->numFields) {
|
||||
numFields = hLeftElement->numFields;
|
||||
}
|
||||
else {
|
||||
numFields = hRightElement->numFields;
|
||||
}
|
||||
|
||||
leftShaper = ((TRI_doc_collection_t*)(hLeftElement->collection))->_shaper;
|
||||
rightShaper = ((TRI_doc_collection_t*)(hRightElement->collection))->_shaper;
|
||||
|
||||
for (j = 0; j < numFields; j++) {
|
||||
compareResult = CompareShapedJsonShapedJson((j + hLeftElement->fields), (j + hRightElement->fields), leftShaper, rightShaper);
|
||||
if (compareResult != 0) {
|
||||
return compareResult;
|
||||
}
|
||||
}
|
||||
|
||||
return defaultEqual;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief used to determine the order of two keys
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool MultiEqualElementElement (TRI_skiplist_multi_t* multiSkiplist, void* leftElement, void* rightElement) {
|
||||
|
||||
SkiplistIndexElement* hLeftElement = (SkiplistIndexElement*)(leftElement);
|
||||
SkiplistIndexElement* hRightElement = (SkiplistIndexElement*)(rightElement);
|
||||
|
||||
if (leftElement == rightElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
printf("%s:%u:%f:%f,%u:%u\n",__FILE__,__LINE__,
|
||||
*((double*)((hLeftElement->fields)->_data.data)),
|
||||
*((double*)((hRightElement->fields)->_data.data)),
|
||||
(uint64_t)(hLeftElement->data),
|
||||
(uint64_t)(hRightElement->data)
|
||||
);
|
||||
*/
|
||||
return (hLeftElement->data == hRightElement->data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1675,13 +993,17 @@ SkiplistIndex* MultiSkiplistIndex_new() {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
TRI_InitSkipListMulti(skiplistIndex->skiplist.nonUniqueSkiplist,
|
||||
sizeof(SkiplistIndexElement),
|
||||
NULL, NULL, NULL,TRI_SKIPLIST_PROB_HALF, 40);
|
||||
/*
|
||||
TRI_InitSkipListMulti(skiplistIndex->skiplist.nonUniqueSkiplist,
|
||||
sizeof(SkiplistIndexElement),
|
||||
MultiCompareElementElement,
|
||||
MultiCompareKeyElement,
|
||||
MultiEqualElementElement,
|
||||
TRI_SKIPLIST_PROB_HALF, 40);
|
||||
|
||||
*/
|
||||
return skiplistIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief removes allocated memory
|
||||
/// @brief Creates a new Skiplist operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_sl_operator_t* CreateSLOperator(TRI_sl_operator_type_e operatorType,
|
||||
|
@ -74,8 +74,8 @@ TRI_sl_operator_t* CreateSLOperator(TRI_sl_operator_type_e operatorType,
|
|||
switch (operatorType) {
|
||||
case TRI_SL_AND_OPERATOR:
|
||||
case TRI_SL_NOT_OPERATOR:
|
||||
case TRI_SL_OR_OPERATOR:
|
||||
{
|
||||
case TRI_SL_OR_OPERATOR: {
|
||||
|
||||
newLogicalOperator = (TRI_sl_logical_operator_t*)TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_sl_logical_operator_t), false);
|
||||
|
||||
if (!newLogicalOperator) {
|
||||
|
@ -95,15 +95,14 @@ TRI_sl_operator_t* CreateSLOperator(TRI_sl_operator_type_e operatorType,
|
|||
case TRI_SL_GT_OPERATOR:
|
||||
case TRI_SL_NE_OPERATOR:
|
||||
case TRI_SL_LE_OPERATOR:
|
||||
case TRI_SL_LT_OPERATOR:
|
||||
{
|
||||
case TRI_SL_LT_OPERATOR: {
|
||||
|
||||
newRelationOperator = (TRI_sl_relation_operator_t*)TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_sl_relation_operator_t), false);
|
||||
|
||||
if (!newRelationOperator) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* FIXME: memory allocation might fail */
|
||||
newRelationOperator->_base._type = operatorType;
|
||||
newLogicalOperator->_base._shaper = shaper;
|
||||
newRelationOperator->_parameters = parameters;
|
||||
|
@ -123,6 +122,12 @@ TRI_sl_operator_t* CreateSLOperator(TRI_sl_operator_type_e operatorType,
|
|||
return newOperator;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Destroys and frees any memory associated with a Skiplist operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ClearSLOperator(TRI_sl_operator_t* slOperator) {
|
||||
|
||||
TRI_sl_logical_operator_t* logicalOperator;
|
||||
|
@ -135,44 +140,50 @@ void ClearSLOperator(TRI_sl_operator_t* slOperator) {
|
|||
switch (slOperator->_type) {
|
||||
case TRI_SL_AND_OPERATOR:
|
||||
case TRI_SL_NOT_OPERATOR:
|
||||
case TRI_SL_OR_OPERATOR:
|
||||
{
|
||||
case TRI_SL_OR_OPERATOR: {
|
||||
|
||||
logicalOperator = (TRI_sl_logical_operator_t*)(slOperator);
|
||||
ClearSLOperator(logicalOperator->_left);
|
||||
ClearSLOperator(logicalOperator->_right);
|
||||
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, logicalOperator);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
|
||||
case TRI_SL_EQ_OPERATOR:
|
||||
case TRI_SL_GE_OPERATOR:
|
||||
case TRI_SL_GT_OPERATOR:
|
||||
case TRI_SL_NE_OPERATOR:
|
||||
case TRI_SL_LE_OPERATOR:
|
||||
case TRI_SL_LT_OPERATOR:
|
||||
{
|
||||
case TRI_SL_LT_OPERATOR: {
|
||||
size_t i;
|
||||
|
||||
relationOperator = (TRI_sl_relation_operator_t*)(slOperator);
|
||||
if (relationOperator->_parameters != NULL) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, relationOperator->_parameters);
|
||||
}
|
||||
|
||||
// relationOperator->_fields contains _numFields shapedJson objects
|
||||
for (i = 0; i < relationOperator->_numFields; ++i) {
|
||||
// destroy each individual shapedJson object
|
||||
TRI_shaped_json_t* shaped = relationOperator->_fields + i;
|
||||
TRI_DestroyShapedJson(relationOperator->_base._shaper, shaped);
|
||||
}
|
||||
// free the memory pointer
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, relationOperator->_fields);
|
||||
|
||||
if (relationOperator->_fields != NULL) {
|
||||
// relationOperator->_fields contains _numFields shapedJson objects
|
||||
for (i = 0; i < relationOperator->_numFields; ++i) {
|
||||
// destroy each individual shapedJson object
|
||||
TRI_shaped_json_t* shaped = relationOperator->_fields + i;
|
||||
TRI_DestroyShapedJson(relationOperator->_base._shaper, shaped);
|
||||
}
|
||||
// free the memory pointer
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, relationOperator->_fields);
|
||||
}
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, relationOperator);
|
||||
break;
|
||||
}
|
||||
} // end of switch statement
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Makes a deep copy of a Skiplist operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_sl_operator_t* CopySLOperator(TRI_sl_operator_t* slOperator) {
|
||||
|
||||
|
@ -194,16 +205,19 @@ TRI_sl_operator_t* CopySLOperator(TRI_sl_operator_t* slOperator) {
|
|||
switch (slOperator->_type) {
|
||||
case TRI_SL_AND_OPERATOR:
|
||||
case TRI_SL_NOT_OPERATOR:
|
||||
case TRI_SL_OR_OPERATOR:
|
||||
{
|
||||
oldLogicalOperator = (TRI_sl_logical_operator_t*)(slOperator);
|
||||
newLogicalOperator = (TRI_sl_logical_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_sl_logical_operator_t), false));
|
||||
/* FIXME: memory allocation might fail */
|
||||
newLogicalOperator->_base._type = slOperator->_type;
|
||||
newLogicalOperator->_left = CopySLOperator(oldLogicalOperator->_left);
|
||||
newLogicalOperator->_right = CopySLOperator(oldLogicalOperator->_right);
|
||||
newOperator = &(newLogicalOperator->_base);
|
||||
case TRI_SL_OR_OPERATOR: {
|
||||
|
||||
oldLogicalOperator = (TRI_sl_logical_operator_t*)(slOperator);
|
||||
newLogicalOperator = (TRI_sl_logical_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_sl_logical_operator_t), false));
|
||||
if (newLogicalOperator != NULL) {
|
||||
newLogicalOperator->_base._type = slOperator->_type;
|
||||
newLogicalOperator->_base._shaper = slOperator->_shaper;
|
||||
newLogicalOperator->_left = CopySLOperator(oldLogicalOperator->_left);
|
||||
newLogicalOperator->_right = CopySLOperator(oldLogicalOperator->_right);
|
||||
newOperator = &(newLogicalOperator->_base);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case TRI_SL_EQ_OPERATOR:
|
||||
|
@ -211,26 +225,33 @@ TRI_sl_operator_t* CopySLOperator(TRI_sl_operator_t* slOperator) {
|
|||
case TRI_SL_GT_OPERATOR:
|
||||
case TRI_SL_NE_OPERATOR:
|
||||
case TRI_SL_LE_OPERATOR:
|
||||
case TRI_SL_LT_OPERATOR:
|
||||
{
|
||||
oldRelationOperator = (TRI_sl_relation_operator_t*)(slOperator);
|
||||
newRelationOperator = (TRI_sl_relation_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_sl_relation_operator_t), false));
|
||||
/* FIXME: memory allocation might fail */
|
||||
newRelationOperator->_base._type = slOperator->_type;
|
||||
newRelationOperator->_parameters = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, oldRelationOperator->_parameters);
|
||||
newRelationOperator->_fields = TRI_CopyShapedJson(oldRelationOperator->_base._shaper, oldRelationOperator->_fields);
|
||||
newRelationOperator->_numFields = oldRelationOperator->_numFields;
|
||||
newRelationOperator->_collection = oldRelationOperator->_collection;
|
||||
newOperator = &(newRelationOperator->_base);
|
||||
case TRI_SL_LT_OPERATOR: {
|
||||
|
||||
oldRelationOperator = (TRI_sl_relation_operator_t*)(slOperator);
|
||||
newRelationOperator = (TRI_sl_relation_operator_t*) (TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_sl_relation_operator_t), false));
|
||||
if (newRelationOperator != NULL) {
|
||||
newRelationOperator->_base._type = slOperator->_type;
|
||||
newRelationOperator->_base._shaper = slOperator->_shaper;
|
||||
newRelationOperator->_parameters = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, oldRelationOperator->_parameters);
|
||||
if (newRelationOperator->_fields != NULL) {
|
||||
newRelationOperator->_fields = TRI_CopyShapedJson(newRelationOperator->_base._shaper, oldRelationOperator->_fields);
|
||||
}
|
||||
newRelationOperator->_numFields = oldRelationOperator->_numFields;
|
||||
newRelationOperator->_collection = oldRelationOperator->_collection;
|
||||
newOperator = &(newRelationOperator->_base);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return newOperator;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief a skiplist operator with all its linked sub information
|
||||
/// @brief Destroys and frees any memory associated with a Skiplist operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TRI_FreeSLOperator(TRI_sl_operator_t* slOperator) {
|
||||
|
|
|
@ -975,8 +975,7 @@ static void RunShell (v8::Handle<v8::Context> context) {
|
|||
}
|
||||
|
||||
console->close();
|
||||
|
||||
printf("\n");
|
||||
printf("\nBye Bye! Auf Wiedersehen!\n");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -2403,8 +2403,7 @@ static void FillLookupSLOperator(TRI_sl_operator_t* slOperator, TRI_doc_collecti
|
|||
switch (slOperator->_type) {
|
||||
case TRI_SL_AND_OPERATOR:
|
||||
case TRI_SL_NOT_OPERATOR:
|
||||
case TRI_SL_OR_OPERATOR:
|
||||
{
|
||||
case TRI_SL_OR_OPERATOR: {
|
||||
logicalOperator = (TRI_sl_logical_operator_t*)(slOperator);
|
||||
FillLookupSLOperator(logicalOperator->_left,collection);
|
||||
FillLookupSLOperator(logicalOperator->_right,collection);
|
||||
|
@ -2416,22 +2415,24 @@ static void FillLookupSLOperator(TRI_sl_operator_t* slOperator, TRI_doc_collecti
|
|||
case TRI_SL_GT_OPERATOR:
|
||||
case TRI_SL_NE_OPERATOR:
|
||||
case TRI_SL_LE_OPERATOR:
|
||||
case TRI_SL_LT_OPERATOR:
|
||||
{
|
||||
case TRI_SL_LT_OPERATOR: {
|
||||
relationOperator = (TRI_sl_relation_operator_t*)(slOperator);
|
||||
relationOperator->_numFields = relationOperator->_parameters->_value._objects._length;
|
||||
relationOperator->_fields = TRI_Allocate( TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * relationOperator->_numFields, false);
|
||||
/* TODO FIXME: memory allocation might fail */
|
||||
relationOperator->_collection = collection;
|
||||
|
||||
for (j = 0; j < relationOperator->_numFields; ++j) {
|
||||
jsonObject = (TRI_json_t*) (TRI_AtVector(&(relationOperator->_parameters->_value._objects),j));
|
||||
shapedObject = TRI_ShapedJsonJson(collection->_shaper, jsonObject);
|
||||
if (shapedObject) {
|
||||
relationOperator->_fields[j] = *shapedObject; // shallow copy here is ok
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shapedObject); // don't require storage anymore
|
||||
relationOperator->_fields = TRI_Allocate(TRI_UNKNOWN_MEM_ZONE, sizeof(TRI_shaped_json_t) * relationOperator->_numFields, false);
|
||||
if (relationOperator->_fields != NULL) {
|
||||
for (j = 0; j < relationOperator->_numFields; ++j) {
|
||||
jsonObject = (TRI_json_t*) (TRI_AtVector(&(relationOperator->_parameters->_value._objects),j));
|
||||
shapedObject = TRI_ShapedJsonJson(collection->_shaper, jsonObject);
|
||||
if (shapedObject) {
|
||||
relationOperator->_fields[j] = *shapedObject; // shallow copy here is ok
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, shapedObject); // don't require storage anymore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
relationOperator->_numFields = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9047,7 +9047,7 @@ if test "x$tr_MRUBY" = "xyes"; then
|
|||
MRUBY_LDFLAGS=""
|
||||
MRUBY_LIBS="${srcdir}/3rdParty/mruby/lib/ritevm.a"
|
||||
|
||||
TRI_MRUBY_VERSION="0.0.0"
|
||||
TRI_MRUBY_VERSION="2012-04-27"
|
||||
|
||||
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
|
|
|
@ -15,7 +15,7 @@ if test "x$tr_MRUBY" = "xyes"; then
|
|||
MRUBY_LDFLAGS=""
|
||||
MRUBY_LIBS="${srcdir}/3rdParty/mruby/lib/ritevm.a"
|
||||
|
||||
TRI_MRUBY_VERSION="0.0.0"
|
||||
TRI_MRUBY_VERSION="2012-04-27"
|
||||
|
||||
AC_DEFINE_UNQUOTED(TRI_ENABLE_MRUBY, 1, [true if mruby should be used])
|
||||
fi
|
||||
|
|
Loading…
Reference in New Issue