1
0
Fork 0
Conflicts:
	SkipLists/skiplist.c
	SkipLists/sl-operator.c
	VocBase/index.c
This commit is contained in:
Frank Celler 2012-04-27 15:50:16 +02:00
commit a0306acaf0
28 changed files with 1193 additions and 930 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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)

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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] = '$';

View File

@ -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)

View File

@ -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)

View File

@ -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;
}

View File

@ -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");
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;
}

781
SkipLists/compare.h Executable file
View File

@ -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:

View File

@ -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
// .......................................................................

View File

@ -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;
}

View File

@ -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) {

View File

@ -975,8 +975,7 @@ static void RunShell (v8::Handle<v8::Context> context) {
}
console->close();
printf("\n");
printf("\nBye Bye! Auf Wiedersehen!\n");
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;
}
}

2
configure vendored
View File

@ -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

View File

@ -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