Commit 0cf40db2 authored by Yoni Fogel's avatar Yoni Fogel

Addresses #284

Checkpoint in implementing linear.c

git-svn-id: file:///svn/tokudb@1776 c7de825b-a66e-492c-adef-691d508d4ae1
parent b32ac2cb
# On OSX do: # On OSX do:
# make OSX=OSX # make OSX=OSX
LIBNAMELINEAR=librangetreelinear
LIBNAME=librangetree LIBNAME=librangetree
OPTFLAGS = -O2 OPTFLAGS = #-O2
# GCOV_FLAGS = -fprofile-arcs -ftest-coverage # GCOV_FLAGS = -fprofile-arcs -ftest-coverage
CFLAGS = -W -Wall -Werror -g -fPIC $(OPTFLAGS) $(GCOV_FLAGS) CFLAGS = -W -Wall -Werror -g -fPIC $(OPTFLAGS) $(GCOV_FLAGS)
CPPFLAGS = -I../../include -I../../newbrt CPPFLAGS = -I../../include -I../../newbrt
CPPFLAGS += -D_GNU_SOURCE -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE #CPPFLAGS += -D_GNU_SOURCE -D_THREAD_SAFE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE
ifeq ($(OSX),OSX) ifeq ($(OSX),OSX)
LIBEXT=dylib LIBEXT=dylib
...@@ -20,28 +20,32 @@ SHARED=-shared ...@@ -20,28 +20,32 @@ SHARED=-shared
endif endif
.PHONY: install logformat .PHONY: install logformat
install: $(LIBNAME).$(LIBEXT) $(LIBNAME).a install: $(LIBNAMELINEAR).$(LIBEXT) $(LIBNAMELINEAR).a #$(LIBNAME).$(LIBEXT) $(LIBNAME).a
cp $(LIBNAME).$(LIBEXT) ../../lib/ #cp $(LIBNAME).$(LIBEXT) ../../lib/
cp $(LIBNAME).a ../../lib #cp $(LIBNAME).a ../../lib
cp $(LIBNAMELINEAR).$(LIBEXT) ../../lib/
check: $(LIBNAME).$(LIBEXT) cp $(LIBNAMELINEAR).a ../../lib
python tokuglobals.py $(LIBNAME).$(LIBEXT)
strip: $(LIBNAME).$(LIBEXT)
strip $(LIBNAME).$(LIBEXT)
clean: clean:
rm -rf $(LIBNAMELINEAR).$(LIBEXT) $(LIBNAMELINEAR)
rm -rf $(LIBNAME).$(LIBEXT) $(LIBNAME).a *.o *.gcno *.gcda *.gcov rm -rf $(LIBNAME).$(LIBEXT) $(LIBNAME).a *.o *.gcno *.gcda *.gcov
cd tests;make clean cd tests;make clean
linear.o: rangetree.h linear.o: linear.c rangetree.h
DBBINS = linear.o gcc $(CFLAGS) $(CPPFLAGS) -DTOKU_LINEAR_RANGE_TREE -c $< -o $@
log.o: log.c rangetree.h
gcc $(CFLAGS) $(CPPFLAGS) -DTOKU_LOG_RANGE_TREE -c $< -o $@
$(LIBNAME).$(LIBEXT): log.o
cc $(CPPFLAGS) $< $(SHARED) -o $@ $(CFLAGS) -lz
$(LIBNAME).$(LIBEXT): $(DBBINS) $(LIBNAMELINEAR).$(LIBEXT): linear.o
cc $(CPPFLAGS) $(DBBINS) $(SHARED) -o $@ $(CFLAGS) -lz cc $(CPPFLAGS) $< $(SHARED) -o $@ $(CFLAGS) -lz
$(LIBNAME).a: $(DBBINS) $(LIBNAME).a: log.o
$(AR) rv $@ $(DBBINS) $(AR) rv $@ $<
libdb.a(ydb.o): ydb.o $(LIBNAMELINEAR).a: linear.o
$(AR) rv $@ $<
...@@ -11,33 +11,226 @@ ...@@ -11,33 +11,226 @@
//Currently this is a stub implementation just so we can write and compile tests //Currently this is a stub implementation just so we can write and compile tests
//before actually implementing the range tree. //before actually implementing the range tree.
#include "rangetree.h" #include "rangetree.h"
#include <errno.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define AA __attribute__((__unused__)) #define AA __attribute__((__unused__))
int toku_rt_create(toku_range_tree** a AA,
int (*b)(void*,void*) AA, int (*c)(void*,void*) AA,
BOOL d AA)
{return 0;}
int toku_rt_close(toku_range_tree*a AA) const unsigned minlen = 64;
{return 0;}
int toku_rt_find(toku_range_tree*b AA, toku_range*c AA, unsigned d AA, toku_range**e AA, unsigned*g AA, unsigned*f AA) /*
{return 0;} * Returns:
* 0: Point \in range
* < 0: Point strictly less than the range.
* > 0: Point strictly greater than the range.
*/
static int __toku_rt_p_cmp(toku_range_tree* tree,
void* point, toku_range* range) {
if (tree->end_cmp(point, range->left) < 0) return -1;
if (tree->end_cmp(point, range->right) > 0) return 1;
return 0;
}
static int __toku_rt_decrease_capacity(toku_range_tree* tree, unsigned num AA) {
assert(tree);
//TODO: reclaim capacity.
return 1;
}
static int __toku_rt_increase_capacity(toku_range_tree* tree, unsigned num) {
assert(tree);
if (tree->ranges_len < num) {
unsigned temp_len = tree->ranges_len;
while (temp_len < num) temp_len *= 2;
toku_range* temp_ranges =
realloc(tree->ranges, temp_len * sizeof(toku_range));
if (!temp_ranges) return errno;
tree->ranges = temp_ranges;
tree->ranges_len = temp_len;
}
return 0;
}
static int __toku_increase_buffer(toku_range** buf, unsigned* buflen,
unsigned num) {
assert(buf);
assert(buflen);
if (*buflen < num) {
unsigned temp_len = *buflen;
while (temp_len < num) temp_len *= 2;
toku_range* temp_buf = realloc(*buf, temp_len * sizeof(toku_range));
if (!temp_buf) return errno;
*buf = temp_buf;
*buflen = temp_len;
}
return 0;
}
static BOOL __toku_rt_overlap(toku_range_tree* tree,
toku_range* a, toku_range* b) {
assert(tree);
assert(a);
assert(b);
//a->left <= b->right && b->left <= a->right
return (tree->end_cmp(a->left, b->right) <= 0 &&
tree->end_cmp(b->left, a->right) <= 0);
}
BOOL __toku_rt_exact(toku_range_tree* tree,
toku_range* a, toku_range* b) {
assert(tree);
assert(a);
// assert(a->left);
// assert(a->right);
assert(b);
// assert(b->left);
// assert(b->right);
return (tree->end_cmp (a->left, b->left) == 0 &&
tree->end_cmp (a->right, b->right) == 0 &&
tree->data_cmp(a->data, b->data) == 0);
}
int toku_rt_create(toku_range_tree** ptree,
int (*end_cmp)(void*,void*), int (*data_cmp)(void*,void*),
BOOL allow_overlaps) {
int r;
toku_range_tree* temptree;
if (!ptree || !end_cmp || !data_cmp) return EINVAL;
temptree = (toku_range_tree*)malloc(sizeof(toku_range_tree));
if (0) {
died1:
free(temptree);
return r;
}
if (!temptree) return errno;
//Any initializers go here.
memset(temptree, 0, sizeof(*temptree));
temptree->end_cmp = end_cmp;
temptree->data_cmp = data_cmp;
temptree->allow_overlaps = allow_overlaps;
temptree->ranges_len = minlen;
temptree->ranges = (toku_range*)
malloc(temptree->ranges_len * sizeof(toku_range));
if (!temptree->ranges) {
r = errno;
goto died1;
}
*ptree = temptree;
return 0;
}
int toku_rt_close(toku_range_tree* tree) {
if (!tree) return EINVAL;
free(tree->ranges);
free(tree);
return 0;
}
int toku_rt_find(toku_range_tree* tree, toku_range* query, unsigned k,
toku_range** buf, unsigned* buflen, unsigned* numfound) {
if (!tree || !query || !buf || !buflen || !numfound) return EINVAL;
if (query->data != NULL) return EINVAL;
if (*buflen == 0) return EINVAL;
unsigned temp_numfound = 0;
int r;
unsigned i;
for (i = 0; i < tree->numelements; i++) {
if (__toku_rt_overlap(tree, query, &tree->ranges[i])) {
r = __toku_increase_buffer(buf, buflen, temp_numfound + 1);
if (r != 0) return r;
(*buf)[temp_numfound++] = tree->ranges[i];
//k == 0 means limit of infinity, this is not a bug.
if (temp_numfound == k) break;
}
}
*numfound = temp_numfound;
return 0;
}
int toku_rt_insert(toku_range_tree* tree, toku_range* range) {
if (!tree || !range) return EINVAL;
unsigned i;
int r;
//EDOM cases
if (tree->allow_overlaps) {
for (i = 0; i < tree->numelements; i++) {
if (__toku_rt_exact (tree, range, &tree->ranges[i])) return EDOM;
}
}
else {
for (i = 0; i < tree->numelements; i++) {
if (__toku_rt_overlap(tree, range, &tree->ranges[i]) ||
__toku_rt_overlap(tree, &tree->ranges[i], range)) return EDOM;
}
}
r = __toku_rt_increase_capacity(tree, tree->numelements + 1);
if (r != 0) return r;
tree->ranges[++tree->numelements] = *range;
return 0;
}
int toku_rt_delete(toku_range_tree* tree, toku_range* range) {
if (!tree || !range) return EINVAL;
unsigned i;
for (i = 0;
i < tree->numelements &&
!__toku_rt_exact(tree, range, &(tree->ranges[i]));
i++) {}
//EDOM case: Not Found
if (i == tree->numelements) return EDOM;
if (i < tree->numelements - 1) {
//juggle
}
__toku_rt_decrease_capacity(tree, --tree->numelements);
return 0;
}
int toku_rt_predecessor (toku_range_tree* tree, void* point, toku_range* pred,
BOOL* wasfound) {
if (!tree || !point || !pred || !wasfound) return EINVAL;
if (tree->allow_overlaps) return EINVAL;
toku_range* best = NULL;
unsigned i;
for (i = 0; i < tree->numelements; i++) {
if (__toku_rt_p_cmp(tree, point, &tree->ranges[i]) > 0 &&
(!best || tree->end_cmp(best->left, tree->ranges[i].left) < 0)) {
best = &tree->ranges[i];
}
}
*wasfound = best != NULL;
pred = best;
return 0;
}
int toku_rt_insert(toku_range_tree*a AA, toku_range*v AA) int toku_rt_successor (toku_range_tree* tree, void* point, toku_range* succ,
{return 0;} BOOL* wasfound) {
int toku_rt_delete(toku_range_tree*c AA, toku_range*q AA) if (!tree || !point || !succ || !wasfound) return EINVAL;
{return 0;} if (tree->allow_overlaps) return EINVAL;
toku_range* best = NULL;
unsigned i;
int toku_rt_predecessor (toku_range_tree*f AA, void*g AA, toku_range*q AA, BOOL* v AA) for (i = 0; i < tree->numelements; i++) {
{return 0;} if (__toku_rt_p_cmp(tree, point, &tree->ranges[i]) < 0 &&
int toku_rt_successor (toku_range_tree*e AA, void*c AA, toku_range*a AA, BOOL* q AA) (!best || tree->end_cmp(best->left, tree->ranges[i].left) > 0)) {
{return 0;} best = &tree->ranges[i];
}
}
*wasfound = best != NULL;
succ = best;
return 0;
}
/* /*
\marginpar{ \marginpar{add more \\marginpar\'s}
static int __toku_lt_infinity;
static int __toku_lt_neg_infinity;
extern void* toku_lt_infinity = &__toku_lt_infinity;
extern void* toku_lt_neg_infinity = &__toku_lt_infinity;}
*/ */
...@@ -10,21 +10,35 @@ ...@@ -10,21 +10,35 @@
#include <brttypes.h> #include <brttypes.h>
/** Represents a range of data with an extra value.
/** Represents a range of data with an extra value. */ * Parameters are never modified on failure with the exception of
* buf and buflen.
*/
typedef struct { typedef struct {
void* left; void* left;
void* right; void* right;
void* data; void* data;
} toku_range; } toku_range;
/** Structure is not yet defined, this is so we can write and compile tests
before implementation.
Will be defined during implementation,
and will actually be defined in a separate headers (one for linear version
and one for binary search tree based version). */
struct __toku_range_tree_internal { struct __toku_range_tree_internal {
int dummy; //Shared fields:
int (*end_cmp)(void*,void*);
int (*data_cmp)(void*,void*);
BOOL allow_overlaps;
unsigned numelements;
#if defined(TOKU_LINEAR_RANGE_TREE)
#if defined(TOKU_LOG_RANGE_TREE)
#error Choose just one range tree type.
#endif
//Linear version only fields:
toku_range* ranges;
unsigned ranges_len;
#elif defined(TOKU_LOG_RANGE_TREE)
#error Not defined yet.
//Log version only fields:
#else
#error Using an undefined RANGE TREE TYPE.
#endif
}; };
/* These lines will remain. */ /* These lines will remain. */
...@@ -68,7 +82,7 @@ int toku_rt_close(toku_range_tree* tree); ...@@ -68,7 +82,7 @@ int toku_rt_close(toku_range_tree* tree);
* k: The maximum number of ranges to return. * k: The maximum number of ranges to return.
* The special value '0' is used to request ALL overlapping * The special value '0' is used to request ALL overlapping
* ranges. * ranges.
* range: The range to query. * query: The range to query.
* range.data must be NULL. * range.data must be NULL.
* buf: A pointer to the buffer used to return ranges. * buf: A pointer to the buffer used to return ranges.
* The buffer will be increased using realloc(3) if * The buffer will be increased using realloc(3) if
...@@ -88,8 +102,11 @@ int toku_rt_close(toku_range_tree* tree); ...@@ -88,8 +102,11 @@ int toku_rt_close(toku_range_tree* tree);
* If range.data != NULL. * If range.data != NULL.
* If buflen == 0. * If buflen == 0.
* Other exit codes may be forwarded from underlying system calls. * Other exit codes may be forwarded from underlying system calls.
* It may be useful in the future to add an extra out parameter to specify
* whether more elements exist in the tree that overlap (in excess of the
* requested limit of k).
*/ */
int toku_rt_find(toku_range_tree* tree, toku_range* range, unsigned k, int toku_rt_find(toku_range_tree* tree, toku_range* query, unsigned k,
toku_range** buf, unsigned* buflen, unsigned* numfound); toku_range** buf, unsigned* buflen, unsigned* numfound);
/** /**
......
...@@ -10,56 +10,50 @@ ifeq ($(OSX),OSX) ...@@ -10,56 +10,50 @@ ifeq ($(OSX),OSX)
#Note: OSX 10.4 needs DYLD_LIBRARY_PATH. OSX 10.5 claims to support -rpath. #Note: OSX 10.4 needs DYLD_LIBRARY_PATH. OSX 10.5 claims to support -rpath.
LIBEXT=dylib LIBEXT=dylib
VGRIND= VGRIND=
TDB_LOADLIBES = -L../ -lrangetree CPPFLAGS =
SETTOKUENV=export DYLD_LIBRARY_PATH=.. ; SETENV=export DYLD_LIBRARY_PATH=.. ;
UNSETTOKUENV=unset DYLD_LIBRARY_PATH ;
else else
SETTOKUENV= SETTOKUENV=
UNSETTOKUENV= UNSETTOKUENV=
LIBEXT=so LIBEXT=so
TDB_LOADLIBES = -L../ -lrangetree -Wl,-rpath,.. -lpthread CPPFLAGS = -Wl,-rpath,..
VGRIND=valgrind --quiet --error-exitcode=1 --leak-check=yes VGRIND=valgrind --quiet --error-exitcode=1 --leak-check=yes
endif endif
LIBNAME=librt.$(LIBEXT) LIBNAME=librt.$(LIBEXT)
# GCOV_FLAGS = -fprofile-arcs -ftest-coverage # GCOV_FLAGS = -fprofile-arcs -ftest-coverage
CFLAGS = -Wall -Werror $(OPTFLAGS) -g $(GCOV_FLAGS) CFLAGS = -Wall -Werror $(OPTFLAGS) -g $(GCOV_FLAGS)
TDB_CPPFLAGS = -I../ -I../../../newbrt CPPFLAGS += -L../ -I../ -I../../../newbrt -lpthread
SRCS = $(wildcard *.c) SRCS = $(wildcard *.c)
TDB_TESTS = $(patsubst %.c,%.tdb,$(SRCS)) LOG_TESTS = $(patsubst %.c,%.log,$(SRCS))
BDB_TESTS = $(patsubst %.c,%.bdb,$(SRCS)) LIN_TESTS = $(patsubst %.c,%.lin,$(SRCS))
LINEAR_TESTS = $(patsubst %.c,%.bdb,$(SRCS))
ALL_TESTS = $(TDB_TESTS) #$(BDB_TESTS) ALL_TESTS = $(LOG_TESTS) $(LIN_TESTS)
RUN_TDB_TESTS = $(patsubst %.tdb,%.tdbrun,$(TDB_TESTS)) RUN_LOG_TESTS = $(patsubst %.log,%.logrun,$(LOG_TESTS))
RUN_BDB_TESTS = $(patsubst %.bdb,%.bdbrun,$(BDB_TESTS)) RUN_LIN_TESTS = $(patsubst %.lin,%.linrun,$(LIN_TESTS))
RUN_ALL_TESTS = $(RUN_TDB_TESTS) $(RUN_BDB_TESTS) RUN_ALL_TESTS = $(RUN_LOG_TESTS) $(RUN_LIN_TESTS)
all: make_libs $(ALL_TESTS) all: make_libs $(ALL_TESTS)
foo: .PHONY: check check.lin check.log tests.lin tests.log
echo RUN_TDB_TESTS: $(RUN_TDB_TESTS) check: check.lin check.log
echo ALL_TESTS: $(ALL_TESTS)
.PHONY: check check.bdb check.tdb
check: check.bdb check.tdb all.recover test_db_assoc3.tdbrun_wasbad
@ echo ok @ echo ok
tests.bdb: $(BDB_TESTS) tests.lin: make_libs $(LIN_TESTS)
check.bdb: $(RUN_BDB_TESTS) check.lin: make_libs $(RUN_LIN_TESTS)
tests.tdb: $(TDB_TESTS) tests.log: make_libs $(LOG_TESTS)
check.tdb: $(RUN_TDB_TESTS) check.log: make_libs $(RUN_LOG_TESTS)
# Need these rule so that Make knows about all the file names # Need these rule so that Make knows about all the file names
.PHONY: %.bdbrun %.tdbrun %.run .PHONY: %.linrun %.logrun %.run
$(RUN_ALL_TESTS): $(RUN_ALL_TESTS):
$(ALL_TESTS): $(ALL_TESTS):
%.run: %.bdbrun %.tdbrun %.run: %.linrun %.logrun
@ echo ok @ echo ok
ifeq ($(VERBOSE),2) ifeq ($(VERBOSE),2)
...@@ -79,94 +73,24 @@ else ...@@ -79,94 +73,24 @@ else
endif endif
# The @ sign makes the make quiet. If there is an error there is enough info to tell what test failed. # The @ sign makes the make quiet. If there is an error there is enough info to tell what test failed.
%.bdbrun: %.bdb %.linrun: %.lin
$(MAYBEATSIGN) $(UNSETTOKUENV) $(VGRIND) $(BDB_SUPPRESSIONS) ./$< $(VERBVERBOSE) $(MAYBEATSIGN) $(SETENV) $(VGRIND) ./$< $(VERBVERBOSE)
%.tdbrun: %.tdb %.logrun: %.log
$(MAYBEATSIGN) $(SETTOKUENV) $(VGRIND) ./$< $(VERBVERBOSE) $(MAYBEATSIGN) $(SETENV) $(VGRIND) ./$< $(VERBVERBOSE)
# For a few of the tests bdb is making valgrind unhappy.
FOO_NO_VGRIND = \
db_already_exists \
db_curs2 \
db_dbt_appmalloc \
db_dbt_mem_behavior \
db_dup \
db_env_open_nocreate \
db_env_open_open_close \
db_open_notexist_reopen \
db_remove_subdb \
db_subdb \
dup_delete \
dup_flags \
dup_insert \
dup_search \
kv_limits \
log4 \
rand_insert \
reverse_compare_fun \
# Comment to terminate list so the previous line can end with a slash
NO_VGRIND = \
db_dbt_appmalloc \
db_dbt_mem_behavior \
db_assoc3 \
db_curs2 \
db_delete \
db_env_open_nocreate \
db_env_open_open_close \
db_open_notexist_reopen \
db_remove_subdb \
log4 \
log5 \
# Comment to terminate list so the previous line can end with a slash
$(patsubst %,test_%.bdbrun,$(NO_VGRIND)): VGRIND=
$(patsubst %,test_%.bdbrun,$(NO_VGRIND)): BDB_SUPPRESSIONS=
libs: libs:
cd ..;make cd ..;make
%.bdb: %.c ../rangetree.h test.h %.lin: %.c ../rangetree.h test.h
$(UNSETTOKUENV) cc -DDIR=\"dir.$<.bdb\" $(BDB_CPPFLAGS) -DUSE_BDB -DIS_TDB=0 $(CFLAGS) $< $(BDB_LDFLAGS) -lrangetree -o $@ $(SETENV) cc -DDIR=\"dir.$<.lin\" -DTOKU_LINEAR_RANGE_TREE $(CPPFLAGS) $(CFLAGS) $< -lrangetreelinear -o $@
%.tdb: %.c ../rangetree.h test.h %.log: %.c ../rangetree.h test.h
$(SETTOKUENV) cc -DDIR=\"dir.$<.tdb\" -DUSE_TDB -DIS_TDB=1 $(CFLAGS) $(TDB_CPPFLAGS) $(TDB_LOADLIBES) $< -o $@ $(SETENV) cc -DDIR=\"dir.$<.log\" -DTOKU_LOG_RANGE_TREE $(CPPFLAGS) $(CFLAGS) $< -lrangetree -o $@
.PHONY: %.recover .PHONY: make_libs
all.recover: test_log2.recover test_log3.recover test_log4.recover test_log5.recover
%.recover: %.tdb
$(MAYBEATSIGN) cd ..;make $(VERBQUIET)
$(MAYBEATSIGN) $(VGRIND) ./$<
$(MAYBEATSIGN) rm -rf dir.$(patsubst %.tdb,%.c.tdb,$<).recover
$(MAYBEATSIGN) mkdir dir.$(patsubst %.tdb,%.c.tdb,$<).recover
$(MAYBEATSIGN) cd dir.$(patsubst %.tdb,%.c.tdb,$<).recover;$(VGRIND) ../../../newbrt/recover ../dir.$(patsubst %.tdb,%.c.tdb,$<)
$(MAYBEATSIGN) diff dir.$(patsubst %.tdb,%.c.tdb,$<) dir.$(patsubst %.tdb,%.c.tdb,$<).recover/foo.db
make_libs: make_libs:
cd ..;make cd ..;make
clean: clean:
rm -f $(ALL_TESTS) *.o *.gcno *.gcda *.gcov rm -f $(ALL_TESTS) *.o *.gcno *.gcda *.gcov
rm -rf dir.*.tdb dir.*.bdb rm -rf dir.*.log dir.*.LIN
test_db_curs4.tdb: trace.h
test_db_curs4.bdb: trace.h
test_db_assoc3.tdb test_db_assoc3.bdb: test.h
# This one failed in both BDB and TokuDB, in the same way. It was a program error. Now it works
test_db_assoc3.tdbrun_wasbad: test_db_assoc3.tdb
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200 --more
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200 --more
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200 --more
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200 --more
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200 --more
$(MAYBEATSIGN) ./test_db_assoc3.tdb --seed=1 --count=200 --more
test_db_assoc3.tdbrun: test_db_assoc3.tdb
$(MAYBEATSIGN) $(VGRIND) ./test_db_assoc3.tdb --seed=2 --count=100000 $(VERBVERBOSE)
$(MAYBEATSIGN) $(VGRIND) ./test_db_assoc3.tdb --seed=2 --count=100000 --more $(VERBVERBOSE)
test_db_assoc3.bdbrun: test_db_assoc3.bdb
$(MAYBEATSIGN) $(VGRIND) ./test_db_assoc3.bdb --seed=2 --count=100000 $(VERBVERBOSE)
$(MAYBEATSIGN) $(VGRIND) ./test_db_assoc3.bdb --seed=2 --count=100000 --more $(VERBVERBOSE)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment