CPPFLAGS = @MYCPPFLAGS@ \
-D_TC_PREFIX="\"$(prefix)\"" -D_TC_INCLUDEDIR="\"$(INCLUDEDIR)\"" \
-D_TC_LIBDIR="\"$(LIBDIR)\"" -D_TC_BINDIR="\"$(BINDIR)\"" -D_TC_LIBEXECDIR="\"$(LIBEXECDIR)\"" \
- -D_TC_APPINC="\"-I$(INCLUDEDIR)\"" -D_TC_APPLIBS="\"-L$(LIBDIR) -ltcejdb @LIBS@\""
+ -D_TC_APPINC="\"-I$(INCLUDEDIR)\"" -D_TC_APPLIBS="\"-L$(LIBDIR) @LIBS@\""
CFLAGS = @MYCFLAGS@
LDFLAGS = @MYLDFLAGS@
CMDLDFLAGS = @MYCMDLDFLAGS@
$(RUNENV) $(RUNCMD) ./tchmgr get casket four > check.out
$(RUNENV) $(RUNCMD) ./tchmgr get casket five > check.out
$(RUNENV) $(RUNCMD) ./tchmgr list -pv casket > check.out
- rm -rf casket*
+# rm -rf casket*
check-bdb :
libtcejdb.dylib : libtcejdb.$(LIBVER).$(LIBREV).0.dylib
ln -f -s libtcejdb.$(LIBVER).$(LIBREV).0.dylib $@
+tcejdb.dll : $(LIBOBJFILES)
+ $(CC) $(CFLAGS) -shared -Wl,--subsystem,windows -o $@ \
+ $(LIBOBJFILES) $(LDFLAGS) $(LIBS)
tcutest : tcutest.o $(LIBRARYFILES)
$(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(CMDLDFLAGS) -ltcejdb $(LIBS)
tcawmgr.cgi : tcawmgr.o $(LIBRARYFILES)
$(LDENV) $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) $(CMDLDFLAGS) -ltcejdb $(LIBS)
+myconf.o : basedefs.h myconf.h
-myconf.o : myconf.h
-
-tcutil.o : myconf.h tcutil.h md5.h
+tcutil.o : basedefs.h myconf.h tcutil.h md5.h
-tchdb.o : myconf.h tcutil.h tchdb.h
+tchdb.o : basedefs.h myconf.h tcutil.h tchdb.h
-tcbdb.o : myconf.h tcutil.h tchdb.h tcbdb.h
+tcbdb.o : basedefs.h myconf.h tcutil.h tchdb.h tcbdb.h
-tcfdb.o : myconf.h tcutil.h tcfdb.h
+tcfdb.o : basedefs.h myconf.h tcutil.h tcfdb.h
-tctdb.o : myconf.h tcutil.h tchdb.h tctdb.h
+tctdb.o : basedefs.h myconf.h tcutil.h tchdb.h tctdb.h
-tcadb.o : myconf.h tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h
+tcadb.o : basedefs.h myconf.h tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h
-tcutest.o tcucodec.o : myconf.h tcutil.h
+tcutest.o tcucodec.o : basedefs.h myconf.h tcutil.h
-tchtest.o tchmttest.o tchmgr.o : myconf.h tcutil.h tchdb.h
+tchtest.o tchmttest.o tchmgr.o : basedefs.h myconf.h tcutil.h tchdb.h
-tcbtest.o tcbmttest.o tcbmgr.o : myconf.h tcutil.h tchdb.h tcbdb.h
+tcbtest.o tcbmttest.o tcbmgr.o : basedefs.h myconf.h tcutil.h tchdb.h tcbdb.h
-tcftest.o tcfmttest.o tcfmgr.o : myconf.h tcutil.h tcfdb.h
+tcftest.o tcfmttest.o tcfmgr.o : basedefs.h myconf.h tcutil.h tcfdb.h
-tcttest.o tctmttest.o tctmgr.o : myconf.h tcutil.h tchdb.h tcbdb.h tctdb.h
+tcttest.o tctmttest.o tctmgr.o : basedefs.h myconf.h tcutil.h tchdb.h tcbdb.h tctdb.h
tcatest.o tcamttest.o tcamgr.o tcawmgr.o : \
- myconf.h tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h
+ basedefs.h myconf.h tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h
-ejdb.o : myconf.h ejdb.h ejdb_private.h ejdbutl.h
+ejdb.o : basedefs.h myconf.h ejdb.h ejdb_private.h ejdbutl.h
-bson.o : myconf.h bson.h
+bson.o : basedefs.h myconf.h bson.h
-ejdbutl.o : ejdbutl.h
+ejdbutl.o : basedefs.h tcutil.h ejdbutl.h
utf8proc.o: utf8proc.h utf8proc.c utf8proc_data.c
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o utf8proc.o utf8proc.c
tokyocabinet_all.o : myconf.h tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h
-
+platform.o : basedefs.h platform.c
# END OF FILE
--- /dev/null
+/*
+ * File: basic.h
+ * Author: adam
+ *
+ * Created on April 1, 2013, 6:21 PM
+ */
+
+#ifndef BASIC_H
+#define BASIC_H
+
+#ifdef __cplusplus
+#define EJDB_EXTERN_C_START extern "C" {
+#define EJDB_EXTERN_C_END }
+#else
+#define EJDB_EXTERN_C_START
+#define EJDB_EXTERN_C_END
+#endif
+
+EJDB_EXTERN_C_START
+
+#ifdef __GNUC__
+#define EJDB_INLINE static inline
+#else
+#define EJDB_INLINE static
+#endif
+
+#ifdef _WIN32
+#ifdef EJDB_DLL
+#define EJDB_EXPORT __declspec(dllexport)
+#elif !defined(EJDB_STATIC)
+#define EJDB_EXPORT __declspec(dllimport)
+#else
+#define EJDB_EXPORT
+#endif
+#else
+#define EJDB_EXPORT
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#define INVALIDHANDLE(_HNDL) (((_HNDL) == INVALID_HANDLE_VALUE) || (_HNDL) == NULL)
+#else
+typedef int HANDLE;
+#define INVALID_HANDLE_VALUE (-1)
+#define INVALIDHANDLE(_HNDL) ((_HNDL) < 0 || (_HNDL) == UINT16_MAX)
+#endif
+
+
+#define JDBIDKEYNAME "_id" /**> Name of PK _id field in BSONs */
+#define JDBIDKEYNAMEL 3
+
+EJDB_EXTERN_C_END
+#endif /* BASIC_H */
+
#include "encoding.h"
#include "myconf.h"
+#ifdef _MYBIGEND
+#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) )
+#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) )
+#define bson_big_endian64(out, in) ( memcpy(out, in, 8) )
+#define bson_big_endian32(out, in) ( memcpy(out, in, 4) )
+#else
+#define bson_little_endian64(out, in) ( memcpy(out, in, 8) )
+#define bson_little_endian32(out, in) ( memcpy(out, in, 4) )
+#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) )
+#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) )
+#endif
+
const int initialBufferSize = 128;
+#ifndef MIN
#define MIN(a,b) (((a)<(b))?(a):(b))
+#endif
+#ifndef MAX
#define MAX(a,b) (((a)>(b))?(a):(b))
+#endif
/* only need one of these */
static const int zero = 0;
void *(*bson_malloc_func)(size_t) = MYMALLOC;
void *(*bson_realloc_func)(void *, size_t) = MYREALLOC;
void ( *bson_free_func)(void *) = MYFREE;
-#ifdef R_SAFETY_NET
-bson_printf_func bson_printf;
-#else
-bson_printf_func bson_printf = printf;
-#endif
-bson_fprintf_func bson_fprintf = fprintf;
-bson_sprintf_func bson_sprintf = sprintf;
static int _bson_errprintf(const char *, ...);
bson_printf_func bson_errprintf = _bson_errprintf;
static int ( *oid_inc_func)(void) = NULL;
-EJDB_EXPORT const char* bson_first_errormsg(bson *bson) {
+ const char* bson_first_errormsg(bson *bson) {
if (bson->errstr) {
return bson->errstr;
}
}
-EJDB_EXPORT void bson_reset(bson *b) {
+ void bson_reset(bson *b) {
b->finished = 0;
b->stackPos = 0;
b->err = 0;
READING
------------------------------ */
-EJDB_EXPORT bson* bson_create(void) {
+ bson* bson_create(void) {
return (bson*) bson_malloc(sizeof (bson));
}
-EJDB_EXPORT void bson_dispose(bson* b) {
+ void bson_dispose(bson* b) {
bson_free(b);
}
-EJDB_EXPORT bson *bson_empty(bson *obj) {
+ bson *bson_empty(bson *obj) {
static char *data = "\005\0\0\0\0";
bson_init_data(obj, data);
obj->finished = 1;
return obj;
}
-EJDB_EXPORT int bson_copy(bson *out, const bson *in) {
+ int bson_copy(bson *out, const bson *in) {
if (!out || !in) return BSON_ERROR;
if (!in->finished) return BSON_ERROR;
bson_init_size(out, bson_size(in));
return BSON_OK;
}
-EJDB_EXPORT int bson_init_finished_data(bson *b, const char *data) {
+ int bson_init_finished_data(bson *b, const char *data) {
bson_init_data(b, (char*) data);
bson_reset(b);
b->finished = 1;
return BSON_OK;
}
-EJDB_EXPORT int bson_size(const bson *b) {
+ int bson_size(const bson *b) {
int i;
if (!b || !b->data)
return 0;
return i;
}
-EJDB_EXPORT int bson_size2(const void *bsdata) {
+ int bson_size2(const void *bsdata) {
int i;
if (!bsdata)
return 0;
return i;
}
-EJDB_EXPORT int bson_buffer_size(const bson *b) {
+ int bson_buffer_size(const bson *b) {
return (b->cur - b->data + 1);
}
-EJDB_EXPORT const char *bson_data(const bson *b) {
+ const char *bson_data(const bson *b) {
return (const char *) b->data;
}
return 0x0;
}
-EJDB_EXPORT void bson_oid_from_string(bson_oid_t *oid, const char *str) {
+ void bson_oid_from_string(bson_oid_t *oid, const char *str) {
int i;
for (i = 0; i < 12; i++) {
oid->bytes[i] = (hexbyte(str[2 * i]) << 4) | hexbyte(str[2 * i + 1]);
}
}
-EJDB_EXPORT void bson_oid_to_string(const bson_oid_t *oid, char *str) {
+ void bson_oid_to_string(const bson_oid_t *oid, char *str) {
static const char hex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
int i;
for (i = 0; i < 12; i++) {
str[24] = '\0';
}
-EJDB_EXPORT void bson_set_oid_fuzz(int ( *func)(void)) {
+ void bson_set_oid_fuzz(int ( *func)(void)) {
oid_fuzz_func = func;
}
-EJDB_EXPORT void bson_set_oid_inc(int ( *func)(void)) {
+ void bson_set_oid_inc(int ( *func)(void)) {
oid_inc_func = func;
}
-EJDB_EXPORT void bson_oid_gen(bson_oid_t *oid) {
+ void bson_oid_gen(bson_oid_t *oid) {
static int incr = 0;
static int fuzz = 0;
int i;
bson_big_endian32(&oid->ints[2], &i);
}
-EJDB_EXPORT time_t bson_oid_generated_time(bson_oid_t *oid) {
+ time_t bson_oid_generated_time(bson_oid_t *oid) {
time_t out;
bson_big_endian32(&out, &oid->ints[0]);
return out;
}
-EJDB_EXPORT void bson_print(FILE *f, const bson *b) {
+ void bson_print(FILE *f, const bson *b) {
bson_print_raw(f, b->data, 0);
}
-EJDB_EXPORT void bson_print_raw(FILE *f, const char *data, int depth) {
+ void bson_print_raw(FILE *f, const char *data, int depth) {
bson_iterator i;
const char *key;
int temp;
key = bson_iterator_key(&i);
for (temp = 0; temp <= depth; temp++)
- bson_fprintf(f, "\t");
- bson_fprintf(f, "%s : %d \t ", key, t);
+ fprintf(f, "\t");
+ fprintf(f, "%s : %d \t ", key, t);
switch (t) {
case BSON_DOUBLE:
- bson_fprintf(f, "%f", bson_iterator_double(&i));
+ fprintf(f, "%f", bson_iterator_double(&i));
break;
case BSON_STRING:
- bson_fprintf(f, "%s", bson_iterator_string(&i));
+ fprintf(f, "%s", bson_iterator_string(&i));
break;
case BSON_SYMBOL:
- bson_fprintf(f, "SYMBOL: %s", bson_iterator_string(&i));
+ fprintf(f, "SYMBOL: %s", bson_iterator_string(&i));
break;
case BSON_OID:
bson_oid_to_string(bson_iterator_oid(&i), oidhex);
- bson_fprintf(f, "%s", oidhex);
+ fprintf(f, "%s", oidhex);
break;
case BSON_BOOL:
- bson_fprintf(f, "%s", bson_iterator_bool(&i) ? "true" : "false");
+ fprintf(f, "%s", bson_iterator_bool(&i) ? "true" : "false");
break;
case BSON_DATE:
- bson_fprintf(f, "%ld", (long int) bson_iterator_date(&i));
+ fprintf(f, "%ld", (long int) bson_iterator_date(&i));
break;
case BSON_BINDATA:
- bson_fprintf(f, "BSON_BINDATA");
+ fprintf(f, "BSON_BINDATA");
break;
case BSON_UNDEFINED:
- bson_fprintf(f, "BSON_UNDEFINED");
+ fprintf(f, "BSON_UNDEFINED");
break;
case BSON_NULL:
- bson_fprintf(f, "BSON_NULL");
+ fprintf(f, "BSON_NULL");
break;
case BSON_REGEX:
- bson_fprintf(f, "BSON_REGEX: %s", bson_iterator_regex(&i));
+ fprintf(f, "BSON_REGEX: %s", bson_iterator_regex(&i));
break;
case BSON_CODE:
- bson_fprintf(f, "BSON_CODE: %s", bson_iterator_code(&i));
+ fprintf(f, "BSON_CODE: %s", bson_iterator_code(&i));
break;
case BSON_CODEWSCOPE:
- bson_fprintf(f, "BSON_CODE_W_SCOPE: %s", bson_iterator_code(&i));
+ fprintf(f, "BSON_CODE_W_SCOPE: %s", bson_iterator_code(&i));
/* bson_init( &scope ); */ /* review - stepped on by bson_iterator_code_scope? */
bson_iterator_code_scope(&i, &scope);
- bson_fprintf(f, "\n\t SCOPE: ");
+ fprintf(f, "\n\t SCOPE: ");
bson_print(f, &scope);
/* bson_destroy( &scope ); */ /* review - causes free error */
break;
case BSON_INT:
- bson_fprintf(f, "%d", bson_iterator_int(&i));
+ fprintf(f, "%d", bson_iterator_int(&i));
break;
case BSON_LONG:
- bson_fprintf(f, "%lld", (uint64_t) bson_iterator_long(&i));
+ fprintf(f, "%" PRIdMAX "", (uint64_t) bson_iterator_long(&i));
break;
case BSON_TIMESTAMP:
ts = bson_iterator_timestamp(&i);
- bson_fprintf(f, "i: %d, t: %d", ts.i, ts.t);
+ fprintf(f, "i: %d, t: %d", ts.i, ts.t);
break;
case BSON_OBJECT:
case BSON_ARRAY:
- bson_fprintf(f, "\n");
+ fprintf(f, "\n");
bson_print_raw(f, bson_iterator_value(&i), depth + 1);
break;
default:
bson_errprintf("can't print type : %d\n", t);
}
- bson_fprintf(f, "\n");
+ fprintf(f, "\n");
}
}
ITERATOR
------------------------------ */
-EJDB_EXPORT bson_iterator* bson_iterator_create(void) {
+ bson_iterator* bson_iterator_create(void) {
return (bson_iterator*) malloc(sizeof ( bson_iterator));
}
-EJDB_EXPORT void bson_iterator_dispose(bson_iterator* i) {
+ void bson_iterator_dispose(bson_iterator* i) {
free(i);
}
-EJDB_EXPORT void bson_iterator_init(bson_iterator *i, const bson *b) {
+ void bson_iterator_init(bson_iterator *i, const bson *b) {
i->cur = b->data + 4;
i->first = 1;
}
-EJDB_EXPORT void bson_iterator_from_buffer(bson_iterator *i, const char *buffer) {
+ void bson_iterator_from_buffer(bson_iterator *i, const char *buffer) {
i->cur = buffer + 4;
i->first = 1;
}
-EJDB_EXPORT bson_type bson_find(bson_iterator *it, const bson *obj, const char *name) {
+ bson_type bson_find(bson_iterator *it, const bson *obj, const char *name) {
bson_iterator_init(it, (bson *) obj);
while (bson_iterator_next(it)) {
if (strcmp(name, bson_iterator_key(it)) == 0)
return bson_iterator_type(it);
}
-EJDB_EXPORT bson_type bson_find_from_buffer(bson_iterator *it, const char *buffer, const char *name) {
+ bson_type bson_find_from_buffer(bson_iterator *it, const char *buffer, const char *name) {
bson_iterator_from_buffer(it, buffer);
while (bson_iterator_next(it)) {
if (strcmp(name, bson_iterator_key(it)) == 0)
}
}
-EJDB_EXPORT void bson_visit_fields(bson_iterator *it, bson_traverse_flags_t flags, BSONVISITOR visitor, void *op) {
+ void bson_visit_fields(bson_iterator *it, bson_traverse_flags_t flags, BSONVISITOR visitor, void *op) {
char pstack[BSON_MAX_FPATH_LEN + 1];
bson_visit_fields_impl(flags, pstack, 0, it, visitor, op);
}
return BSON_EOO;
}
-EJDB_EXPORT bson_type bson_find_fieldpath_value(const char *fpath, bson_iterator *it) {
+ bson_type bson_find_fieldpath_value(const char *fpath, bson_iterator *it) {
return bson_find_fieldpath_value2(fpath, strlen(fpath), it);
}
-EJDB_EXPORT bson_type bson_find_fieldpath_value2(const char *fpath, int fplen, bson_iterator *it) {
+ bson_type bson_find_fieldpath_value2(const char *fpath, int fplen, bson_iterator *it) {
FFPCTX ffctx = {
.fpath = fpath,
.fplen = fplen,
return bson_find_fieldpath_value3(&ffctx);
}
-EJDB_EXPORT bson_type bson_find_fieldpath_value3(FFPCTX* ffctx) {
+ bson_type bson_find_fieldpath_value3(FFPCTX* ffctx) {
char pstackstack[BSON_MAX_FPATH_LEN + 1];
char *pstack;
if (ffctx->fplen <= BSON_MAX_FPATH_LEN) {
return bt;
}
-EJDB_EXPORT bson_bool_t bson_iterator_more(const bson_iterator *i) {
+ bson_bool_t bson_iterator_more(const bson_iterator *i) {
return *(i->cur);
}
-EJDB_EXPORT bson_type bson_iterator_next(bson_iterator *i) {
+ bson_type bson_iterator_next(bson_iterator *i) {
int ds;
if (i->first) {
return (bson_type) (*i->cur);
}
-EJDB_EXPORT bson_type bson_iterator_type(const bson_iterator *i) {
+ bson_type bson_iterator_type(const bson_iterator *i) {
return (bson_type) i->cur[0];
}
-EJDB_EXPORT const char *bson_iterator_key(const bson_iterator *i) {
+ const char *bson_iterator_key(const bson_iterator *i) {
return i->cur + 1;
}
-EJDB_EXPORT const char *bson_iterator_value(const bson_iterator *i) {
+ const char *bson_iterator_value(const bson_iterator *i) {
const char *t = i->cur + 1;
t += strlen(t) + 1;
return t;
/* types */
-EJDB_EXPORT int bson_iterator_int_raw(const bson_iterator *i) {
+ int bson_iterator_int_raw(const bson_iterator *i) {
int out;
bson_little_endian32(&out, bson_iterator_value(i));
return out;
}
-EJDB_EXPORT double bson_iterator_double_raw(const bson_iterator *i) {
+ double bson_iterator_double_raw(const bson_iterator *i) {
double out;
bson_little_endian64(&out, bson_iterator_value(i));
return out;
}
-EJDB_EXPORT int64_t bson_iterator_long_raw(const bson_iterator *i) {
+ int64_t bson_iterator_long_raw(const bson_iterator *i) {
int64_t out;
bson_little_endian64(&out, bson_iterator_value(i));
return out;
}
-EJDB_EXPORT bson_bool_t bson_iterator_bool_raw(const bson_iterator *i) {
+ bson_bool_t bson_iterator_bool_raw(const bson_iterator *i) {
return bson_iterator_value(i)[0];
}
-EJDB_EXPORT bson_oid_t *bson_iterator_oid(const bson_iterator *i) {
+ bson_oid_t *bson_iterator_oid(const bson_iterator *i) {
return (bson_oid_t *) bson_iterator_value(i);
}
-EJDB_EXPORT int bson_iterator_int(const bson_iterator *i) {
+ int bson_iterator_int(const bson_iterator *i) {
switch (bson_iterator_type(i)) {
case BSON_INT:
return bson_iterator_int_raw(i);
}
}
-EJDB_EXPORT double bson_iterator_double(const bson_iterator *i) {
+ double bson_iterator_double(const bson_iterator *i) {
switch (bson_iterator_type(i)) {
case BSON_INT:
return bson_iterator_int_raw(i);
}
}
-EJDB_EXPORT int64_t bson_iterator_long(const bson_iterator *i) {
+ int64_t bson_iterator_long(const bson_iterator *i) {
switch (bson_iterator_type(i)) {
case BSON_INT:
return bson_iterator_int_raw(i);
}
}
-EJDB_EXPORT bson_timestamp_t bson_iterator_timestamp(const bson_iterator *i) {
+ bson_timestamp_t bson_iterator_timestamp(const bson_iterator *i) {
bson_timestamp_t ts;
bson_little_endian32(&(ts.i), bson_iterator_value(i));
bson_little_endian32(&(ts.t), bson_iterator_value(i) + 4);
return ts;
}
-EJDB_EXPORT int bson_iterator_timestamp_time(const bson_iterator *i) {
+ int bson_iterator_timestamp_time(const bson_iterator *i) {
int time;
bson_little_endian32(&time, bson_iterator_value(i) + 4);
return time;
}
-EJDB_EXPORT int bson_iterator_timestamp_increment(const bson_iterator *i) {
+ int bson_iterator_timestamp_increment(const bson_iterator *i) {
int increment;
bson_little_endian32(&increment, bson_iterator_value(i));
return increment;
}
-EJDB_EXPORT bson_bool_t bson_iterator_bool(const bson_iterator *i) {
+ bson_bool_t bson_iterator_bool(const bson_iterator *i) {
switch (bson_iterator_type(i)) {
case BSON_BOOL:
return bson_iterator_bool_raw(i);
}
}
-EJDB_EXPORT const char *bson_iterator_string(const bson_iterator *i) {
+ const char *bson_iterator_string(const bson_iterator *i) {
switch (bson_iterator_type(i)) {
case BSON_STRING:
case BSON_SYMBOL:
return bson_iterator_int_raw(i);
}
-EJDB_EXPORT const char *bson_iterator_code(const bson_iterator *i) {
+ const char *bson_iterator_code(const bson_iterator *i) {
switch (bson_iterator_type(i)) {
case BSON_STRING:
case BSON_CODE:
}
}
-EJDB_EXPORT void bson_iterator_code_scope(const bson_iterator *i, bson *scope) {
+ void bson_iterator_code_scope(const bson_iterator *i, bson *scope) {
if (bson_iterator_type(i) == BSON_CODEWSCOPE) {
int code_len;
bson_little_endian32(&code_len, bson_iterator_value(i) + 4);
}
}
-EJDB_EXPORT bson_date_t bson_iterator_date(const bson_iterator *i) {
+ bson_date_t bson_iterator_date(const bson_iterator *i) {
return bson_iterator_long_raw(i);
}
-EJDB_EXPORT time_t bson_iterator_time_t(const bson_iterator *i) {
+ time_t bson_iterator_time_t(const bson_iterator *i) {
return bson_iterator_date(i) / 1000;
}
-EJDB_EXPORT int bson_iterator_bin_len(const bson_iterator *i) {
+ int bson_iterator_bin_len(const bson_iterator *i) {
return ( bson_iterator_bin_type(i) == BSON_BIN_BINARY_OLD)
? bson_iterator_int_raw(i) - 4
: bson_iterator_int_raw(i);
}
-EJDB_EXPORT char bson_iterator_bin_type(const bson_iterator *i) {
+ char bson_iterator_bin_type(const bson_iterator *i) {
return bson_iterator_value(i)[4];
}
-EJDB_EXPORT const char *bson_iterator_bin_data(const bson_iterator *i) {
+ const char *bson_iterator_bin_data(const bson_iterator *i) {
return ( bson_iterator_bin_type(i) == BSON_BIN_BINARY_OLD)
? bson_iterator_value(i) + 9
: bson_iterator_value(i) + 5;
}
-EJDB_EXPORT const char *bson_iterator_regex(const bson_iterator *i) {
+ const char *bson_iterator_regex(const bson_iterator *i) {
return bson_iterator_value(i);
}
-EJDB_EXPORT const char *bson_iterator_regex_opts(const bson_iterator *i) {
+ const char *bson_iterator_regex_opts(const bson_iterator *i) {
const char *p = bson_iterator_value(i);
return p + strlen(p) + 1;
}
-EJDB_EXPORT void bson_iterator_subobject(const bson_iterator *i, bson *sub) {
+ void bson_iterator_subobject(const bson_iterator *i, bson *sub) {
bson_init_data(sub, (char *) bson_iterator_value(i));
bson_reset(sub);
sub->finished = 1;
}
-EJDB_EXPORT void bson_iterator_subiterator(const bson_iterator *i, bson_iterator *sub) {
+ void bson_iterator_subiterator(const bson_iterator *i, bson_iterator *sub) {
bson_iterator_from_buffer(sub, bson_iterator_value(i));
}
bson_reset(b);
}
-EJDB_EXPORT void bson_init(bson *b) {
+ void bson_init(bson *b) {
_bson_init_size(b, initialBufferSize);
}
-EJDB_EXPORT void bson_init_as_query(bson *b) {
+ void bson_init_as_query(bson *b) {
bson_init(b);
b->flags |= BSON_FLAG_QUERY_MODE;
}
b->cur++;
}
-EJDB_EXPORT void bson_append(bson *b, const void *data, int len) {
+ void bson_append(bson *b, const void *data, int len) {
memcpy(b->cur, data, len);
b->cur += len;
}
return BSON_OK;
}
-EJDB_EXPORT int bson_finish(bson *b) {
+ int bson_finish(bson *b) {
int i;
if (b->err & BSON_NOT_UTF8)
return BSON_OK;
}
-EJDB_EXPORT void bson_destroy(bson *b) {
+ void bson_destroy(bson *b) {
if (b) {
if (b->data && !(b->flags & BSON_FLAG_STACK_ALLOCATED)) {
bson_free(b->data);
}
}
-EJDB_EXPORT void bson_del(bson *b) {
+ void bson_del(bson *b) {
if (b) {
bson_destroy(b);
bson_free(b);
BUILDING TYPES
------------------------------ */
-EJDB_EXPORT int bson_append_int(bson *b, const char *name, const int i) {
+ int bson_append_int(bson *b, const char *name, const int i) {
if (bson_append_estart(b, BSON_INT, name, 4) == BSON_ERROR)
return BSON_ERROR;
bson_append32(b, &i);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_long(bson *b, const char *name, const int64_t i) {
+ int bson_append_long(bson *b, const char *name, const int64_t i) {
if (bson_append_estart(b, BSON_LONG, name, 8) == BSON_ERROR)
return BSON_ERROR;
bson_append64(b, &i);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_double(bson *b, const char *name, const double d) {
+ int bson_append_double(bson *b, const char *name, const double d) {
if (bson_append_estart(b, BSON_DOUBLE, name, 8) == BSON_ERROR)
return BSON_ERROR;
bson_append64(b, &d);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_bool(bson *b, const char *name, const bson_bool_t i) {
+ int bson_append_bool(bson *b, const char *name, const bson_bool_t i) {
if (bson_append_estart(b, BSON_BOOL, name, 1) == BSON_ERROR)
return BSON_ERROR;
bson_append_byte(b, i != 0);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_null(bson *b, const char *name) {
+ int bson_append_null(bson *b, const char *name) {
if (bson_append_estart(b, BSON_NULL, name, 0) == BSON_ERROR)
return BSON_ERROR;
return BSON_OK;
}
-EJDB_EXPORT int bson_append_undefined(bson *b, const char *name) {
+ int bson_append_undefined(bson *b, const char *name) {
if (bson_append_estart(b, BSON_UNDEFINED, name, 0) == BSON_ERROR)
return BSON_ERROR;
return BSON_OK;
return BSON_OK;
}
-EJDB_EXPORT int bson_append_string(bson *b, const char *name, const char *value) {
+ int bson_append_string(bson *b, const char *name, const char *value) {
return bson_append_string_base(b, name, value, strlen(value), BSON_STRING);
}
-EJDB_EXPORT int bson_append_symbol(bson *b, const char *name, const char *value) {
+ int bson_append_symbol(bson *b, const char *name, const char *value) {
return bson_append_string_base(b, name, value, strlen(value), BSON_SYMBOL);
}
-EJDB_EXPORT int bson_append_code(bson *b, const char *name, const char *value) {
+ int bson_append_code(bson *b, const char *name, const char *value) {
return bson_append_string_base(b, name, value, strlen(value), BSON_CODE);
}
-EJDB_EXPORT int bson_append_string_n(bson *b, const char *name, const char *value, int len) {
+ int bson_append_string_n(bson *b, const char *name, const char *value, int len) {
return bson_append_string_base(b, name, value, len, BSON_STRING);
}
-EJDB_EXPORT int bson_append_symbol_n(bson *b, const char *name, const char *value, int len) {
+ int bson_append_symbol_n(bson *b, const char *name, const char *value, int len) {
return bson_append_string_base(b, name, value, len, BSON_SYMBOL);
}
-EJDB_EXPORT int bson_append_code_n(bson *b, const char *name, const char *value, int len) {
+ int bson_append_code_n(bson *b, const char *name, const char *value, int len) {
return bson_append_string_base(b, name, value, len, BSON_CODE);
}
-EJDB_EXPORT int bson_append_code_w_scope_n(bson *b, const char *name,
+ int bson_append_code_w_scope_n(bson *b, const char *name,
const char *code, int len, const bson *scope) {
int sl, size;
return BSON_OK;
}
-EJDB_EXPORT int bson_append_code_w_scope(bson *b, const char *name, const char *code, const bson *scope) {
+ int bson_append_code_w_scope(bson *b, const char *name, const char *code, const bson *scope) {
return bson_append_code_w_scope_n(b, name, code, strlen(code), scope);
}
-EJDB_EXPORT int bson_append_binary(bson *b, const char *name, char type, const char *str, int len) {
+ int bson_append_binary(bson *b, const char *name, char type, const char *str, int len) {
if (type == BSON_BIN_BINARY_OLD) {
int subtwolen = len + 4;
if (bson_append_estart(b, BSON_BINDATA, name, 4 + 1 + 4 + len) == BSON_ERROR)
return BSON_OK;
}
-EJDB_EXPORT int bson_append_oid(bson *b, const char *name, const bson_oid_t *oid) {
+ int bson_append_oid(bson *b, const char *name, const bson_oid_t *oid) {
if (bson_append_estart(b, BSON_OID, name, 12) == BSON_ERROR)
return BSON_ERROR;
bson_append(b, oid, 12);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_new_oid(bson *b, const char *name) {
+ int bson_append_new_oid(bson *b, const char *name) {
bson_oid_t oid;
bson_oid_gen(&oid);
return bson_append_oid(b, name, &oid);
}
-EJDB_EXPORT int bson_append_regex(bson *b, const char *name, const char *pattern, const char *opts) {
+ int bson_append_regex(bson *b, const char *name, const char *pattern, const char *opts) {
const int plen = strlen(pattern) + 1;
const int olen = strlen(opts) + 1;
if (bson_append_estart(b, BSON_REGEX, name, plen + olen) == BSON_ERROR)
return BSON_OK;
}
-EJDB_EXPORT int bson_append_bson(bson *b, const char *name, const bson *bson) {
+ int bson_append_bson(bson *b, const char *name, const bson *bson) {
if (!bson) return BSON_ERROR;
if (bson_append_estart(b, BSON_OBJECT, name, bson_size(bson)) == BSON_ERROR)
return BSON_ERROR;
return BSON_OK;
}
-EJDB_EXPORT int bson_append_element(bson *b, const char *name_or_null, const bson_iterator *elem) {
+ int bson_append_element(bson *b, const char *name_or_null, const bson_iterator *elem) {
bson_iterator next = *elem;
int size;
return BSON_OK;
}
-EJDB_EXPORT int bson_append_timestamp(bson *b, const char *name, bson_timestamp_t *ts) {
+ int bson_append_timestamp(bson *b, const char *name, bson_timestamp_t *ts) {
if (bson_append_estart(b, BSON_TIMESTAMP, name, 8) == BSON_ERROR) return BSON_ERROR;
bson_append32(b, &(ts->i));
return BSON_OK;
}
-EJDB_EXPORT int bson_append_timestamp2(bson *b, const char *name, int time, int increment) {
+ int bson_append_timestamp2(bson *b, const char *name, int time, int increment) {
if (bson_append_estart(b, BSON_TIMESTAMP, name, 8) == BSON_ERROR) return BSON_ERROR;
bson_append32(b, &increment);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_date(bson *b, const char *name, bson_date_t millis) {
+ int bson_append_date(bson *b, const char *name, bson_date_t millis) {
if (bson_append_estart(b, BSON_DATE, name, 8) == BSON_ERROR) return BSON_ERROR;
bson_append64(b, &millis);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_time_t(bson *b, const char *name, time_t secs) {
+ int bson_append_time_t(bson *b, const char *name, time_t secs) {
return bson_append_date(b, name, (bson_date_t) secs * 1000);
}
-EJDB_EXPORT int bson_append_start_object(bson *b, const char *name) {
+ int bson_append_start_object(bson *b, const char *name) {
if (bson_append_estart(b, BSON_OBJECT, name, 5) == BSON_ERROR) return BSON_ERROR;
b->stack[ b->stackPos++ ] = b->cur - b->data;
bson_append32(b, &zero);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_start_object2(bson *b, const char *name, int namelen) {
+ int bson_append_start_object2(bson *b, const char *name, int namelen) {
if (bson_append_estart2(b, BSON_OBJECT, name, namelen, 5) == BSON_ERROR) return BSON_ERROR;
b->stack[ b->stackPos++ ] = b->cur - b->data;
bson_append32(b, &zero);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_start_array(bson *b, const char *name) {
+ int bson_append_start_array(bson *b, const char *name) {
return bson_append_start_array2(b, name, strlen(name));
}
-EJDB_EXPORT int bson_append_start_array2(bson *b, const char *name, int namelen) {
+ int bson_append_start_array2(bson *b, const char *name, int namelen) {
if (bson_append_estart2(b, BSON_ARRAY, name, namelen, 5) == BSON_ERROR) return BSON_ERROR;
b->stack[ b->stackPos++ ] = b->cur - b->data;
bson_append32(b, &zero);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_finish_object(bson *b) {
+ int bson_append_finish_object(bson *b) {
char *start;
int i;
if (bson_ensure_space(b, 1) == BSON_ERROR) return BSON_ERROR;
return BSON_OK;
}
-EJDB_EXPORT double bson_int64_to_double(int64_t i64) {
+ double bson_int64_to_double(int64_t i64) {
return (double) i64;
}
-EJDB_EXPORT int bson_append_finish_array(bson *b) {
+ int bson_append_finish_array(bson *b) {
return bson_append_finish_object(b);
}
static bson_err_handler err_handler = NULL;
-EJDB_EXPORT bson_err_handler set_bson_err_handler(bson_err_handler func) {
+ bson_err_handler set_bson_err_handler(bson_err_handler func) {
bson_err_handler old = err_handler;
err_handler = func;
return old;
}
-EJDB_EXPORT void bson_free(void *ptr) {
+ void bson_free(void *ptr) {
bson_free_func(ptr);
}
-EJDB_EXPORT void *bson_malloc(int size) {
+ void *bson_malloc(int size) {
void *p;
p = bson_malloc_func(size);
bson_fatal_msg(!!p, "malloc() failed");
va_list ap;
int ret;
va_start(ap, format);
-#ifndef R_SAFETY_NET
ret = vfprintf(stderr, format, ap);
-#endif
va_end(ap);
-
return ret;
}
if (err_handler) {
err_handler(msg);
}
-#ifndef R_SAFETY_NET
bson_errprintf("error: %s\n", msg);
- exit(-5);
-#endif
}
/* Efficiently copy an integer to a string. */
extern const char bson_numstrs[1000][4];
-EJDB_EXPORT void bson_numstr(char *str, int64_t i) {
+ void bson_numstr(char *str, int64_t i) {
if (i >= 0 && i < 1000)
memcpy(str, bson_numstrs[i], 4);
else
- bson_sprintf(str, "%lld", (long long int) i);
+ sprintf(str, "%" PRIdMAX "", (long long int) i);
}
-EJDB_EXPORT int bson_numstrn(char *str, int maxbuf, int64_t i) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+ int bson_numstrn(char *str, int maxbuf, int64_t i) {
if (i >= 0 && i < 1000 && maxbuf > 4) {
memcpy(str, bson_numstrs[i], 4);
return strlen(bson_numstrs[i]);
} else {
- return snprintf(str, maxbuf, "%lld", (long long int) i);
+ return snprintf(str, maxbuf, "%" PRIdMAX "", (long long int) i);
}
}
+ #pragma GCC diagnostic pop
static bson_bool_t bson_isnumstr(const char *str, int len) {
assert(str);
return (isnum && (*str == '\0' || len == 0));
}
-EJDB_EXPORT void bson_swap_endian64(void *outp, const void *inp) {
+ void bson_swap_endian64(void *outp, const void *inp) {
const char *in = (const char *) inp;
char *out = (char *) outp;
out[0] = in[7];
}
-EJDB_EXPORT void bson_swap_endian32(void *outp, const void *inp) {
+ void bson_swap_endian32(void *outp, const void *inp) {
const char *in = (const char *) inp;
char *out = (char *) outp;
out[0] = in[3];
out[3] = in[0];
}
-EJDB_EXPORT int bson_append_array_from_iterator(const char *key, bson_iterator *from, bson *into) {
+ int bson_append_array_from_iterator(const char *key, bson_iterator *from, bson *into) {
assert(key && from && into);
bson_type bt;
bson_append_start_array(into, key);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_object_from_iterator(const char *key, bson_iterator *from, bson *into) {
+ int bson_append_object_from_iterator(const char *key, bson_iterator *from, bson *into) {
assert(key && from && into);
bson_type bt;
bson_append_start_object(into, key);
return BSON_OK;
}
-EJDB_EXPORT int bson_append_field_from_iterator2(const char *key, const bson_iterator *from, bson *into) {
+ int bson_append_field_from_iterator2(const char *key, const bson_iterator *from, bson *into) {
assert(key && from && into);
bson_type t = bson_iterator_type(from);
if (t == BSON_EOO || into->finished) {
return BSON_OK;
}
-EJDB_EXPORT int bson_append_field_from_iterator(const bson_iterator *from, bson *into) {
+ int bson_append_field_from_iterator(const bson_iterator *from, bson *into) {
assert(from && into);
return bson_append_field_from_iterator2(bson_iterator_key(from), from, into);
}
-EJDB_EXPORT int bson_merge2(const void *b1data, const void *b2data, bson_bool_t overwrite, bson *out) {
+ int bson_merge2(const void *b1data, const void *b2data, bson_bool_t overwrite, bson *out) {
bson_iterator it1, it2;
bson_type bt1, bt2;
return BSON_OK;
}
-EJDB_EXPORT int bson_merge(const bson *b1, const bson *b2, bson_bool_t overwrite, bson *out) {
+ int bson_merge(const bson *b1, const bson *b2, bson_bool_t overwrite, bson *out) {
assert(b1 && b2 && out);
if (!b1->finished || !b2->finished || out->finished) {
return BSON_ERROR;
return bson_merge2(bson_data(b1), bson_data(b2), overwrite, out);
}
-EJDB_EXPORT int bson_inplace_set_bool(bson_iterator *pos, bson_bool_t val) {
+ int bson_inplace_set_bool(bson_iterator *pos, bson_bool_t val) {
assert(pos);
bson_type bt = bson_iterator_type(pos);
if (bt != BSON_BOOL) {
return BSON_OK;
}
-EJDB_EXPORT int bson_inplace_set_long(bson_iterator *pos, int64_t val) {
+ int bson_inplace_set_long(bson_iterator *pos, int64_t val) {
assert(pos);
bson_type bt = bson_iterator_type(pos);
if (!BSON_IS_NUM_TYPE(bt)) {
return BSON_OK;
}
-EJDB_EXPORT int bson_inplace_set_double(bson_iterator *pos, double val) {
+ int bson_inplace_set_double(bson_iterator *pos, double val) {
assert(pos);
bson_type bt = bson_iterator_type(pos);
if (!BSON_IS_NUM_TYPE(bt)) {
return BSON_OK;
}
-EJDB_EXPORT int bson_compare_fpaths(const void *bsdata1, const void *bsdata2, const char *fpath1, int fplen1, const char *fpath2, int fplen2) {
+ int bson_compare_fpaths(const void *bsdata1, const void *bsdata2, const char *fpath1, int fplen1, const char *fpath2, int fplen2) {
assert(bsdata1 && bsdata2 && fpath1 && fpath2);
bson_iterator it1, it2;
bson_iterator_from_buffer(&it1, bsdata1);
* @param i
* @return
*/
-EJDB_EXPORT int bson_compare_it_current(const bson_iterator *it1, const bson_iterator *it2) {
+ int bson_compare_it_current(const bson_iterator *it1, const bson_iterator *it2) {
bson_type t1 = bson_iterator_type(it1);
bson_type t2 = bson_iterator_type(it2);
if (t1 == BSON_BOOL || t1 == BSON_EOO || t1 == BSON_NULL || t1 == BSON_UNDEFINED) {
return (t1 - t2);
}
-EJDB_EXPORT int bson_compare(const void *bsdata1, const void *bsdata2, const char* fpath, int fplen) {
+ int bson_compare(const void *bsdata1, const void *bsdata2, const char* fpath, int fplen) {
return bson_compare_fpaths(bsdata1, bsdata2, fpath, fplen, fpath, fplen);
}
-EJDB_EXPORT int bson_compare_string(const char *cv, const void *bsdata, const char *fpath) {
+ int bson_compare_string(const char *cv, const void *bsdata, const char *fpath) {
assert(cv && bsdata && fpath);
bson *bs1 = bson_create();
bson_init(bs1);
return res;
}
-EJDB_EXPORT int bson_compare_long(long cv, const void *bsdata, const char *fpath) {
+ int bson_compare_long(long cv, const void *bsdata, const char *fpath) {
bson *bs1 = bson_create();
bson_init(bs1);
bson_append_long(bs1, "$", cv);
return res;
}
-EJDB_EXPORT int bson_compare_double(double cv, const void *bsdata, const char *fpath) {
+ int bson_compare_double(double cv, const void *bsdata, const char *fpath) {
bson *bs1 = bson_create();
bson_init(bs1);
bson_append_double(bs1, "$", cv);
return res;
}
-EJDB_EXPORT int bson_compare_bool(bson_bool_t cv, const void *bsdata, const char *fpath) {
+ int bson_compare_bool(bson_bool_t cv, const void *bsdata, const char *fpath) {
bson *bs1 = bson_create();
bson_init(bs1);
bson_append_bool(bs1, "$", cv);
return res;
}
-EJDB_EXPORT bson* bson_dup(const bson *src) {
+ bson* bson_dup(const bson *src) {
assert(src);
bson *rv = bson_create();
int s = bson_size(src);
return rv;
}
-EJDB_EXPORT bson* bson_create_from_buffer(const void* buf, int bufsz) {
+ bson* bson_create_from_buffer(const void* buf, int bufsz) {
return bson_create_from_buffer2(bson_create(), buf, bufsz);
}
-EJDB_EXPORT bson* bson_create_from_buffer2(bson *rv, const void* buf, int bufsz) {
+ bson* bson_create_from_buffer2(bson *rv, const void* buf, int bufsz) {
assert(buf);
assert(bufsz - 4 > 0);
bson_init_size(rv, bufsz);
return rv;
}
-EJDB_EXPORT bool bson_find_merged_array_sets(const void *mbuf, const void *inbuf, bool expandall) {
+ bool bson_find_merged_array_sets(const void *mbuf, const void *inbuf, bool expandall) {
assert(mbuf && inbuf);
bool found = false;
bson_iterator it, it2;
return found;
}
-EJDB_EXPORT bool bson_find_unmerged_array_sets(const void *mbuf, const void *inbuf) {
+ bool bson_find_unmerged_array_sets(const void *mbuf, const void *inbuf) {
assert(mbuf && inbuf);
bool allfound = false;
bson_iterator it, it2;
}
-EJDB_EXPORT int bson_merge_array_sets(const void *mbuf, const void *inbuf, bool pull, bool expandall, bson *bsout) {
+ int bson_merge_array_sets(const void *mbuf, const void *inbuf, bool pull, bool expandall, bson *bsout) {
assert(mbuf && inbuf && bsout);
if (bsout->finished) {
return BSON_ERROR;
#ifndef BSON_H_
#define BSON_H_
-#include "myconf.h"
-
-#ifdef EJDB_BIG_ENDIAN
-#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) )
-#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) )
-#define bson_big_endian64(out, in) ( memcpy(out, in, 8) )
-#define bson_big_endian32(out, in) ( memcpy(out, in, 4) )
-#else
-#define bson_little_endian64(out, in) ( memcpy(out, in, 8) )
-#define bson_little_endian32(out, in) ( memcpy(out, in, 4) )
-#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) )
-#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) )
-#endif
+#include "basedefs.h"
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
#define BSON_IS_NUM_TYPE(atype) (atype == BSON_INT || atype == BSON_LONG || atype == BSON_DOUBLE)
/* bson_err_handlers shouldn't return!!! */
typedef void( *bson_err_handler)(const char *errmsg);
-
typedef int (*bson_printf_func)(const char *, ...);
-typedef int (*bson_fprintf_func)(FILE *, const char *, ...);
-typedef int (*bson_sprintf_func)(char *, const char *, ...);
extern void *(*bson_malloc_func)(size_t);
extern void *(*bson_realloc_func)(void *, size_t);
extern void ( *bson_free_func)(void *);
-extern bson_printf_func bson_printf;
-extern bson_fprintf_func bson_fprintf;
-extern bson_sprintf_func bson_sprintf;
extern bson_printf_func bson_errprintf;
EJDB_EXPORT void bson_free(void *ptr);
--- /dev/null
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2013 Free Software Foundation, Inc.
+
+timestamp='2013-02-12'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2013 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | be32 | be64 \
+ | bfin \
+ | c4x | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | epiphany \
+ | fido | fr30 | frv \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 \
+ | or1k | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i386-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i386-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or1k-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
\ No newline at end of file
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tcejdb 1.0.68.
+# Generated by GNU Autoconf 2.68 for tcejdb 1.0.68.
#
#
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
+# Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-# Use a proper internal environment variable to ensure we don't fall
- # into an infinite loop, continuously re-executing ourselves.
- if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
- _as_can_reexec=no; export _as_can_reexec;
- # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
- fi
- # We don't want this to propagate to other subprocesses.
- { _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
else
exitcode=1; echo positional parameters were not saved.
fi
-test x\$exitcode = x0 || exit 1
-test -x / || exit 1"
+test x\$exitcode = x0 || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
if test "x$CONFIG_SHELL" != x; then :
- export CONFIG_SHELL
- # We cannot yet assume a decent shell, so we have to provide a
-# neutralization value for shells without unset; and this also
-# works around shells that cannot unset nonexistent variables.
-# Preserve -v and -x to the replacement shell.
-BASH_ENV=/dev/null
-ENV=/dev/null
-(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-case $- in # ((((
- *v*x* | *x*v* ) as_opts=-vx ;;
- *v* ) as_opts=-v ;;
- *x* ) as_opts=-x ;;
- * ) as_opts= ;;
-esac
-exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
-# Admittedly, this is quite paranoid, since all the known shells bail
-# out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-exit 255
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ # Preserve -v and -x to the replacement shell.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+ esac
+ exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"}
fi
if test x$as_have_required = xno; then :
} # as_fn_mkdir_p
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
- test -f "$1" && test -x "$1"
-} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
- # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
- # already done that, so ensure we don't try to do so again and fall
- # in an infinite loop. This has already happened in practice.
- _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
as_mkdir_p=false
fi
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
LDFLAGS
CFLAGS
CC
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
target_alias
host_alias
build_alias
enable_bzip
enable_ubc
enable_zlib
-enable_pthread
enable_shared
enable_exlzma
enable_exlzo
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
+ $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used" >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
_ACEOF
cat <<\_ACEOF
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
_ACEOF
fi
--enable-bzip build with BZIP2 compression
--disable-ubc build without the unified buffer cache assumption
--disable-zlib build without ZLIB compression
- --disable-pthread build without POSIX thread support
--disable-shared avoid to build shared libraries
--disable-exlzma build with the custom codec of LZMA
--disable-exlzo build with the custom codec of LZO
if $ac_init_version; then
cat <<\_ACEOF
tcejdb configure 1.0.68
-generated by GNU Autoconf 2.69
+generated by GNU Autoconf 2.68
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
- test -x conftest$ac_exeext
+ $as_test_x conftest$ac_exeext
}; then :
ac_retval=0
else
running configure, to aid debugging if configure makes a mistake.
It was created by tcejdb $as_me 1.0.68, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@
|| { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
done
ac_compiler_gnu=$ac_cv_c_compiler_gnu
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ if test -f "$ac_dir/install-sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f "$ac_dir/install.sh"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ elif test -f "$ac_dir/shtool"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/shtool install -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if ${ac_cv_build+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if ${ac_cv_host+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
# Package information
MYLIBVER=9
MYFORMATVER="1.0"
# Targets
-MYHEADERFILES="tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h ejdb.h ejdb_private.h bson.h myconf.h"
+MYHEADERFILES="tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h ejdb.h ejdb_private.h bson.h myconf.h basedefs.h"
MYLIBRARYFILES="libtcejdb.a"
+
MYLIBOBJFILES="tcutil.o tchdb.o tcbdb.o tcfdb.o tctdb.o tcadb.o myconf.o md5.o ejdb.o \
-bson.o numbers.o encoding.o utf8proc.o ejdbutl.o"
+bson.o numbers.o encoding.o utf8proc.o ejdbutl.o platform.o"
+
MYCOMMANDFILES="tcutest tcumttest tcucodec tchtest tchmttest tchmgr"
MYCOMMANDFILES="$MYCOMMANDFILES tcbtest tcbmttest tcbmgr tcftest tcfmttest tcfmgr"
MYCOMMANDFILES="$MYCOMMANDFILES tcttest tctmttest tctmgr tcatest tcamttest tcamgr"
MYPCFILES="tcejdb.pc"
# Building flags
-MYCFLAGS="$MYCFLAGS -std=c99 -Wall -fPIC -fsigned-char -O2"
-MYCPPFLAGS="-I. -I\$(INCLUDEDIR) -I$HOME/include -I/usr/local/include"
+MYCFLAGS="$MYCFLAGS -std=gnu99 -Wall -fsigned-char -O2 -Wfatal-errors"
+MYCPPFLAGS="-I. -I$HOME/include -I\$(INCLUDEDIR) -I/usr/local/include"
MYCPPFLAGS="$MYCPPFLAGS -D_UNICODE -DNDEBUG -D_GNU_SOURCE=1 -D_REENTRANT -D__EXTENSIONS__"
-MYLDFLAGS="-L. -L\$(LIBDIR) -L$HOME/lib -L/usr/local/lib"
+MYLDFLAGS="-L. -L\$(LIBDIR) -L$HOME/lib -L/usr/local/lib -L/usr/lib -Wl,-Bstatic"
MYCMDLDFLAGS=""
MYRUNPATH="\$(LIBDIR)"
MYLDLIBPATHENV="LD_LIBRARY_PATH"
if test "$enable_debug" = "yes"
then
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -O0"
- MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -g -O0 -Wfatal-errors -Werror"
+ MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG -DEJDB_STATIC"
MYCMDLDFLAGS="$MYCMDLDFLAGS -static"
enables="$enables (debug)"
fi
if test "$enable_devel" = "yes"
then
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -O2 -pipe"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -g -O2 -pipe"
MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG"
enables="$enables (devel)"
fi
if test "$enable_profile" = "yes"
then
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -pg -O2 -pipe"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -g -pg -O2 -pipe"
enables="$enables (profile)"
fi
if test "$enable_fastest" = "yes"
then
MYLIBOBJFILES="tokyocabinet_all.o"
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -O3"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -O3"
MYCFLAGS="$MYCFLAGS -fomit-frame-pointer -fforce-addr -minline-all-stringops"
MYCPPFLAGS="$MYCPPFLAGS -D_MYFASTEST"
enables="$enables (fastest)"
enables="$enables (no-zlib)"
fi
-# Disable POSIX thread
-# Check whether --enable-pthread was given.
-if test "${enable_pthread+set}" = set; then :
- enableval=$enable_pthread;
-fi
-
-if test "$enable_pthread" = "no"
-then
- MYCPPFLAGS="$MYCPPFLAGS -D_MYNOPTHREAD"
- enables="$enables (no-pthread)"
-fi
-
# Disable shared object
# Check whether --enable-shared was given.
if test "${enable_shared+set}" = set; then :
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
fi
fi
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-struct stat;
+#include <sys/types.h>
+#include <sys/stat.h>
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
# BSD install
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
- if test -f "$ac_dir/install-sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install-sh -c"
- break
- elif test -f "$ac_dir/install.sh"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/install.sh -c"
- break
- elif test -f "$ac_dir/shtool"; then
- ac_aux_dir=$ac_dir
- ac_install_sh="$ac_aux_dir/shtool install -c"
- break
- fi
-done
-if test -z "$ac_aux_dir"; then
- as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
-
-
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
- if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
+See \`config.log' for more details" "$LINENO" 5 ; }
fi
ac_ext=c
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- as_fn_executable_p "$ac_path_GREP" || continue
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- as_fn_executable_p "$ac_path_EGREP" || continue
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
;; #(
*)
as_fn_error $? "unknown endianness
- presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
esac
fi
-if test "$enable_pthread" != "no"
-then
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
-$as_echo_n "checking for main in -lpthread... " >&6; }
-if ${ac_cv_lib_pthread_main+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpthread $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-int
-main ()
-{
-return main ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_pthread_main=yes
-else
- ac_cv_lib_pthread_main=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
-$as_echo "$ac_cv_lib_pthread_main" >&6; }
-if test "x$ac_cv_lib_pthread_main" = xyes; then :
- cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBPTHREAD 1
-_ACEOF
-
- LIBS="-lpthread $LIBS"
-
-fi
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lrt" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lrt" >&5
$as_echo_n "checking for main in -lrt... " >&6; }
if ${ac_cv_lib_rt_main+:} false; then :
$as_echo_n "(cached) " >&6
fi
-fi
+
if test "$enable_zlib" != "no"
then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lz" >&5
fi
fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ltcejdb" >&5
-$as_echo_n "checking for main in -ltcejdb... " >&6; }
-if ${ac_cv_lib_tcejdb_main+:} false; then :
- $as_echo_n "(cached) " >&6
-else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-ltcejdb $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-int
-main ()
-{
-return main ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
- ac_cv_lib_tcejdb_main=yes
-else
- ac_cv_lib_tcejdb_main=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tcejdb_main" >&5
-$as_echo "$ac_cv_lib_tcejdb_main" >&6; }
-if test "x$ac_cv_lib_tcejdb_main" = xyes; then :
- { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: old version of EJDB was found" >&5
-$as_echo "$as_me: WARNING: old version of EJDB was found" >&2;}
-fi
-
if test "$enable_tests" = "yes"
then
fi
-ac_fn_c_check_header_mongrel "$LINENO" "regex.h" "ac_cv_header_regex_h" "$ac_includes_default"
-if test "x$ac_cv_header_regex_h" = xyes; then :
+ac_fn_c_check_header_mongrel "$LINENO" "stddef.h" "ac_cv_header_stddef_h" "$ac_includes_default"
+if test "x$ac_cv_header_stddef_h" = xyes; then :
true
else
- as_fn_error $? "regex.h is required" "$LINENO" 5
+ as_fn_error $? "stddef.h is required" "$LINENO" 5
fi
-ac_fn_c_check_header_mongrel "$LINENO" "glob.h" "ac_cv_header_glob_h" "$ac_includes_default"
-if test "x$ac_cv_header_glob_h" = xyes; then :
- true
-else
- as_fn_error $? "glob.h is required" "$LINENO" 5
-fi
-
-
-if test "$enable_pthread" != "no"
-then
- ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
+ac_fn_c_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default"
if test "x$ac_cv_header_pthread_h" = xyes; then :
true
else
fi
-fi
+
if test "$enable_zlib" != "no"
then
ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
fi
+case $host_os in
+ mingw*)
+ ac_fn_c_check_header_mongrel "$LINENO" "windows.h" "ac_cv_header_windows_h" "$ac_includes_default"
+if test "x$ac_cv_header_windows_h" = xyes; then :
+ true
+else
+ as_fn_error $? "windows.h is required" "$LINENO" 5
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "time.h" "ac_cv_header_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_time_h" = xyes; then :
+ true
+else
+ as_fn_error $? "time.h is required" "$LINENO" 5
+fi
+
+
+ ;;
+ *)
+ ac_fn_c_check_header_mongrel "$LINENO" "glob.h" "ac_cv_header_glob_h" "$ac_includes_default"
+if test "x$ac_cv_header_glob_h" = xyes; then :
+ true
+else
+ as_fn_error $? "glob.h is required" "$LINENO" 5
+fi
+
+
+ ;;
+esac
+
+
# Shared libraries
if test "$enable_shared" != "no" && test "$enable_profile" != "yes"
then
- if uname | grep Darwin >/dev/null
- then
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.$MYLIBREV.0.dylib"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.dylib"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.dylib"
- MYLDLIBPATHENV="DYLD_LIBRARY_PATH"
- else
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER.$MYLIBREV.0"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so"
- fi
+ case $host_os in
+ darwin*)
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.$MYLIBREV.0.dylib"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.dylib"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.dylib"
+ MYLDLIBPATHENV="DYLD_LIBRARY_PATH"
+ ;;
+ mingw*)
+ MYLIBRARYFILES="$MYLIBRARYFILES tcejdb.dll"
+ MYCPPFLAGS="$MYCPPFLAGS -DEJDB_DLL"
+ ;;
+ *)
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER.$MYLIBREV.0"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so"
+ ;;
+ esac
+fi
+
+
+
+case $host_os in
+ mingw*)
+ ac_fn_c_check_header_mongrel "$LINENO" "pcre.h" "ac_cv_header_pcre_h" "$ac_includes_default"
+if test "x$ac_cv_header_pcre_h" = xyes; then :
+ true
+else
+ as_fn_error $? "pcre.h is required" "$LINENO" 5
+fi
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "pcreposix.h" "ac_cv_header_pcreposix_h" "$ac_includes_default"
+if test "x$ac_cv_header_pcreposix_h" = xyes; then :
+ true
+else
+ as_fn_error $? "pcreposix.h is required" "$LINENO" 5
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre_compile in -lpcre" >&5
+$as_echo_n "checking for pcre_compile in -lpcre... " >&6; }
+if ${ac_cv_lib_pcre_pcre_compile+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpcre $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pcre_compile ();
+int
+main ()
+{
+return pcre_compile ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pcre_pcre_compile=yes
+else
+ ac_cv_lib_pcre_pcre_compile=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcre_pcre_compile" >&5
+$as_echo "$ac_cv_lib_pcre_pcre_compile" >&6; }
+if test "x$ac_cv_lib_pcre_pcre_compile" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPCRE 1
+_ACEOF
+
+ LIBS="-lpcre $LIBS"
+
+else
+ as_fn_error $? "pcre lib is required" "$LINENO" 5
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for regcomp in -lpcreposix" >&5
+$as_echo_n "checking for regcomp in -lpcreposix... " >&6; }
+if ${ac_cv_lib_pcreposix_regcomp+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpcreposix $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char regcomp ();
+int
+main ()
+{
+return regcomp ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pcreposix_regcomp=yes
+else
+ ac_cv_lib_pcreposix_regcomp=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcreposix_regcomp" >&5
+$as_echo "$ac_cv_lib_pcreposix_regcomp" >&6; }
+if test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPCREPOSIX 1
+_ACEOF
+
+ LIBS="-lpcreposix $LIBS"
+
+else
+ as_fn_error $? "pcreposix lib is required" "$LINENO" 5
fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthreadGC2" >&5
+$as_echo_n "checking for main in -lpthreadGC2... " >&6; }
+if ${ac_cv_lib_pthreadGC2_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthreadGC2 $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthreadGC2_main=yes
+else
+ ac_cv_lib_pthreadGC2_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreadGC2_main" >&5
+$as_echo "$ac_cv_lib_pthreadGC2_main" >&6; }
+if test "x$ac_cv_lib_pthreadGC2_main" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREADGC2 1
+_ACEOF
+
+ LIBS="-lpthreadGC2 $LIBS"
+
+else
+ as_fn_error $? "pthreadGC2 lubrary is required" "$LINENO" 5
+fi
+
+ MYLDFLAGS="-static-libgcc -static-libstdc++ $MYLDFLAGS"
+ MYHEADERFILES="$MYHEADERFILES win32/platform.h"
+ MYCPPFLAGS="$MYCPPFLAGS -DPCRE_STATIC -DPTW32_STATIC_LIB"
+ ;;
+ *)
+ ac_fn_c_check_header_mongrel "$LINENO" "regex.h" "ac_cv_header_regex_h" "$ac_includes_default"
+if test "x$ac_cv_header_regex_h" = xyes; then :
+ true
+else
+ as_fn_error $? "regex.h is required" "$LINENO" 5
+fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for regcomp in -lregex" >&5
+$as_echo_n "checking for regcomp in -lregex... " >&6; }
+if ${ac_cv_lib_regex_regcomp+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lregex $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char regcomp ();
+int
+main ()
+{
+return regcomp ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_regex_regcomp=yes
+else
+ ac_cv_lib_regex_regcomp=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_regex_regcomp" >&5
+$as_echo "$ac_cv_lib_regex_regcomp" >&6; }
+if test "x$ac_cv_lib_regex_regcomp" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBREGEX 1
+_ACEOF
+
+ LIBS="-lregex $LIBS"
+
+else
+ as_fn_error $? "regex lib is required" "$LINENO" 5
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lpthread" >&5
+$as_echo_n "checking for main in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_main+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+int
+main ()
+{
+return main ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_main=yes
+else
+ ac_cv_lib_pthread_main=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_main" >&5
+$as_echo "$ac_cv_lib_pthread_main" >&6; }
+if test "x$ac_cv_lib_pthread_main" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+ LIBS="-lpthread $LIBS"
+
+else
+ as_fn_error $? "pthread lubrary is required" "$LINENO" 5
+fi
+
+ MYCFLAGS="$MYCFLAGS -fPIC"
+ ;;
+esac
+
#================================================================
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
- # In both cases, we have to default to `cp -pR'.
+ # In both cases, we have to default to `cp -p'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
else
- as_ln_s='cp -pR'
+ as_ln_s='cp -p'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
as_mkdir_p=false
fi
-
-# as_fn_executable_p FILE
-# -----------------------
-# Test if FILE is an executable regular file.
-as_fn_executable_p ()
-{
- test -f "$1" && test -x "$1"
-} # as_fn_executable_p
-as_test_x='test -x'
-as_executable_p=as_fn_executable_p
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# values after options handling.
ac_log="
This file was extended by tcejdb $as_me 1.0.68, which was
-generated by GNU Autoconf 2.69. Invocation command line was
+generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
tcejdb config.status 1.0.68
-configured by $0, generated by GNU Autoconf 2.69,
+configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2010 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"tcejdb.pc") CONFIG_FILES="$CONFIG_FILES tcejdb.pc" ;;
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
esac
done
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
case $ac_tag in
*:-:* | *:-) cat >"$ac_tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
# Source of configuration for Tokyo Cabinet
-
#================================================================
# Generic Settings
#================================================================
# Package name
AC_INIT(tcejdb, 1.0.68)
+AC_CANONICAL_HOST
# Package information
MYLIBVER=9
MYFORMATVER="1.0"
# Targets
-MYHEADERFILES="tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h ejdb.h ejdb_private.h bson.h myconf.h"
+MYHEADERFILES="tcutil.h tchdb.h tcbdb.h tcfdb.h tctdb.h tcadb.h ejdb.h ejdb_private.h bson.h myconf.h basedefs.h"
MYLIBRARYFILES="libtcejdb.a"
+
MYLIBOBJFILES="tcutil.o tchdb.o tcbdb.o tcfdb.o tctdb.o tcadb.o myconf.o md5.o ejdb.o \
-bson.o numbers.o encoding.o utf8proc.o ejdbutl.o"
+bson.o numbers.o encoding.o utf8proc.o ejdbutl.o platform.o"
+
MYCOMMANDFILES="tcutest tcumttest tcucodec tchtest tchmttest tchmgr"
MYCOMMANDFILES="$MYCOMMANDFILES tcbtest tcbmttest tcbmgr tcftest tcfmttest tcfmgr"
MYCOMMANDFILES="$MYCOMMANDFILES tcttest tctmttest tctmgr tcatest tcamttest tcamgr"
MYPCFILES="tcejdb.pc"
# Building flags
-MYCFLAGS="$MYCFLAGS -std=c99 -Wall -fPIC -fsigned-char -O2"
-MYCPPFLAGS="-I. -I\$(INCLUDEDIR) -I$HOME/include -I/usr/local/include"
+MYCFLAGS="$MYCFLAGS -std=gnu99 -Wall -fsigned-char -O2 -Wfatal-errors"
+MYCPPFLAGS="-I. -I$HOME/include -I\$(INCLUDEDIR) -I/usr/local/include"
MYCPPFLAGS="$MYCPPFLAGS -D_UNICODE -DNDEBUG -D_GNU_SOURCE=1 -D_REENTRANT -D__EXTENSIONS__"
-MYLDFLAGS="-L. -L\$(LIBDIR) -L$HOME/lib -L/usr/local/lib"
+MYLDFLAGS="-L. -L\$(LIBDIR) -L$HOME/lib -L/usr/local/lib -L/usr/lib -Wl,-Bstatic"
MYCMDLDFLAGS=""
MYRUNPATH="\$(LIBDIR)"
MYLDLIBPATHENV="LD_LIBRARY_PATH"
AC_HELP_STRING([--enable-debug], [build for debugging]))
if test "$enable_debug" = "yes"
then
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -O0"
- MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -g -O0 -Wfatal-errors -Werror"
+ MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG -DEJDB_STATIC"
MYCMDLDFLAGS="$MYCMDLDFLAGS -static"
enables="$enables (debug)"
fi
AC_HELP_STRING([--enable-devel], [build for development]))
if test "$enable_devel" = "yes"
then
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -O2 -pipe"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -g -O2 -pipe"
MYCPPFLAGS="$MYCPPFLAGS -UNDEBUG"
enables="$enables (devel)"
fi
AC_HELP_STRING([--enable-profile], [build for profiling]))
if test "$enable_profile" = "yes"
then
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -g -pg -O2 -pipe"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -g -pg -O2 -pipe"
enables="$enables (profile)"
fi
if test "$enable_fastest" = "yes"
then
MYLIBOBJFILES="tokyocabinet_all.o"
- MYCFLAGS="-std=c99 -Wall -fPIC -pedantic -fsigned-char -O3"
+ MYCFLAGS="-std=gnu99 -Wall -pedantic -fsigned-char -O3"
MYCFLAGS="$MYCFLAGS -fomit-frame-pointer -fforce-addr -minline-all-stringops"
MYCPPFLAGS="$MYCPPFLAGS -D_MYFASTEST"
enables="$enables (fastest)"
enables="$enables (no-zlib)"
fi
-# Disable POSIX thread
-AC_ARG_ENABLE(pthread,
- AC_HELP_STRING([--disable-pthread], [build without POSIX thread support]))
-if test "$enable_pthread" = "no"
-then
- MYCPPFLAGS="$MYCPPFLAGS -D_MYNOPTHREAD"
- enables="$enables (no-pthread)"
-fi
-
# Disable shared object
AC_ARG_ENABLE(shared,
AC_HELP_STRING([--disable-shared], [avoid to build shared libraries]))
# Underlying libraries
AC_CHECK_LIB(c, main)
AC_CHECK_LIB(m, main)
-if test "$enable_pthread" != "no"
-then
- AC_CHECK_LIB(pthread, main)
- AC_CHECK_LIB(rt, main)
-fi
+AC_CHECK_LIB(rt, main)
+
if test "$enable_zlib" != "no"
then
AC_CHECK_LIB(z, main)
then
AC_CHECK_LIB(lzo2, main)
fi
-AC_CHECK_LIB(tcejdb, main, AC_MSG_WARN([old version of EJDB was found]))
if test "$enable_tests" = "yes"
then
AC_CHECK_HEADER(stdint.h, true, AC_MSG_ERROR([stdint.h is required]))
AC_CHECK_HEADER(unistd.h, true, AC_MSG_ERROR([unistd.h is required]))
AC_CHECK_HEADER(dirent.h, true, AC_MSG_ERROR([dirent.h is required]))
-AC_CHECK_HEADER(regex.h, true, AC_MSG_ERROR([regex.h is required]))
-AC_CHECK_HEADER(glob.h, true, AC_MSG_ERROR([glob.h is required]))
-if test "$enable_pthread" != "no"
-then
- AC_CHECK_HEADER(pthread.h, true, AC_MSG_ERROR([pthread.h is required]))
-fi
+AC_CHECK_HEADER(stddef.h, true, AC_MSG_ERROR([stddef.h is required]))
+AC_CHECK_HEADER(pthread.h, true, AC_MSG_ERROR([pthread.h is required]))
+
if test "$enable_zlib" != "no"
then
AC_CHECK_HEADER(zlib.h, true, AC_MSG_ERROR([zlib.h is required]))
AC_CHECK_HEADER(lzo/lzo1x.h, true, AC_MSG_ERROR([lzo/lzo1x.h is required]))
fi
+case $host_os in
+ mingw*)
+ AC_CHECK_HEADER(windows.h, true, AC_MSG_ERROR([windows.h is required]))
+ AC_CHECK_HEADER(time.h, true, AC_MSG_ERROR([time.h is required]))
+ ;;
+ *)
+ AC_CHECK_HEADER(glob.h, true, AC_MSG_ERROR([glob.h is required]))
+ ;;
+esac
+
+
# Shared libraries
if test "$enable_shared" != "no" && test "$enable_profile" != "yes"
then
- if uname | grep Darwin >/dev/null
- then
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.$MYLIBREV.0.dylib"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.dylib"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.dylib"
- MYLDLIBPATHENV="DYLD_LIBRARY_PATH"
- else
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER.$MYLIBREV.0"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER"
- MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so"
- fi
+ case $host_os in
+ darwin*)
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.$MYLIBREV.0.dylib"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.$MYLIBVER.dylib"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.dylib"
+ MYLDLIBPATHENV="DYLD_LIBRARY_PATH"
+ ;;
+ mingw*)
+ MYLIBRARYFILES="$MYLIBRARYFILES tcejdb.dll"
+ MYCPPFLAGS="$MYCPPFLAGS -DEJDB_DLL"
+ ;;
+ *)
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER.$MYLIBREV.0"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so.$MYLIBVER"
+ MYLIBRARYFILES="$MYLIBRARYFILES libtcejdb.so"
+ ;;
+ esac
fi
+case $host_os in
+ mingw*)
+ AC_CHECK_HEADER(pcre.h, true, AC_MSG_ERROR([pcre.h is required]))
+ AC_CHECK_HEADER(pcreposix.h, true, AC_MSG_ERROR([pcreposix.h is required]))
+ AC_CHECK_LIB(pcre, pcre_compile, [], AC_MSG_ERROR([pcre lib is required]))
+ AC_CHECK_LIB(pcreposix, regcomp, [], AC_MSG_ERROR([pcreposix lib is required]))
+ AC_CHECK_LIB(pthreadGC2, main, [], AC_MSG_ERROR([pthreadGC2 lubrary is required]))
+ MYLDFLAGS="-static-libgcc -static-libstdc++ $MYLDFLAGS"
+ MYHEADERFILES="$MYHEADERFILES win32/platform.h"
+ MYCPPFLAGS="$MYCPPFLAGS -DPCRE_STATIC -DPTW32_STATIC_LIB"
+ ;;
+ *)
+ AC_CHECK_HEADER(regex.h, true, AC_MSG_ERROR([regex.h is required]))
+ AC_CHECK_LIB(regex, regcomp, [], AC_MSG_ERROR([regex lib is required]))
+ AC_CHECK_LIB(pthread, main, [], AC_MSG_ERROR([pthread lubrary is required]))
+ MYCFLAGS="$MYCFLAGS -fPIC"
+ ;;
+esac
+
+
+
#================================================================
# Generic Settings
#================================================================
* Boston, MA 02111-1307 USA.
*************************************************************************************************/
+#include "myconf.h"
#include "bson.h"
-
-
-#include <regex.h>
#include "ejdb_private.h"
#include "ejdbutl.h"
#define JBISOPEN(JB_jb) ((JB_jb) && (JB_jb)->metadb && (JB_jb)->metadb->open) ? true : false
-#define JBISVALCOLNAME(JB_cname) ((JB_cname) && strlen(JB_cname) < JBMAXCOLNAMELEN && !index((JB_cname), '.'))
+#define JBISVALCOLNAME(JB_cname) ((JB_cname) && strlen(JB_cname) < JBMAXCOLNAMELEN && !strchr((JB_cname), '.'))
#define JBENSUREOPENLOCK(JB_jb, JB_lock, JB_ret) \
assert(JB_jb); \
static bool _metasetopts(EJDB *jb, const char *colname, EJCOLLOPTS *opts);
static bool _metagetopts(EJDB *jb, const char *colname, EJCOLLOPTS *opts);
static bson* _metagetbson(EJDB *jb, const char *colname, int colnamesz, const char *mkey);
-static bson* _metagetbson2(EJCOLL *jcoll, const char *mkey);
+static bson* _metagetbson2(EJCOLL *jcoll, const char *mkey) __attribute__ ((unused));
static bool _metasetbson(EJDB *jb, const char *colname, int colnamesz,
const char *mkey, bson *val, bool merge, bool mergeoverwrt);
static bool _metasetbson2(EJCOLL *jcoll, const char *mkey, bson *val, bool merge, bool mergeoverwrt);
static const bool yes = true;
static const bool no = false;
-EJDB_EXPORT const char* ejdberrmsg(int ecode) {
+ const char* ejdberrmsg(int ecode) {
if (ecode > -6 && ecode < 0) { //Hook for negative error codes of utf8proc library
return utf8proc_errmsg(ecode);
}
}
}
-EJDB_EXPORT bool ejdbisvalidoidstr(const char *oid) {
+ bool ejdbisvalidoidstr(const char *oid) {
if (!oid) {
return false;
}
}
/* Get the last happened error code of a database object. */
-EJDB_EXPORT int ejdbecode(EJDB *jb) {
+ int ejdbecode(EJDB *jb) {
assert(jb && jb->metadb);
return tctdbecode(jb->metadb);
}
-EJDB_EXPORT EJDB* ejdbnew(void) {
+ EJDB* ejdbnew(void) {
EJDB *jb;
TCCALLOC(jb, 1, sizeof (*jb));
jb->metadb = tctdbnew();
return jb;
}
-EJDB_EXPORT void ejdbdel(EJDB *jb) {
+ void ejdbdel(EJDB *jb) {
assert(jb && jb->metadb);
if (JBISOPEN(jb)) ejdbclose(jb);
for (int i = 0; i < jb->cdbsnum; ++i) {
TCFREE(jb);
}
-EJDB_EXPORT bool ejdbclose(EJDB *jb) {
+ bool ejdbclose(EJDB *jb) {
JBENSUREOPENLOCK(jb, true, false);
bool rv = true;
for (int i = 0; i < jb->cdbsnum; ++i) {
return rv;
}
-EJDB_EXPORT bool ejdbisopen(EJDB *jb) {
+ bool ejdbisopen(EJDB *jb) {
return JBISOPEN(jb);
}
-EJDB_EXPORT bool ejdbopen(EJDB *jb, const char *path, int mode) {
+ bool ejdbopen(EJDB *jb, const char *path, int mode) {
assert(jb && path);
assert(jb->metadb);
if (!JBLOCKMETHOD(jb, true)) return false;
return rv;
}
-EJDB_EXPORT EJCOLL* ejdbgetcoll(EJDB *jb, const char *colname) {
+ EJCOLL* ejdbgetcoll(EJDB *jb, const char *colname) {
assert(colname);
EJCOLL *coll = NULL;
JBENSUREOPENLOCK(jb, false, NULL);
return coll;
}
-EJDB_EXPORT TCLIST* ejdbgetcolls(EJDB *jb) {
+ TCLIST* ejdbgetcolls(EJDB *jb) {
assert(jb);
EJCOLL *coll = NULL;
JBENSUREOPENLOCK(jb, false, NULL);
return ret;
}
-EJDB_EXPORT EJCOLL* ejdbcreatecoll(EJDB *jb, const char *colname, EJCOLLOPTS *opts) {
+ EJCOLL* ejdbcreatecoll(EJDB *jb, const char *colname, EJCOLLOPTS *opts) {
assert(colname);
EJCOLL *coll = ejdbgetcoll(jb, colname);
if (coll) {
return coll;
}
-EJDB_EXPORT bool ejdbrmcoll(EJDB *jb, const char *colname, bool unlinkfile) {
+ bool ejdbrmcoll(EJDB *jb, const char *colname, bool unlinkfile) {
assert(colname);
JBENSUREOPENLOCK(jb, true, false);
bool rv = true;
}
/* Save/Update BSON */
-EJDB_EXPORT bool ejdbsavebson(EJCOLL *jcoll, bson *bs, bson_oid_t *oid) {
+ bool ejdbsavebson(EJCOLL *jcoll, bson *bs, bson_oid_t *oid) {
return ejdbsavebson2(jcoll, bs, oid, false);
}
-EJDB_EXPORT bool ejdbsavebson2(EJCOLL *jcoll, bson *bs, bson_oid_t *oid, bool merge) {
+ bool ejdbsavebson2(EJCOLL *jcoll, bson *bs, bson_oid_t *oid, bool merge) {
assert(jcoll);
if (!bs || bs->err || !bs->finished) {
_ejdbsetecode(jcoll->jb, JBEINVALIDBSON, __FILE__, __LINE__, __func__);
return rv;
}
-EJDB_EXPORT bool ejdbrmbson(EJCOLL *jcoll, bson_oid_t *oid) {
+ bool ejdbrmbson(EJCOLL *jcoll, bson_oid_t *oid) {
assert(jcoll && oid);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return rv;
}
-EJDB_EXPORT bson* ejdbloadbson(EJCOLL *jcoll, const bson_oid_t *oid) {
+ bson* ejdbloadbson(EJCOLL *jcoll, const bson_oid_t *oid) {
assert(jcoll && oid);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return ret;
}
-EJDB_EXPORT EJQ* ejdbcreatequery(EJDB *jb, bson *qobj, bson *orqobjs, int orqobjsnum, bson *hints) {
+ EJQ* ejdbcreatequery(EJDB *jb, bson *qobj, bson *orqobjs, int orqobjsnum, bson *hints) {
assert(jb);
if (!qobj || qobj->err || !qobj->finished) {
_ejdbsetecode(jb, JBEINVALIDBSON, __FILE__, __LINE__, __func__);
return NULL;
}
-EJDB_EXPORT void ejdbquerydel(EJQ *q) {
+ void ejdbquerydel(EJQ *q) {
_qrydel(q, true);
}
/** Set index */
-EJDB_EXPORT bool ejdbsetindex(EJCOLL *jcoll, const char *fpath, int flags) {
+ bool ejdbsetindex(EJCOLL *jcoll, const char *fpath, int flags) {
assert(jcoll && fpath);
bool rv = true;
bson *imeta = NULL;
return rv;
}
-EJDB_EXPORT uint32_t ejdbupdate(EJCOLL *jcoll, bson *qobj, bson *orqobjs, int orqobjsnum, bson *hints, TCXSTR *log) {
+ uint32_t ejdbupdate(EJCOLL *jcoll, bson *qobj, bson *orqobjs, int orqobjsnum, bson *hints, TCXSTR *log) {
assert(jcoll);
uint32_t count = 0;
EJQ *q = ejdbcreatequery(jcoll->jb, qobj, orqobjs, orqobjsnum, hints);
return count;
}
-EJDB_EXPORT TCLIST* ejdbqryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *count, int qflags, TCXSTR *log) {
+ TCLIST* ejdbqryexecute(EJCOLL *jcoll, const EJQ *q, uint32_t *count, int qflags, TCXSTR *log) {
assert(jcoll && q && q->qobjlist);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return res;
}
-EJDB_EXPORT bool ejdbsyncoll(EJCOLL *jcoll) {
+ bool ejdbsyncoll(EJCOLL *jcoll) {
assert(jcoll);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return rv;
}
-EJDB_EXPORT bool ejdbsyncdb(EJDB *jb) {
+ bool ejdbsyncdb(EJDB *jb) {
assert(jb);
JBENSUREOPENLOCK(jb, true, false);
bool rv = true;
return rv;
}
-EJDB_EXPORT bool ejdbtranbegin(EJCOLL *jcoll) {
+ bool ejdbtranbegin(EJCOLL *jcoll) {
assert(jcoll);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
- for (double wsec = 1.0 / sysconf(_SC_CLK_TCK); true; wsec *= 2) {
+ for (double wsec = 1.0 / sysconf_SC_CLK_TCK; true; wsec *= 2) {
if (!JBCLOCKMETHOD(jcoll, true)) return false;
if (!jcoll->tdb->open || !jcoll->tdb->wmode) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return true;
}
-EJDB_EXPORT bool ejdbtrancommit(EJCOLL *jcoll) {
+ bool ejdbtrancommit(EJCOLL *jcoll) {
assert(jcoll);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return !err;
}
-EJDB_EXPORT bool ejdbtranabort(EJCOLL *jcoll) {
+ bool ejdbtranabort(EJCOLL *jcoll) {
assert(jcoll);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return !err;
}
-EJDB_EXPORT bool ejdbtranstatus(EJCOLL *jcoll, bool *txactive) {
+ bool ejdbtranstatus(EJCOLL *jcoll, bool *txactive) {
assert(jcoll && txactive);
if (!JBISOPEN(jcoll->jb)) {
_ejdbsetecode(jcoll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
/* Set mutual exclusion control of a table database object for threading. */
static bool _ejdbsetmutex(EJDB *ejdb) {
assert(ejdb);
- if (!TCUSEPTHREAD) return true;
if (ejdb->mmtx || JBISOPEN(ejdb)) {
_ejdbsetecode(ejdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
static bool _ejdbcolsetmutex(EJCOLL *coll) {
assert(coll && coll->jb);
- if (!TCUSEPTHREAD) return true;
if (coll->mmtx) {
_ejdbsetecode(coll->jb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
#ifndef EJDB_H
#define EJDB_H
-#include "myconf.h"
#include "bson.h"
#include "tcutil.h"
*************************************************************************************************/
#ifndef EJDB_PRIVATE_H
-#define EJDB_PRIVATE_H
+#define EJDB_PRIVATE_H
#include "ejdb.h"
-
-#include "myconf.h"
#include "tcutil.h"
#include "tctdb.h"
#include "tchdb.h"
#include <limits.h>
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
/* Byte-wise swap two items of size SIZE. */
#define SWAP(a, b, size) \
*************************************************************************************************/
#ifndef EJDBUTL_H
-#define EJDBUTL_H
+#define EJDBUTL_H
-#include "myconf.h"
#include "tcutil.h"
EJDB_EXTERN_C_START
#endif
-
+#include "basedefs.h"
/*************************************************************************************************
* common settings
*************************************************************************************************/
-#ifdef __cplusplus
-#define EJDB_EXTERN_C_START extern "C" {
-#define EJDB_EXTERN_C_END }
-#else
-#define EJDB_EXTERN_C_START
-#define EJDB_EXTERN_C_END
-#endif
-
-#ifdef __GNUC__
-#define EJDB_INLINE static __inline__
-#define EJDB_EXPORT
-#else
-#define EJDB_INLINE static
-#ifdef EJDB_STATIC_BUILD
-#define EJDB_EXPORT
-#elif defined(MONGO_DLL_BUILD)
-#define EJDB_EXPORT __declspec(dllexport)
-#else
-#define EJDB_EXPORT __declspec(dllimport)
-#endif
-#endif
-
#if defined(NDEBUG)
#define TCDODEBUG(TC_expr) \
#if defined(_MYNOUBC) || defined(__hppa__)
#define TCUBCACHE 0
#elif defined(_SYS_LINUX_) || defined(_SYS_FREEBSD_) || defined(_SYS_NETBSD_) || \
- defined(_SYS_MACOSX_) || defined(_SYS_SUNOS_)
+ defined(_SYS_MACOSX_) || defined(_SYS_SUNOS_) || defined(_WIN32)
#define TCUBCACHE 1
#else
#define TCUBCACHE 0
#define TCUSEEXLZO 0
#endif
-#if defined(_MYNOPTHREAD)
-#define TCUSEPTHREAD 0
-#else
-#define TCUSEPTHREAD 1
-#endif
-
#if defined(_MYMICROYIELD)
#define TCMICROYIELD 1
#else
*************************************************************************************************/
+#ifdef _WIN32
+#include <pcreposix.h>
+#include "win32/platform.h"
+#define GET_STDOUT_HANDLE() GetStdHandle(STD_OUTPUT_HANDLE)
+#define GET_STDERR_HANDLE() GetStdHandle(STD_ERROR_HANDLE)
+#define GET_STDIN_HANDLE() GetStdHandle(STD_INPUT_HANDLE)
+#define CLOSEFH(_fd) (CloseHandle(_fd))
+#else
+#include <regex.h>
+#include <glob.h>
+#include <sys/mman.h>
+#include <sys/times.h>
+#include <sys/wait.h>
+#include <sys/resource.h>
+#define GET_STDOUT_HANDLE() (1)
+#define GET_STDERR_HANDLE() (2)
+#define GET_STDIN_HANDLE() (0)
+#define CLOSEFH(_fd) (close(_fd) != -1)
+#define sysconf_SC_CLK_TCK sysconf(_SC_CLK_TCK)
+#endif
+
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/mman.h>
#include <sys/time.h>
-#include <sys/times.h>
-#include <sys/wait.h>
-#include <sys/resource.h>
+
#include <fcntl.h>
#include <dirent.h>
-#include <regex.h>
-#include <glob.h>
-
-#if TCUSEPTHREAD
#include <pthread.h>
+
#if defined(_POSIX_PRIORITY_SCHEDULING)
#include <sched.h>
#endif
-#endif
-
-
/*************************************************************************************************
* miscellaneous hacks
* notation of filesystems
*************************************************************************************************/
-
+#ifdef _WIN32
+#define MYPATHCHR '\\'
+#define MYPATHSTR "\\"
+#else
#define MYPATHCHR '/'
#define MYPATHSTR "/"
+#endif
+
#define MYEXTCHR '.'
#define MYEXTSTR "."
#define MYCDIRSTR "."
void *_tc_recdecode(const void *ptr, int size, int *sp, void *op);
-
-
-/*************************************************************************************************
- * for POSIX thread disability
- *************************************************************************************************/
-
-
-#if ! TCUSEPTHREAD
-
-#define pthread_t intptr_t
-
-#define pthread_once_t intptr_t
-#undef PTHREAD_ONCE_INIT
-#define PTHREAD_ONCE_INIT 0
-#define pthread_once(TC_a, TC_b) _tc_dummyfuncv((intptr_t)(TC_a), (TC_b))
-
-#define pthread_mutexattr_t intptr_t
-#undef PTHREAD_MUTEX_RECURSIVE
-#define PTHREAD_MUTEX_RECURSIVE 0
-#define pthread_mutexattr_init(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_mutexattr_destroy(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_mutexattr_settype(TC_a, TC_b) _tc_dummyfuncv((intptr_t)(TC_a), (TC_b))
-
-#define pthread_mutex_t intptr_t
-#undef PTHREAD_MUTEX_INITIALIZER
-#define PTHREAD_MUTEX_INITIALIZER 0
-#define pthread_mutex_init(TC_a, TC_b) _tc_dummyfuncv((intptr_t)(TC_a), (TC_b))
-#define pthread_mutex_destroy(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_mutex_lock(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_mutex_unlock(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-
-#define pthread_rwlock_t intptr_t
-#undef PTHREAD_RWLOCK_INITIALIZER
-#define PTHREAD_RWLOCK_INITIALIZER 0
-#define pthread_rwlock_init(TC_a, TC_b) _tc_dummyfuncv((intptr_t)(TC_a), (TC_b))
-#define pthread_rwlock_destroy(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_rwlock_rdlock(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_rwlock_wrlock(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_rwlock_unlock(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-
-#define pthread_key_t intptr_t
-#define pthread_key_create(TC_a, TC_b) _tc_dummyfuncv((intptr_t)(TC_a), (TC_b))
-#define pthread_key_delete(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_setspecific(TC_a, TC_b) _tc_dummyfuncv((intptr_t)(TC_a))
-#define pthread_getspecific(TC_a) _tc_dummyfuncv((intptr_t)(TC_a))
-
-#define pthread_create(TC_th, TC_attr, TC_func, TC_arg) \
- (*(TC_th) = 0, (TC_func)(TC_arg), 0)
-#define pthread_join(TC_th, TC_rv) (*(TC_rv) = NULL, 0)
-#define pthread_detach(TC_th) 0
-#define sched_yield() _tc_dummyfunc()
-
-#endif
-
-#if TCUSEPTHREAD && TCMICROYIELD
+#if TCMICROYIELD
#define TCTESTYIELD() \
do { \
if(((++_tc_dummy_cnt) & (0x20 - 1)) == 0){ \
} while(false)
#endif
-#if !defined(_POSIX_PRIORITY_SCHEDULING) && TCUSEPTHREAD
+#ifndef _POSIX_PRIORITY_SCHEDULING
#define sched_yield() usleep(1000 * 20)
#endif
#endif // duplication check
-
-//EJDB Shared
-
-#define JDBIDKEYNAME "_id" /**> Name of PK _id field in BSONs */
-#define JDBIDKEYNAMEL 3
-
-
// END OF FILE
--- /dev/null
+#ifdef _WIN32
+#include "win32/platform.c"
+#endif
tclistdel(elems);
return false;
}
- int dbgfd = -1;
+ HANDLE dbgfd = INVALID_HANDLE_VALUE;
int64_t bnum = -1;
int64_t capnum = -1;
int64_t capsiz = -1;
if(!pv) continue;
*(pv++) = '\0';
if(!tcstricmp(elem, "dbgfd")){
- dbgfd = tcatoi(pv);
+ int dbgdescr = tcatoi(pv);
+#ifndef _WIN32
+ dbgfd = dbgdescr;
+#else
+ dbgfd = (HANDLE)_get_osfhandle(dbgdescr);
+#endif
} else if(!tcstricmp(elem, "bnum")){
bnum = tcatoix(pv);
} else if(!tcstricmp(elem, "capnum")){
adb->omode = ADBONDB;
} else if(tcstribwm(path, ".tch") || tcstribwm(path, ".hdb")){
TCHDB *hdb = tchdbnew();
- if(dbgfd >= 0) tchdbsetdbgfd(hdb, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tchdbsetdbgfd(hdb, dbgfd);
tchdbsetmutex(hdb);
int opts = 0;
if(tlmode) opts |= HDBTLARGE;
adb->omode = ADBOHDB;
} else if(tcstribwm(path, ".tcb") || tcstribwm(path, ".bdb")){
TCBDB *bdb = tcbdbnew();
- if(dbgfd >= 0) tcbdbsetdbgfd(bdb, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(bdb, dbgfd);
tcbdbsetmutex(bdb);
int opts = 0;
if(tlmode) opts |= BDBTLARGE;
adb->omode = ADBOBDB;
} else if(tcstribwm(path, ".tcf") || tcstribwm(path, ".fdb")){
TCFDB *fdb = tcfdbnew();
- if(dbgfd >= 0) tcfdbsetdbgfd(fdb, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcfdbsetdbgfd(fdb, dbgfd);
tcfdbsetmutex(fdb);
tcfdbtune(fdb, width, limsiz);
int omode = owmode ? FDBOWRITER : FDBOREADER;
adb->omode = ADBOFDB;
} else if(tcstribwm(path, ".tct") || tcstribwm(path, ".tdb")){
TCTDB *tdb = tctdbnew();
- if(dbgfd >= 0) tctdbsetdbgfd(tdb, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tctdbsetdbgfd(tdb, dbgfd);
tctdbsetmutex(tdb);
int opts = 0;
if(tlmode) opts |= TDBTLARGE;
break;
case ADBOTDB:
if(ksiz < 1){
- ksiz = sprintf(numbuf, "%lld", (long long)tctdbgenuid(adb->tdb));
+ ksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(adb->tdb));
kbuf = numbuf;
}
if(!tctdbput2(adb->tdb, kbuf, ksiz, vbuf, vsiz)) err = true;
break;
case ADBOTDB:
if(ksiz < 1){
- ksiz = sprintf(numbuf, "%lld", (long long)tctdbgenuid(adb->tdb));
+ ksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(adb->tdb));
kbuf = numbuf;
}
if(!tctdbputkeep2(adb->tdb, kbuf, ksiz, vbuf, vsiz)) err = true;
break;
case ADBOTDB:
if(ksiz < 1){
- ksiz = sprintf(numbuf, "%lld", (long long)tctdbgenuid(adb->tdb));
+ ksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(adb->tdb));
kbuf = numbuf;
}
if(!tctdbputcat2(adb->tdb, kbuf, ksiz, vbuf, vsiz)) err = true;
break;
case ADBOTDB:
if(ksiz < 1){
- ksiz = sprintf(numbuf, "%lld", (long long)tctdbgenuid(adb->tdb));
+ ksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(adb->tdb));
kbuf = numbuf;
}
rv = tctdbaddint(adb->tdb, kbuf, ksiz, num);
break;
case ADBOTDB:
if(ksiz < 1){
- ksiz = sprintf(numbuf, "%lld", (long long)tctdbgenuid(adb->tdb));
+ ksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(adb->tdb));
kbuf = numbuf;
}
rv = tctdbadddouble(adb->tdb, kbuf, ksiz, num);
case ADBONDB:
if(*path == '@'){
char tsbuf[TCNUMBUFSIZ];
- sprintf(tsbuf, "%llu", (unsigned long long)(tctime() * 1000000));
+ sprintf(tsbuf, "%" PRIuMAX "", (unsigned long long)(tctime() * 1000000));
const char *args[2];
args[0] = path + 1;
args[1] = tsbuf;
} else if(!strcmp(name, "genuid")){
rv = tclistnew2(1);
char numbuf[TCNUMBUFSIZ];
- int nsiz = sprintf(numbuf, "%lld", (long long)tctdbgenuid(adb->tdb));
+ int nsiz = sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(adb->tdb));
TCLISTPUSH(rv, numbuf, nsiz);
} else {
rv = NULL;
if(!tcadbcopy(adbs[i], path)) err = true;
}
} else {
- if(mkdir(path, ADBDIRMODE) == -1 && errno != EEXIST) return false;
+ if(mkdir(path, ADBDIRMODE) && errno != EEXIST) return false;
for(int i = 0; i < num; i++){
TCADB *adb = adbs[i];
const char *cpath = tcadbpath(adb);
/* Create an abstract database object.
The return value is the new abstract database object. */
-TCADB *tcadbnew(void);
+EJDB_EXPORT TCADB *tcadbnew(void);
/* Delete an abstract database object.
`adb' specifies the abstract database object. */
-void tcadbdel(TCADB *adb);
+EJDB_EXPORT void tcadbdel(TCADB *adb);
/* Open an abstract database.
of TCBS option. "idx" specifies the column name of an index and its type separated by ":".
For example, "casket.tch#bnum=1000000#opts=ld" means that the name of the database file is
"casket.tch", and the bucket number is 1000000, and the options are large and Deflate. */
-bool tcadbopen(TCADB *adb, const char *name);
+EJDB_EXPORT bool tcadbopen(TCADB *adb, const char *name);
/* Close an abstract database object.
If successful, the return value is true, else, it is false.
Update of a database is assured to be written when the database is closed. If a writer opens
a database but does not close it appropriately, the database will be broken. */
-bool tcadbclose(TCADB *adb);
+EJDB_EXPORT bool tcadbclose(TCADB *adb);
/* Store a record into an abstract database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tcadbput(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcadbput(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into an abstract object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tcadbput2(TCADB *adb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcadbput2(TCADB *adb, const char *kstr, const char *vstr);
/* Store a new record into an abstract database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcadbputkeep(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcadbputkeep(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into an abstract database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcadbputkeep2(TCADB *adb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcadbputkeep2(TCADB *adb, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the existing record in an abstract database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tcadbputcat(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcadbputcat(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string value at the end of the existing record in an abstract database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tcadbputcat2(TCADB *adb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcadbputcat2(TCADB *adb, const char *kstr, const char *vstr);
/* Remove a record of an abstract database object.
`kbuf' specifies the pointer to the region of the key.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true, else, it is false. */
-bool tcadbout(TCADB *adb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcadbout(TCADB *adb, const void *kbuf, int ksiz);
/* Remove a string record of an abstract database object.
`adb' specifies the abstract database object.
`kstr' specifies the string of the key.
If successful, the return value is true, else, it is false. */
-bool tcadbout2(TCADB *adb, const char *kstr);
+EJDB_EXPORT bool tcadbout2(TCADB *adb, const char *kstr);
/* Retrieve a record in an abstract database object.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tcadbget(TCADB *adb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcadbget(TCADB *adb, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in an abstract database object.
`NULL' is returned if no record corresponds.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcadbget2(TCADB *adb, const char *kstr);
+EJDB_EXPORT char *tcadbget2(TCADB *adb, const char *kstr);
/* Get the size of the value of a record in an abstract database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tcadbvsiz(TCADB *adb, const void *kbuf, int ksiz);
+EJDB_EXPORT int tcadbvsiz(TCADB *adb, const void *kbuf, int ksiz);
/* Get the size of the value of a string record in an abstract database object.
`kstr' specifies the string of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tcadbvsiz2(TCADB *adb, const char *kstr);
+EJDB_EXPORT int tcadbvsiz2(TCADB *adb, const char *kstr);
/* Initialize the iterator of an abstract database object.
`adb' specifies the abstract database object.
If successful, the return value is true, else, it is false.
The iterator is used in order to access the key of every record stored in a database. */
-bool tcadbiterinit(TCADB *adb);
+EJDB_EXPORT bool tcadbiterinit(TCADB *adb);
/* Get the next key of the iterator of an abstract database object.
However, it is not assured if updating the database is occurred while the iteration. Besides,
the order of this traversal access method is arbitrary, so it is not assured that the order of
storing matches the one of the traversal access. */
-void *tcadbiternext(TCADB *adb, int *sp);
+EJDB_EXPORT void *tcadbiternext(TCADB *adb, int *sp);
/* Get the next key string of the iterator of an abstract database object.
database is occurred while the iteration. Besides, the order of this traversal access method
is arbitrary, so it is not assured that the order of storing matches the one of the traversal
access. */
-char *tcadbiternext2(TCADB *adb);
+EJDB_EXPORT char *tcadbiternext2(TCADB *adb);
/* Get forward matching keys in an abstract database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tcadbfwmkeys(TCADB *adb, const void *pbuf, int psiz, int max);
+EJDB_EXPORT TCLIST *tcadbfwmkeys(TCADB *adb, const void *pbuf, int psiz, int max);
/* Get forward matching string keys in an abstract database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tcadbfwmkeys2(TCADB *adb, const char *pstr, int max);
+EJDB_EXPORT TCLIST *tcadbfwmkeys2(TCADB *adb, const char *pstr, int max);
/* Add an integer to a record in an abstract database object.
If successful, the return value is the summation value, else, it is `INT_MIN'.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tcadbaddint(TCADB *adb, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tcadbaddint(TCADB *adb, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in an abstract database object.
If successful, the return value is the summation value, else, it is Not-a-Number.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tcadbadddouble(TCADB *adb, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tcadbadddouble(TCADB *adb, const void *kbuf, int ksiz, double num);
/* Synchronize updated contents of an abstract database object with the file and the device.
`adb' specifies the abstract database object.
If successful, the return value is true, else, it is false. */
-bool tcadbsync(TCADB *adb);
+EJDB_EXPORT bool tcadbsync(TCADB *adb);
/* Optimize the storage of an abstract database object.
If successful, the return value is true, else, it is false.
This function is useful to reduce the size of the database storage with data fragmentation by
successive updating. */
-bool tcadboptimize(TCADB *adb, const char *params);
+EJDB_EXPORT bool tcadboptimize(TCADB *adb, const char *params);
/* Remove all records of an abstract database object.
`adb' specifies the abstract database object.
If successful, the return value is true, else, it is false. */
-bool tcadbvanish(TCADB *adb);
+EJDB_EXPORT bool tcadbvanish(TCADB *adb);
/* Copy the database file of an abstract database object.
The database file is assured to be kept synchronized and not modified while the copying or
executing operation is in progress. So, this function is useful to create a backup file of
the database file. */
-bool tcadbcopy(TCADB *adb, const char *path);
+EJDB_EXPORT bool tcadbcopy(TCADB *adb, const char *path);
/* Begin the transaction of an abstract database object.
assumed if every database operation is performed in the transaction. All updated regions are
kept track of by write ahead logging while the transaction. If the database is closed during
transaction, the transaction is aborted implicitly. */
-bool tcadbtranbegin(TCADB *adb);
+EJDB_EXPORT bool tcadbtranbegin(TCADB *adb);
/* Commit the transaction of an abstract database object.
`adb' specifies the abstract database object.
If successful, the return value is true, else, it is false.
Update in the transaction is fixed when it is committed successfully. */
-bool tcadbtrancommit(TCADB *adb);
+EJDB_EXPORT bool tcadbtrancommit(TCADB *adb);
/* Abort the transaction of an abstract database object.
If successful, the return value is true, else, it is false.
Update in the transaction is discarded when it is aborted. The state of the database is
rollbacked to before transaction. */
-bool tcadbtranabort(TCADB *adb);
+EJDB_EXPORT bool tcadbtranabort(TCADB *adb);
/* Get the file path of an abstract database object.
The return value is the path of the database file or `NULL' if the object does not connect to
any database. "*" stands for on-memory hash database. "+" stands for on-memory tree
database. */
-const char *tcadbpath(TCADB *adb);
+EJDB_EXPORT const char *tcadbpath(TCADB *adb);
/* Get the number of records of an abstract database object.
`adb' specifies the abstract database object.
The return value is the number of records or 0 if the object does not connect to any database
instance. */
-uint64_t tcadbrnum(TCADB *adb);
+EJDB_EXPORT uint64_t tcadbrnum(TCADB *adb);
/* Get the size of the database of an abstract database object.
`adb' specifies the abstract database object.
The return value is the size of the database or 0 if the object does not connect to any
database instance. */
-uint64_t tcadbsize(TCADB *adb);
+EJDB_EXPORT uint64_t tcadbsize(TCADB *adb);
/* Call a versatile function for miscellaneous operations of an abstract database object.
If successful, the return value is a list object of the result. `NULL' is returned on failure.
Because the object of the return value is created with the function `tclistnew', it
should be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcadbmisc(TCADB *adb, const char *name, const TCLIST *args);
+EJDB_EXPORT TCLIST *tcadbmisc(TCADB *adb, const char *name, const TCLIST *args);
`adb' specifies the abstract database object.
`skel' specifies the extra database skeleton.
If successful, the return value is true, else, it is false. */
-bool tcadbsetskel(TCADB *adb, ADBSKEL *skel);
+EJDB_EXPORT bool tcadbsetskel(TCADB *adb, ADBSKEL *skel);
/* Set the multiple database skeleton to an abstract database object.
`adb' specifies the abstract database object.
`num' specifies the number of inner databases.
If successful, the return value is true, else, it is false. */
-bool tcadbsetskelmulti(TCADB *adb, int num);
+EJDB_EXPORT bool tcadbsetskelmulti(TCADB *adb, int num);
/* Get the open mode of an abstract database object.
The return value is `ADBOVOID' for not opened database, `ADBOMDB' for on-memory hash database,
`ADBONDB' for on-memory tree database, `ADBOHDB' for hash database, `ADBOBDB' for B+ tree
database, `ADBOFDB' for fixed-length database, `ADBOTDB' for table database. */
-int tcadbomode(TCADB *adb);
+EJDB_EXPORT int tcadbomode(TCADB *adb);
/* Get the concrete database object of an abstract database object.
`adb' specifies the abstract database object.
The return value is the concrete database object depend on the open mode or 0 if the object
does not connect to any database instance. */
-void *tcadbreveal(TCADB *adb);
+EJDB_EXPORT void *tcadbreveal(TCADB *adb);
/* Store a record into an abstract database object with a duplication handler.
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false.
This function does not work for the table database. */
-bool tcadbputproc(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tcadbputproc(TCADB *adb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
`op' specifies an arbitrary pointer to be given as a parameter of the iterator function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tcadbforeach(TCADB *adb, TCITER iter, void *op);
+EJDB_EXPORT bool tcadbforeach(TCADB *adb, TCITER iter, void *op);
/* Map records of an abstract database object into another B+ tree database.
`csiz' specifies the size of the cache to sort emitted records. If it is negative, the
default size is specified. The default size is 268435456.
If successful, the return value is true, else, it is false. */
-bool tcadbmapbdb(TCADB *adb, TCLIST *keys, TCBDB *bdb, ADBMAPPROC proc, void *op, int64_t csiz);
+EJDB_EXPORT bool tcadbmapbdb(TCADB *adb, TCLIST *keys, TCBDB *bdb, ADBMAPPROC proc, void *op, int64_t csiz);
/* Emit records generated by the mapping function into the result map.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false. */
-bool tcadbmapbdbemit(void *map, const char *kbuf, int ksiz, const char *vbuf, int vsiz);
+EJDB_EXPORT bool tcadbmapbdbemit(void *map, const char *kbuf, int ksiz, const char *vbuf, int vsiz);
case ADBOSKEL: type = "skeleton database"; break;
}
printf("database type: %s\n", type);
- printf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- printf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ printf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ printf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
if(!tcadbclose(adb)){
printerr(adb);
err = true;
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
putchar(c);
fflush(stdout);
}
-
-
/* print error message of abstract database */
-static void eprint(TCADB *adb, int line, const char *func){
- const char *path = adb ? tcadbpath(adb) : NULL;
- fprintf(stderr, "%s: %s: %d: %s: error\n", g_progname, path ? path : "-", line, func);
+static void eprint(TCADB *adb, int line, const char *func) {
+ const char *path = adb ? tcadbpath(adb) : NULL;
+#ifdef _WIN32
+ DWORD winerrno = GetLastError();
+#endif
+ int stderrno = errno;
+#ifdef _WIN32
+ LPTSTR errorText = NULL;
+ if (winerrno > 0) {
+ DWORD ret = FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, winerrno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) & errorText, 0, NULL);
+ if (!ret) {
+ if (errorText) LocalFree(errorText);
+ errorText = NULL;
+ }
+ }
+ fprintf(stderr,
+ "ERROR:%s:%d:%s:%s:%d:%s:%d:%s\n",
+ g_progname, line,
+ func, (path ? path : "-"),
+ winerrno, (errorText ? errorText : "-"),
+ stderrno, (stderrno > 0 ? strerror(stderrno) : "-"));
+ if (errorText) LocalFree(errorText);
+#else
+ fprintf(stderr,
+ "ERROR:%s:%d:%s:%s:%d:%s\n",
+ g_progname, line,
+ func, (path ? path : "-"),
+ stderrno, strerror(stderrno));
+#endif
}
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
eprint(adb, __LINE__, "tcadbforeach");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
if(!tcadbclose(adb)){
eprint(adb, __LINE__, "tcadbclose");
eprint(adb, __LINE__, "(validation)");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tcadbrnum(adb));
- iprintf("size: %llu\n", (unsigned long long)tcadbsize(adb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcadbrnum(adb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcadbsize(adb));
sysprint();
tcmapdel(map);
if(!tcadbclose(adb)){
TCMDB *mdb = tcmdbnew2(rnum / 2);
TCNDB *ndb = tcndbnew();
TCHDB *hdb = tchdbnew();
- tchdbsetdbgfd(hdb, UINT16_MAX);
+ tchdbsetdbgfd(hdb, INVALID_HANDLE_VALUE);
int hopts = 0;
if(myrand(2) == 1) hopts |= HDBTLARGE;
if(myrand(2) == 1) hopts |= HDBTBZIP;
err = true;
}
TCBDB *bdb = tcbdbnew();
- tcbdbsetdbgfd(bdb, UINT16_MAX);
+ tcbdbsetdbgfd(bdb, INVALID_HANDLE_VALUE);
int bopts = 0;
if(myrand(2) == 1) bopts |= BDBTLARGE;
if(myrand(2) == 1) bopts |= BDBTBZIP;
/* set the footer of HTML */
static void sethtmlfooter(PARAMS *params, TCXSTR *obuf, TCADB *db){
XP("<hr />\n");
- XP("<div>record number: %lld</div>\n", (long long)tcadbrnum(db));
- XP("<div>size: %lld</div>\n", (long long)tcadbsize(db));
+ XP("<div>record number: %" PRIdMAX "</div>\n", (long long)tcadbrnum(db));
+ XP("<div>size: %" PRIdMAX "</div>\n", (long long)tcadbsize(db));
XP("</body>\n");
XP("\n");
XP("</html>\n");
/* Set mutual exclusion control of a B+ tree database object for threading. */
bool tcbdbsetmutex(TCBDB *bdb){
assert(bdb);
- if(!TCUSEPTHREAD) return true;
if(bdb->mmtx || bdb->open){
tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
/* Begin the transaction of a B+ tree database object. */
bool tcbdbtranbegin(TCBDB *bdb){
assert(bdb);
- for(double wsec = 1.0 / sysconf(_SC_CLK_TCK); true; wsec *= 2){
+ for(double wsec = 1.0 / sysconf_SC_CLK_TCK; true; wsec *= 2){
if(!BDBLOCKMETHOD(bdb, true)) return false;
if(!bdb->open || !bdb->wmode){
tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
bdb->tran = true;
- TCMEMDUP(bdb->rbopaque, bdb->opaque, BDBOPAQUESIZ);
+ TCMALLOC(bdb->rbopaque, BDBOPAQUESIZ);
+ tchdbreadopaque(bdb->hdb, bdb->rbopaque, 0, BDBOPAQUESIZ);
BDBUNLOCKMETHOD(bdb);
return true;
}
return false;
}
tcbdbcachepurge(bdb);
- memcpy(bdb->opaque, bdb->rbopaque, BDBOPAQUESIZ);
+ tchdbwriteopaque(bdb->hdb, bdb->rbopaque, 0, BDBOPAQUESIZ);
tcbdbloadmeta(bdb);
TCFREE(bdb->rbopaque);
bdb->tran = false;
/* Set the file descriptor for debugging output. */
-void tcbdbsetdbgfd(TCBDB *bdb, int fd){
- assert(bdb && fd >= 0);
+void tcbdbsetdbgfd(TCBDB *bdb, HANDLE fd){
+ assert(bdb && !INVALIDHANDLE(fd));
tchdbsetdbgfd(bdb->hdb, fd);
}
/* Get the file descriptor for debugging output. */
-int tcbdbdbgfd(TCBDB *bdb){
+HANDLE tcbdbdbgfd(TCBDB *bdb){
assert(bdb);
return tchdbdbgfd(bdb->hdb);
}
}
-/* Get the pointer to the opaque field of a B+ tree database object. */
-char *tcbdbopaque(TCBDB *bdb){
- assert(bdb);
- if(!bdb->open){
- tcbdbsetecode(bdb, TCEINVALID, __FILE__, __LINE__, __func__);
- return NULL;
- }
- return bdb->opaque + BDBOPAQUESIZ;
-}
-
-
/* Get the number of used elements of the bucket array of a B+ tree database object. */
uint64_t tcbdbbnumused(TCBDB *bdb){
assert(bdb);
bdb->mmtx = NULL;
bdb->cmtx = NULL;
bdb->hdb = NULL;
- bdb->opaque = NULL;
bdb->open = false;
bdb->wmode = false;
bdb->lmemb = BDBDEFLMEMB;
`bdb' specifies the B+ tree database object. */
static void tcbdbdumpmeta(TCBDB *bdb){
assert(bdb);
- memset(bdb->opaque, 0, 64);
- char *wp = bdb->opaque;
+ char odata[BDBOPAQUESIZ];
+ memset(odata, 0, BDBOPAQUESIZ);
+ char *wp = odata;
if(bdb->cmp == tccmplexical){
*(uint8_t *)(wp++) = 0x0;
} else if(bdb->cmp == tccmpdecimal){
llnum = TCHTOILL(llnum);
memcpy(wp, &llnum, sizeof(llnum));
wp += sizeof(llnum);
+ tchdbwriteopaque(bdb->hdb, odata, 0, BDBOPAQUESIZ);
}
/* Deserialize meta data from the opaque field.
`bdb' specifies the B+ tree database object. */
static void tcbdbloadmeta(TCBDB *bdb){
- const char *rp = bdb->opaque;
+ char odata[BDBOPAQUESIZ];
+ tchdbreadopaque(bdb->hdb, odata, 0, BDBOPAQUESIZ);
+ const char *rp = odata;
uint8_t cnum = *(uint8_t *)(rp++);
if(cnum == 0x0){
bdb->cmp = tccmplexical;
}
}
bool err = false;
- step = sprintf(hbuf, "%llx", (unsigned long long)leaf->id);
+ step = sprintf(hbuf, "%" PRIxMAX "", (unsigned long long)leaf->id);
if(ln < 1 && !tchdbout(bdb->hdb, hbuf, step) && tchdbecode(bdb->hdb) != TCENOREC)
err = true;
if(!leaf->dead && !tchdbput(bdb->hdb, hbuf, step, TCXSTRPTR(rbuf), TCXSTRSIZE(rbuf)))
TCDODEBUG(bdb->cnt_loadleaf++);
char hbuf[(sizeof(uint64_t)+1)*3];
int step;
- step = sprintf(hbuf, "%llx", (unsigned long long)id);
+ step = sprintf(hbuf, "%" PRIxMAX "", (unsigned long long)id);
char *rbuf = NULL;
char wbuf[BDBPAGEBUFSIZ];
const char *rp = NULL;
if(clk) BDBUNLOCKCACHE(bdb);
if(leaf) return true;
char hbuf[(sizeof(uint64_t)+1)*3];
- int step = sprintf(hbuf, "%llx", (unsigned long long)id);
+ int step = sprintf(hbuf, "%" PRIxMAX "", (unsigned long long)id);
return tchdbvsiz(bdb->hdb, hbuf, step) > 0;
}
TCXSTRCAT(rbuf, ebuf, idx->ksiz);
}
bool err = false;
- step = sprintf(hbuf, "#%llx", (unsigned long long)(node->id - BDBNODEIDBASE));
+ step = sprintf(hbuf, "#%" PRIxMAX "", (unsigned long long)(node->id - BDBNODEIDBASE));
if(ln < 1 && !tchdbout(bdb->hdb, hbuf, step) && tchdbecode(bdb->hdb) != TCENOREC)
err = true;
if(!node->dead && !tchdbput(bdb->hdb, hbuf, step, TCXSTRPTR(rbuf), TCXSTRSIZE(rbuf)))
TCDODEBUG(bdb->cnt_loadnode++);
char hbuf[(sizeof(uint64_t)+1)*2];
int step;
- step = sprintf(hbuf, "#%llx", (unsigned long long)(id - BDBNODEIDBASE));
+ step = sprintf(hbuf, "#%" PRIxMAX "", (unsigned long long)(id - BDBNODEIDBASE));
char *rbuf = NULL;
char wbuf[BDBPAGEBUFSIZ];
const char *rp = NULL;
bdb->lnum = 0;
bdb->nnum = 0;
bdb->rnum = 0;
- bdb->opaque = tchdbopaque(bdb->hdb);
bdb->leafc = tcmapnew2(bdb->lcnum * 2 + 1);
bdb->nodec = tcmapnew2(bdb->ncnum * 2 + 1);
if(bdb->wmode && tchdbrnum(bdb->hdb) < 1){
bool err = false;
if(bdb->tran){
tcbdbcachepurge(bdb);
- memcpy(bdb->opaque, bdb->rbopaque, BDBOPAQUESIZ);
+ tchdbwriteopaque(bdb->hdb, bdb->rbopaque, 0, BDBOPAQUESIZ);
tcbdbloadmeta(bdb);
TCFREE(bdb->rbopaque);
bdb->tran = false;
static bool tcbdboptimizeimpl(TCBDB *bdb, int32_t lmemb, int32_t nmemb,
int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){
assert(bdb);
- const char *path = tchdbpath(bdb->hdb);
- char *tpath = tcsprintf("%s%ctmp%c%llu", path, MYEXTCHR, MYEXTCHR, tchdbinode(bdb->hdb));
+ char *opath = tcstrdup(tchdbpath(bdb->hdb));
+ char *tpath = tcsprintf("%s%ctmp%c%" PRIuMAX "", opath, MYEXTCHR, MYEXTCHR, tchdbinode(bdb->hdb));
+ int omode = (tchdbomode(bdb->hdb) & ~BDBOCREAT) & ~BDBOTRUNC;
TCBDB *tbdb = tcbdbnew();
- int dbgfd = tchdbdbgfd(bdb->hdb);
- if(dbgfd >= 0) tcbdbsetdbgfd(tbdb, dbgfd);
+ HANDLE dbgfd = tchdbdbgfd(bdb->hdb);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(tbdb, dbgfd);
tcbdbsetcmpfunc(tbdb, bdb->cmp, bdb->cmpop);
TCCODEC enc, dec;
void *encop, *decop;
bdb->ncnum = BDBCACHEOUT * 2;
tbdb->lcnum = BDBLEVELMAX;
tbdb->ncnum = BDBCACHEOUT * 2;
- if(!tcbdbopen(tbdb, tpath, BDBOWRITER | BDBOCREAT | BDBOTRUNC)){
- tcbdbsetecode(bdb, tcbdbecode(tbdb), __FILE__, __LINE__, __func__);
+ if(!tcbdbopen(tbdb, tpath, BDBOWRITER | BDBOCREAT | BDBOTRUNC) ||
+ !tchdbcopyopaque(tbdb->hdb, bdb->hdb, 0, -1)){
tcbdbdel(tbdb);
TCFREE(tpath);
+ TCFREE(opath);
return false;
}
- memcpy(tcbdbopaque(tbdb), tcbdbopaque(bdb), BDBLEFTOPQSIZ);
bool err = false;
BDBCUR *cur = tcbdbcurnew(bdb);
tcbdbcurfirstimpl(cur);
bdb->lcnum = lcnum;
bdb->ncnum = ncnum;
tcbdbdel(tbdb);
- if(unlink(path) == -1){
+ if(err){
+ TCFREE(tpath);
+ TCFREE(opath);
+ return false;
+ }
+ if(!tcbdbcloseimpl(bdb)){
+ TCFREE(opath);
+ return false;
+ }
+ if(unlink(opath)){
tcbdbsetecode(bdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
- if(rename(tpath, path) == -1){
+ if(rename(tpath, opath)){
tcbdbsetecode(bdb, TCERENAME, __FILE__, __LINE__, __func__);
err = true;
}
TCFREE(tpath);
- if(err) return false;
- tpath = tcstrdup(path);
- int omode = (tchdbomode(bdb->hdb) & ~BDBOCREAT) & ~BDBOTRUNC;
- if(!tcbdbcloseimpl(bdb)){
- TCFREE(tpath);
+ if(err){
+ TCFREE(opath);
return false;
}
- bool rv = tcbdbopenimpl(bdb, tpath, omode);
- TCFREE(tpath);
+ bool rv = tcbdbopenimpl(bdb, opath, omode);
+ TCFREE(opath);
return rv;
}
`bdb' specifies the B+ tree database object. */
void tcbdbprintmeta(TCBDB *bdb){
assert(bdb);
- int dbgfd = tchdbdbgfd(bdb->hdb);
- if(dbgfd < 0) return;
- if(dbgfd == UINT16_MAX) dbgfd = 1;
+ HANDLE dbgfd = tchdbdbgfd(bdb->hdb);
+ if (INVALIDHANDLE(dbgfd)) {
+ dbgfd = GET_STDOUT_HANDLE();
+ }
char buf[BDBPAGEBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "META:");
wp += sprintf(wp, " mmtx=%p", (void *)bdb->mmtx);
wp += sprintf(wp, " cmtx=%p", (void *)bdb->cmtx);
wp += sprintf(wp, " hdb=%p", (void *)bdb->hdb);
- wp += sprintf(wp, " opaque=%p", (void *)bdb->opaque);
+ //wp += sprintf(wp, " opaque=%p", (void *)bdb->opaque);
wp += sprintf(wp, " open=%d", bdb->open);
wp += sprintf(wp, " wmode=%d", bdb->wmode);
wp += sprintf(wp, " lmemb=%u", bdb->lmemb);
wp += sprintf(wp, " nmemb=%u", bdb->nmemb);
wp += sprintf(wp, " opts=%u", bdb->opts);
- wp += sprintf(wp, " root=%llx", (unsigned long long)bdb->root);
- wp += sprintf(wp, " first=%llx", (unsigned long long)bdb->first);
- wp += sprintf(wp, " last=%llx", (unsigned long long)bdb->last);
- wp += sprintf(wp, " lnum=%llu", (unsigned long long)bdb->lnum);
- wp += sprintf(wp, " nnum=%llu", (unsigned long long)bdb->nnum);
- wp += sprintf(wp, " rnum=%llu", (unsigned long long)bdb->rnum);
+ wp += sprintf(wp, " root=%" PRIxMAX "", (unsigned long long)bdb->root);
+ wp += sprintf(wp, " first=%" PRIxMAX "", (unsigned long long)bdb->first);
+ wp += sprintf(wp, " last=%" PRIxMAX "", (unsigned long long)bdb->last);
+ wp += sprintf(wp, " lnum=%" PRIuMAX "", (unsigned long long)bdb->lnum);
+ wp += sprintf(wp, " nnum=%" PRIuMAX "", (unsigned long long)bdb->nnum);
+ wp += sprintf(wp, " rnum=%" PRIuMAX "", (unsigned long long)bdb->rnum);
wp += sprintf(wp, " leafc=%p", (void *)bdb->leafc);
wp += sprintf(wp, " nodec=%p", (void *)bdb->nodec);
wp += sprintf(wp, " cmp=%p", (void *)(intptr_t)bdb->cmp);
wp += sprintf(wp, " ncnum=%u", bdb->ncnum);
wp += sprintf(wp, " lsmax=%u", bdb->lsmax);
wp += sprintf(wp, " lschk=%u", bdb->lschk);
- wp += sprintf(wp, " capnum=%llu", (unsigned long long)bdb->capnum);
+ wp += sprintf(wp, " capnum=%" PRIuMAX "", (unsigned long long)bdb->capnum);
wp += sprintf(wp, " hist=%p", (void *)bdb->hist);
wp += sprintf(wp, " hnum=%d", bdb->hnum);
- wp += sprintf(wp, " hleaf=%llu", (unsigned long long)bdb->hleaf);
- wp += sprintf(wp, " lleaf=%llu", (unsigned long long)bdb->lleaf);
+ wp += sprintf(wp, " hleaf=%" PRIuMAX "", (unsigned long long)bdb->hleaf);
+ wp += sprintf(wp, " lleaf=%" PRIuMAX "", (unsigned long long)bdb->lleaf);
wp += sprintf(wp, " tran=%d", bdb->tran);
- wp += sprintf(wp, " rbopaque=%p", (void *)bdb->rbopaque);
- wp += sprintf(wp, " clock=%llu", (unsigned long long)bdb->clock);
- wp += sprintf(wp, " cnt_saveleaf=%lld", (long long)bdb->cnt_saveleaf);
- wp += sprintf(wp, " cnt_loadleaf=%lld", (long long)bdb->cnt_loadleaf);
- wp += sprintf(wp, " cnt_killleaf=%lld", (long long)bdb->cnt_killleaf);
- wp += sprintf(wp, " cnt_adjleafc=%lld", (long long)bdb->cnt_adjleafc);
- wp += sprintf(wp, " cnt_savenode=%lld", (long long)bdb->cnt_savenode);
- wp += sprintf(wp, " cnt_loadnode=%lld", (long long)bdb->cnt_loadnode);
- wp += sprintf(wp, " cnt_adjnodec=%lld", (long long)bdb->cnt_adjnodec);
+ //wp += sprintf(wp, " rbopaque=%p", (void *)bdb->rbopaque);
+ wp += sprintf(wp, " clock=%" PRIuMAX "", (unsigned long long)bdb->clock);
+ wp += sprintf(wp, " cnt_saveleaf=%" PRIdMAX "", (long long)bdb->cnt_saveleaf);
+ wp += sprintf(wp, " cnt_loadleaf=%" PRIdMAX "", (long long)bdb->cnt_loadleaf);
+ wp += sprintf(wp, " cnt_killleaf=%" PRIdMAX "", (long long)bdb->cnt_killleaf);
+ wp += sprintf(wp, " cnt_adjleafc=%" PRIdMAX "", (long long)bdb->cnt_adjleafc);
+ wp += sprintf(wp, " cnt_savenode=%" PRIdMAX "", (long long)bdb->cnt_savenode);
+ wp += sprintf(wp, " cnt_loadnode=%" PRIdMAX "", (long long)bdb->cnt_loadnode);
+ wp += sprintf(wp, " cnt_adjnodec=%" PRIdMAX "", (long long)bdb->cnt_adjnodec);
*(wp++) = '\n';
tcwrite(dbgfd, buf, wp - buf);
}
`leaf' specifies the leaf object. */
void tcbdbprintleaf(TCBDB *bdb, BDBLEAF *leaf){
assert(bdb && leaf);
- int dbgfd = tchdbdbgfd(bdb->hdb);
+ HANDLE dbgfd = tchdbdbgfd(bdb->hdb);
TCPTRLIST *recs = leaf->recs;
- if(dbgfd < 0) return;
- if(dbgfd == UINT16_MAX) dbgfd = 1;
+ if(INVALIDHANDLE(dbgfd)) {
+ dbgfd = GET_STDOUT_HANDLE();
+ }
char buf[BDBPAGEBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "LEAF:");
- wp += sprintf(wp, " id:%llx", (unsigned long long)leaf->id);
+ wp += sprintf(wp, " id:%" PRIxMAX "", (unsigned long long)leaf->id);
wp += sprintf(wp, " size:%u", leaf->size);
- wp += sprintf(wp, " prev:%llx", (unsigned long long)leaf->prev);
- wp += sprintf(wp, " next:%llx", (unsigned long long)leaf->next);
+ wp += sprintf(wp, " prev:%" PRIxMAX "", (unsigned long long)leaf->prev);
+ wp += sprintf(wp, " next:%" PRIxMAX "", (unsigned long long)leaf->next);
wp += sprintf(wp, " dirty:%d", leaf->dirty);
wp += sprintf(wp, " dead:%d", leaf->dead);
wp += sprintf(wp, " rnum:%d", TCPTRLISTNUM(recs));
`node' specifies the node object. */
void tcbdbprintnode(TCBDB *bdb, BDBNODE *node){
assert(bdb && node);
- int dbgfd = tchdbdbgfd(bdb->hdb);
+ HANDLE dbgfd = tchdbdbgfd(bdb->hdb);
TCPTRLIST *idxs = node->idxs;
- if(dbgfd < 0) return;
- if(dbgfd == UINT16_MAX) dbgfd = 1;
+ if(INVALIDHANDLE(dbgfd)) {
+ dbgfd = GET_STDOUT_HANDLE();
+ }
char buf[BDBPAGEBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "NODE:");
- wp += sprintf(wp, " id:%llx", (unsigned long long)node->id);
- wp += sprintf(wp, " heir:%llx", (unsigned long long)node->heir);
+ wp += sprintf(wp, " id:%" PRIxMAX "", (unsigned long long)node->id);
+ wp += sprintf(wp, " heir:%" PRIxMAX "", (unsigned long long)node->heir);
wp += sprintf(wp, " dirty:%d", node->dirty);
wp += sprintf(wp, " dead:%d", node->dead);
wp += sprintf(wp, " rnum:%d", TCPTRLISTNUM(idxs));
wp = buf;
BDBIDX *idx = TCPTRLISTVAL(idxs, i);
char *ebuf = (char *)idx + sizeof(*idx);
- wp += sprintf(wp, " [%llx:%s]", (unsigned long long)idx->pid, ebuf);
+ wp += sprintf(wp, " [%" PRIxMAX ":%s]", (unsigned long long)idx->pid, ebuf);
}
*(wp++) = '\n';
tcwrite(dbgfd, buf, wp - buf);
void *mmtx; /* mutex for method */
void *cmtx; /* mutex for cache */
TCHDB *hdb; /* internal database object */
- char *opaque; /* opaque buffer */
bool open; /* whether the internal database is opened */
bool wmode; /* whether to be writable */
uint32_t lmemb; /* number of members in each leaf */
/* Get the message string corresponding to an error code.
`ecode' specifies the error code.
The return value is the message string of the error code. */
-const char *tcbdberrmsg(int ecode);
+EJDB_EXPORT const char *tcbdberrmsg(int ecode);
/* Create a B+ tree database object.
The return value is the new B+ tree database object. */
-TCBDB *tcbdbnew(void);
+EJDB_EXPORT TCBDB *tcbdbnew(void);
/* Delete a B+ tree database object.
`bdb' specifies the B+ tree database object.
If the database is not closed, it is closed implicitly. Note that the deleted object and its
derivatives can not be used anymore. */
-void tcbdbdel(TCBDB *bdb);
+EJDB_EXPORT void tcbdbdel(TCBDB *bdb);
/* Get the last happened error code of a B+ tree database object.
for unlink error, `TCERENAME' for rename error, `TCEMKDIR' for mkdir error, `TCERMDIR' for
rmdir error, `TCEKEEP' for existing record, `TCENOREC' for no record found, and `TCEMISC' for
miscellaneous error. */
-int tcbdbecode(TCBDB *bdb);
+EJDB_EXPORT int tcbdbecode(TCBDB *bdb);
/* Set mutual exclusion control of a B+ tree database object for threading.
If successful, the return value is true, else, it is false.
Note that the mutual exclusion control is needed if the object is shared by plural threads and
this function should be called before the database is opened. */
-bool tcbdbsetmutex(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbsetmutex(TCBDB *bdb);
/* Set the custom comparison function of a B+ tree database object.
`tctccmplexical' (dafault), `tctccmpdecimal', `tctccmpint32', and `tctccmpint64' are built-in.
Note that the comparison function should be set before the database is opened. Moreover,
user-defined comparison functions should be set every time the database is being opened. */
-bool tcbdbsetcmpfunc(TCBDB *bdb, TCCMP cmp, void *cmpop);
+EJDB_EXPORT bool tcbdbsetcmpfunc(TCBDB *bdb, TCCMP cmp, void *cmpop);
/* Set the tuning parameters of a B+ tree database object.
BZIP2 encoding, `BDBTTCBS' specifies that each page is compressed with TCBS encoding.
If successful, the return value is true, else, it is false.
Note that the tuning parameters should be set before the database is opened. */
-bool tcbdbtune(TCBDB *bdb, int32_t lmemb, int32_t nmemb,
+EJDB_EXPORT bool tcbdbtune(TCBDB *bdb, int32_t lmemb, int32_t nmemb,
int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
the default value is specified. The default value is 512.
If successful, the return value is true, else, it is false.
Note that the caching parameters should be set before the database is opened. */
-bool tcbdbsetcache(TCBDB *bdb, int32_t lcnum, int32_t ncnum);
+EJDB_EXPORT bool tcbdbsetcache(TCBDB *bdb, int32_t lcnum, int32_t ncnum);
/* Set the size of the extra mapped memory of a B+ tree database object.
mapped memory is disabled. It is disabled by default.
If successful, the return value is true, else, it is false.
Note that the mapping parameters should be set before the database is opened. */
-bool tcbdbsetxmsiz(TCBDB *bdb, int64_t xmsiz);
+EJDB_EXPORT bool tcbdbsetxmsiz(TCBDB *bdb, int64_t xmsiz);
/* Set the unit step number of auto defragmentation of a B+ tree database object.
is disabled. It is disabled by default.
If successful, the return value is true, else, it is false.
Note that the defragmentation parameter should be set before the database is opened. */
-bool tcbdbsetdfunit(TCBDB *bdb, int32_t dfunit);
+EJDB_EXPORT bool tcbdbsetdfunit(TCBDB *bdb, int32_t dfunit);
/* Open a database file and connect a B+ tree database object.
bitwise-or: `BDBONOLCK', which means it opens the database file without file locking, or
`BDBOLCKNB', which means locking is performed without blocking.
If successful, the return value is true, else, it is false. */
-bool tcbdbopen(TCBDB *bdb, const char *path, int omode);
+EJDB_EXPORT bool tcbdbopen(TCBDB *bdb, const char *path, int omode);
/* Close a B+ tree database object.
If successful, the return value is true, else, it is false.
Update of a database is assured to be written when the database is closed. If a writer opens
a database but does not close it appropriately, the database will be broken. */
-bool tcbdbclose(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbclose(TCBDB *bdb);
/* Store a record into a B+ tree database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcbdbput(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into a B+ tree database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tcbdbput2(TCBDB *bdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcbdbput2(TCBDB *bdb, const char *kstr, const char *vstr);
/* Store a new record into a B+ tree database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcbdbputkeep(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcbdbputkeep(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into a B+ tree database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcbdbputkeep2(TCBDB *bdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcbdbputkeep2(TCBDB *bdb, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the existing record in a B+ tree database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tcbdbputcat(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcbdbputcat(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string value at the end of the existing record in a B+ tree database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tcbdbputcat2(TCBDB *bdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcbdbputcat2(TCBDB *bdb, const char *kstr, const char *vstr);
/* Store a record into a B+ tree database object with allowing duplication of keys.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, the new record is placed after the
existing one. */
-bool tcbdbputdup(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcbdbputdup(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into a B+ tree database object with allowing duplication of keys.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, the new record is placed after the
existing one. */
-bool tcbdbputdup2(TCBDB *bdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcbdbputdup2(TCBDB *bdb, const char *kstr, const char *vstr);
/* Store records into a B+ tree database object with allowing duplication of keys.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, the new records are placed after the
existing one. */
-bool tcbdbputdup3(TCBDB *bdb, const void *kbuf, int ksiz, const TCLIST *vals);
+EJDB_EXPORT bool tcbdbputdup3(TCBDB *bdb, const void *kbuf, int ksiz, const TCLIST *vals);
/* Remove a record of a B+ tree database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true, else, it is false.
If the key of duplicated records is specified, the first one is selected. */
-bool tcbdbout(TCBDB *bdb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcbdbout(TCBDB *bdb, const void *kbuf, int ksiz);
/* Remove a string record of a B+ tree database object.
`kstr' specifies the string of the key.
If successful, the return value is true, else, it is false.
If the key of duplicated records is specified, the first one is selected. */
-bool tcbdbout2(TCBDB *bdb, const char *kstr);
+EJDB_EXPORT bool tcbdbout2(TCBDB *bdb, const char *kstr);
/* Remove records of a B+ tree database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true, else, it is false.
If the key of duplicated records is specified, all of them are removed. */
-bool tcbdbout3(TCBDB *bdb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcbdbout3(TCBDB *bdb, const void *kbuf, int ksiz);
/* Retrieve a record in a B+ tree database object.
value can be treated as a character string. Because the region of the return value is
allocated with the `malloc' call, it should be released with the `free' call when it is no
longer in use. */
-void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcbdbget(TCBDB *bdb, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in a B+ tree database object.
If the key of duplicated records is specified, the first one is selected. Because the region
of the return value is allocated with the `malloc' call, it should be released with the `free'
call when it is no longer in use. */
-char *tcbdbget2(TCBDB *bdb, const char *kstr);
+EJDB_EXPORT char *tcbdbget2(TCBDB *bdb, const char *kstr);
/* Retrieve a record in a B+ tree database object as a volatile buffer.
value can be treated as a character string. Because the region of the return value is
volatile and it may be spoiled by another operation of the database, the data should be copied
into another involatile buffer immediately. */
-const void *tcbdbget3(TCBDB *bdb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT const void *tcbdbget3(TCBDB *bdb, const void *kbuf, int ksiz, int *sp);
/* Retrieve records in a B+ tree database object.
`NULL' is returned if no record corresponds.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcbdbget4(TCBDB *bdb, const void *kbuf, int ksiz);
+EJDB_EXPORT TCLIST *tcbdbget4(TCBDB *bdb, const void *kbuf, int ksiz);
/* Get the number of records corresponding a key in a B+ tree database object.
`kbuf' specifies the pointer to the region of the key.
`ksiz' specifies the size of the region of the key.
If successful, the return value is the number of the corresponding records, else, it is 0. */
-int tcbdbvnum(TCBDB *bdb, const void *kbuf, int ksiz);
+EJDB_EXPORT int tcbdbvnum(TCBDB *bdb, const void *kbuf, int ksiz);
/* Get the number of records corresponding a string key in a B+ tree database object.
`bdb' specifies the B+ tree database object.
`kstr' specifies the string of the key.
If successful, the return value is the number of the corresponding records, else, it is 0. */
-int tcbdbvnum2(TCBDB *bdb, const char *kstr);
+EJDB_EXPORT int tcbdbvnum2(TCBDB *bdb, const char *kstr);
/* Get the size of the value of a record in a B+ tree database object.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1.
If the key of duplicated records is specified, the first one is selected. */
-int tcbdbvsiz(TCBDB *bdb, const void *kbuf, int ksiz);
+EJDB_EXPORT int tcbdbvsiz(TCBDB *bdb, const void *kbuf, int ksiz);
/* Get the size of the value of a string record in a B+ tree database object.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1.
If the key of duplicated records is specified, the first one is selected. */
-int tcbdbvsiz2(TCBDB *bdb, const char *kstr);
+EJDB_EXPORT int tcbdbvsiz2(TCBDB *bdb, const char *kstr);
/* Get keys of ranged records in a B+ tree database object.
does never fail. It returns an empty list even if no record corresponds.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcbdbrange(TCBDB *bdb, const void *bkbuf, int bksiz, bool binc,
+EJDB_EXPORT TCLIST *tcbdbrange(TCBDB *bdb, const void *bkbuf, int bksiz, bool binc,
const void *ekbuf, int eksiz, bool einc, int max);
does never fail. It returns an empty list even if no record corresponds.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcbdbrange2(TCBDB *bdb, const char *bkstr, bool binc,
+EJDB_EXPORT TCLIST *tcbdbrange2(TCBDB *bdb, const char *bkstr, bool binc,
const char *ekstr, bool einc, int max);
It returns an empty list even if no key corresponds.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcbdbfwmkeys(TCBDB *bdb, const void *pbuf, int psiz, int max);
+EJDB_EXPORT TCLIST *tcbdbfwmkeys(TCBDB *bdb, const void *pbuf, int psiz, int max);
/* Get forward matching string keys in a B+ tree database object.
It returns an empty list even if no key corresponds.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcbdbfwmkeys2(TCBDB *bdb, const char *pstr, int max);
+EJDB_EXPORT TCLIST *tcbdbfwmkeys2(TCBDB *bdb, const char *pstr, int max);
/* Add an integer to a record in a B+ tree database object.
If successful, the return value is the summation value, else, it is `INT_MIN'.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tcbdbaddint(TCBDB *bdb, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tcbdbaddint(TCBDB *bdb, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in a B+ tree database object.
If successful, the return value is the summation value, else, it is Not-a-Number.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tcbdbadddouble(TCBDB *bdb, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tcbdbadddouble(TCBDB *bdb, const void *kbuf, int ksiz, double num);
/* Synchronize updated contents of a B+ tree database object with the file and the device.
`bdb' specifies the B+ tree database object connected as a writer.
If successful, the return value is true, else, it is false.
This function is useful when another process connects to the same database file. */
-bool tcbdbsync(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbsync(TCBDB *bdb);
/* Optimize the file of a B+ tree database object.
If successful, the return value is true, else, it is false.
This function is useful to reduce the size of the database file with data fragmentation by
successive updating. */
-bool tcbdboptimize(TCBDB *bdb, int32_t lmemb, int32_t nmemb,
+EJDB_EXPORT bool tcbdboptimize(TCBDB *bdb, int32_t lmemb, int32_t nmemb,
int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
/* Remove all records of a B+ tree database object.
`bdb' specifies the B+ tree database object connected as a writer.
If successful, the return value is true, else, it is false. */
-bool tcbdbvanish(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbvanish(TCBDB *bdb);
/* Copy the database file of a B+ tree database object.
The database file is assured to be kept synchronized and not modified while the copying or
executing operation is in progress. So, this function is useful to create a backup file of
the database file. */
-bool tcbdbcopy(TCBDB *bdb, const char *path);
+EJDB_EXPORT bool tcbdbcopy(TCBDB *bdb, const char *path);
/* Begin the transaction of a B+ tree database object.
cached on memory while the transaction, the amount of referred records is limited by the
memory capacity. If the database is closed during transaction, the transaction is aborted
implicitly. */
-bool tcbdbtranbegin(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbtranbegin(TCBDB *bdb);
/* Commit the transaction of a B+ tree database object.
`bdb' specifies the B+ tree database object connected as a writer.
If successful, the return value is true, else, it is false.
Update in the transaction is fixed when it is committed successfully. */
-bool tcbdbtrancommit(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbtrancommit(TCBDB *bdb);
/* Abort the transaction of a B+ tree database object.
If successful, the return value is true, else, it is false.
Update in the transaction is discarded when it is aborted. The state of the database is
rollbacked to before transaction. */
-bool tcbdbtranabort(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbtranabort(TCBDB *bdb);
/* Get the file path of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the path of the database file or `NULL' if the object does not connect to
any database file. */
-const char *tcbdbpath(TCBDB *bdb);
+EJDB_EXPORT const char *tcbdbpath(TCBDB *bdb);
/* Get the number of records of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the number of records or 0 if the object does not connect to any database
file. */
-uint64_t tcbdbrnum(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdbrnum(TCBDB *bdb);
/* Get the size of the database file of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the size of the database file or 0 if the object does not connect to any
database file. */
-uint64_t tcbdbfsiz(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdbfsiz(TCBDB *bdb);
/* Create a cursor object.
Note that the cursor is available only after initialization with the `tcbdbcurfirst' or the
`tcbdbcurjump' functions and so on. Moreover, the position of the cursor will be indefinite
when the database is updated after the initialization of the cursor. */
-BDBCUR *tcbdbcurnew(TCBDB *bdb);
+EJDB_EXPORT BDBCUR *tcbdbcurnew(TCBDB *bdb);
/* Delete a cursor object.
`cur' specifies the cursor object. */
-void tcbdbcurdel(BDBCUR *cur);
+EJDB_EXPORT void tcbdbcurdel(BDBCUR *cur);
/* Move a cursor object to the first record.
`cur' specifies the cursor object.
If successful, the return value is true, else, it is false. False is returned if there is
no record in the database. */
-bool tcbdbcurfirst(BDBCUR *cur);
+EJDB_EXPORT bool tcbdbcurfirst(BDBCUR *cur);
/* Move a cursor object to the last record.
`cur' specifies the cursor object.
If successful, the return value is true, else, it is false. False is returned if there is
no record in the database. */
-bool tcbdbcurlast(BDBCUR *cur);
+EJDB_EXPORT bool tcbdbcurlast(BDBCUR *cur);
/* Move a cursor object to the front of records corresponding a key.
no record corresponding the condition.
The cursor is set to the first record corresponding the key or the next substitute if
completely matching record does not exist. */
-bool tcbdbcurjump(BDBCUR *cur, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcbdbcurjump(BDBCUR *cur, const void *kbuf, int ksiz);
/* Move a cursor object to the front of records corresponding a key string.
no record corresponding the condition.
The cursor is set to the first record corresponding the key or the next substitute if
completely matching record does not exist. */
-bool tcbdbcurjump2(BDBCUR *cur, const char *kstr);
+EJDB_EXPORT bool tcbdbcurjump2(BDBCUR *cur, const char *kstr);
/* Move a cursor object to the previous record.
`cur' specifies the cursor object.
If successful, the return value is true, else, it is false. False is returned if there is
no previous record. */
-bool tcbdbcurprev(BDBCUR *cur);
+EJDB_EXPORT bool tcbdbcurprev(BDBCUR *cur);
/* Move a cursor object to the next record.
`cur' specifies the cursor object.
If successful, the return value is true, else, it is false. False is returned if there is
no next record. */
-bool tcbdbcurnext(BDBCUR *cur);
+EJDB_EXPORT bool tcbdbcurnext(BDBCUR *cur);
/* Insert a record around a cursor object.
If successful, the return value is true, else, it is false. False is returned when the cursor
is at invalid position.
After insertion, the cursor is moved to the inserted record. */
-bool tcbdbcurput(BDBCUR *cur, const void *vbuf, int vsiz, int cpmode);
+EJDB_EXPORT bool tcbdbcurput(BDBCUR *cur, const void *vbuf, int vsiz, int cpmode);
/* Insert a string record around a cursor object.
If successful, the return value is true, else, it is false. False is returned when the cursor
is at invalid position.
After insertion, the cursor is moved to the inserted record. */
-bool tcbdbcurput2(BDBCUR *cur, const char *vstr, int cpmode);
+EJDB_EXPORT bool tcbdbcurput2(BDBCUR *cur, const char *vstr, int cpmode);
/* Remove the record where a cursor object is.
If successful, the return value is true, else, it is false. False is returned when the cursor
is at invalid position.
After deletion, the cursor is moved to the next record if possible. */
-bool tcbdbcurout(BDBCUR *cur);
+EJDB_EXPORT bool tcbdbcurout(BDBCUR *cur);
/* Get the key of the record where the cursor object is.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tcbdbcurkey(BDBCUR *cur, int *sp);
+EJDB_EXPORT void *tcbdbcurkey(BDBCUR *cur, int *sp);
/* Get the key string of the record where the cursor object is.
returned when the cursor is at invalid position.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcbdbcurkey2(BDBCUR *cur);
+EJDB_EXPORT char *tcbdbcurkey2(BDBCUR *cur);
/* Get the key of the record where the cursor object is, as a volatile buffer.
the return value can be treated as a character string. Because the region of the return value
is volatile and it may be spoiled by another operation of the database, the data should be
copied into another involatile buffer immediately. */
-const void *tcbdbcurkey3(BDBCUR *cur, int *sp);
+EJDB_EXPORT const void *tcbdbcurkey3(BDBCUR *cur, int *sp);
/* Get the value of the record where the cursor object is.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tcbdbcurval(BDBCUR *cur, int *sp);
+EJDB_EXPORT void *tcbdbcurval(BDBCUR *cur, int *sp);
/* Get the value string of the record where the cursor object is.
returned when the cursor is at invalid position.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcbdbcurval2(BDBCUR *cur);
+EJDB_EXPORT char *tcbdbcurval2(BDBCUR *cur);
/* Get the value of the record where the cursor object is, as a volatile buffer.
the return value can be treated as a character string. Because the region of the return value
is volatile and it may be spoiled by another operation of the database, the data should be
copied into another involatile buffer immediately. */
-const void *tcbdbcurval3(BDBCUR *cur, int *sp);
+EJDB_EXPORT const void *tcbdbcurval3(BDBCUR *cur, int *sp);
/* Get the key and the value of the record where the cursor object is.
`vxstr' specifies the object into which the value is wrote down.
If successful, the return value is true, else, it is false. False is returned when the cursor
is at invalid position. */
-bool tcbdbcurrec(BDBCUR *cur, TCXSTR *kxstr, TCXSTR *vxstr);
+EJDB_EXPORT bool tcbdbcurrec(BDBCUR *cur, TCXSTR *kxstr, TCXSTR *vxstr);
`file' specifies the file name of the code.
`line' specifies the line number of the code.
`func' specifies the function name of the code. */
-void tcbdbsetecode(TCBDB *bdb, int ecode, const char *filename, int line, const char *func);
+EJDB_EXPORT void tcbdbsetecode(TCBDB *bdb, int ecode, const char *filename, int line, const char *func);
/* Set the file descriptor for debugging output.
`bdb' specifies the B+ tree database object.
`fd' specifies the file descriptor for debugging output. */
-void tcbdbsetdbgfd(TCBDB *bdb, int fd);
+EJDB_EXPORT void tcbdbsetdbgfd(TCBDB *bdb, HANDLE fd);
/* Get the file descriptor for debugging output.
`bdb' specifies the B+ tree database object.
The return value is the file descriptor for debugging output. */
-int tcbdbdbgfd(TCBDB *bdb);
+EJDB_EXPORT HANDLE tcbdbdbgfd(TCBDB *bdb);
/* Check whether mutual exclusion control is set to a B+ tree database object.
`bdb' specifies the B+ tree database object.
If mutual exclusion control is set, it is true, else it is false. */
-bool tcbdbhasmutex(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbhasmutex(TCBDB *bdb);
/* Synchronize updating contents on memory of a B+ tree database object.
`bdb' specifies the B+ tree database object connected as a writer.
`phys' specifies whether to synchronize physically.
If successful, the return value is true, else, it is false. */
-bool tcbdbmemsync(TCBDB *bdb, bool phys);
+EJDB_EXPORT bool tcbdbmemsync(TCBDB *bdb, bool phys);
/* Get the comparison function of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the pointer to the comparison function. */
-TCCMP tcbdbcmpfunc(TCBDB *bdb);
+EJDB_EXPORT TCCMP tcbdbcmpfunc(TCBDB *bdb);
/* Get the opaque object for the comparison function of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the opaque object for the comparison function. */
-void *tcbdbcmpop(TCBDB *bdb);
+EJDB_EXPORT void *tcbdbcmpop(TCBDB *bdb);
/* Get the maximum number of cached leaf nodes of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the maximum number of cached leaf nodes. */
-uint32_t tcbdblmemb(TCBDB *bdb);
+EJDB_EXPORT uint32_t tcbdblmemb(TCBDB *bdb);
/* Get the maximum number of cached non-leaf nodes of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the maximum number of cached non-leaf nodes. */
-uint32_t tcbdbnmemb(TCBDB *bdb);
+EJDB_EXPORT uint32_t tcbdbnmemb(TCBDB *bdb);
/* Get the number of the leaf nodes of B+ tree database object.
`bdb' specifies the B+ tree database object.
If successful, the return value is the number of the leaf nodes or 0 if the object does not
connect to any database file. */
-uint64_t tcbdblnum(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdblnum(TCBDB *bdb);
/* Get the number of the non-leaf nodes of B+ tree database object.
`bdb' specifies the B+ tree database object.
If successful, the return value is the number of the non-leaf nodes or 0 if the object does
not connect to any database file. */
-uint64_t tcbdbnnum(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdbnnum(TCBDB *bdb);
/* Get the number of elements of the bucket array of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the number of elements of the bucket array or 0 if the object does not
connect to any database file. */
-uint64_t tcbdbbnum(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdbbnum(TCBDB *bdb);
/* Get the record alignment of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the record alignment or 0 if the object does not connect to any database
file. */
-uint32_t tcbdbalign(TCBDB *bdb);
+EJDB_EXPORT uint32_t tcbdbalign(TCBDB *bdb);
/* Get the maximum number of the free block pool of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the maximum number of the free block pool or 0 if the object does not
connect to any database file. */
-uint32_t tcbdbfbpmax(TCBDB *bdb);
+EJDB_EXPORT uint32_t tcbdbfbpmax(TCBDB *bdb);
/* Get the inode number of the database file of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the inode number of the database file or 0 if the object does not connect
to any database file. */
-uint64_t tcbdbinode(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdbinode(TCBDB *bdb);
/* Get the modification time of the database file of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the inode number of the database file or 0 if the object does not connect
to any database file. */
-time_t tcbdbmtime(TCBDB *bdb);
+EJDB_EXPORT time_t tcbdbmtime(TCBDB *bdb);
/* Get the additional flags of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the additional flags. */
-uint8_t tcbdbflags(TCBDB *bdb);
+EJDB_EXPORT uint8_t tcbdbflags(TCBDB *bdb);
/* Get the options of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the options. */
-uint8_t tcbdbopts(TCBDB *bdb);
-
-
-/* Get the pointer to the opaque field of a B+ tree database object.
- `bdb' specifies the B+ tree database object.
- The return value is the pointer to the opaque field whose size is 128 bytes. */
-char *tcbdbopaque(TCBDB *bdb);
+EJDB_EXPORT uint8_t tcbdbopts(TCBDB *bdb);
/* Get the number of used elements of the bucket array of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the number of used elements of the bucket array or 0 if the object does not
connect to any database file. */
-uint64_t tcbdbbnumused(TCBDB *bdb);
+EJDB_EXPORT uint64_t tcbdbbnumused(TCBDB *bdb);
/* Set the maximum size of each leaf node.
value is specified. The default value is 16386.
If successful, the return value is true, else, it is false.
Note that the tuning parameters of the database should be set before the database is opened. */
-bool tcbdbsetlsmax(TCBDB *bdb, uint32_t lsmax);
+EJDB_EXPORT bool tcbdbsetlsmax(TCBDB *bdb, uint32_t lsmax);
/* Set the capacity number of records.
If successful, the return value is true, else, it is false.
When the number of records exceeds the capacity, forehand records are removed implicitly.
Note that the tuning parameters of the database should be set before the database is opened. */
-bool tcbdbsetcapnum(TCBDB *bdb, uint64_t capnum);
+EJDB_EXPORT bool tcbdbsetcapnum(TCBDB *bdb, uint64_t capnum);
/* Set the custom codec functions of a B+ tree database object.
If successful, the return value is true, else, it is false.
Note that the custom codec functions should be set before the database is opened and should be
set every time the database is being opened. */
-bool tcbdbsetcodecfunc(TCBDB *bdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop);
+EJDB_EXPORT bool tcbdbsetcodecfunc(TCBDB *bdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop);
/* Get the unit step number of auto defragmentation of a B+ tree database object.
`bdb' specifies the B+ tree database object.
The return value is the unit step number of auto defragmentation. */
-uint32_t tcbdbdfunit(TCBDB *bdb);
+EJDB_EXPORT uint32_t tcbdbdfunit(TCBDB *bdb);
/* Perform dynamic defragmentation of a B+ tree database object.
`step' specifie the number of steps. If it is not more than 0, the whole file is defragmented
gradually without keeping a continuous lock.
If successful, the return value is true, else, it is false. */
-bool tcbdbdefrag(TCBDB *bdb, int64_t step);
+EJDB_EXPORT bool tcbdbdefrag(TCBDB *bdb, int64_t step);
/* Clear the cache of a B+ tree database object.
`bdb' specifies the B+ tree database object.
If successful, the return value is true, else, it is false. */
-bool tcbdbcacheclear(TCBDB *bdb);
+EJDB_EXPORT bool tcbdbcacheclear(TCBDB *bdb);
/* Store a new record into a B+ tree database object with backward duplication.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, the new record is placed after the
existing one. */
-bool tcbdbputdupback(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcbdbputdupback(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into a B+ tree database object with backward duplication.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, the new record is placed after the
existing one. */
-bool tcbdbputdupback2(TCBDB *bdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcbdbputdupback2(TCBDB *bdb, const char *kstr, const char *vstr);
/* Store a record into a B+ tree database object with a duplication handler.
If successful, the return value is true, else, it is false.
Note that the callback function can not perform any database operation because the function
is called in the critical section guarded by the same locks of database operations. */
-bool tcbdbputproc(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tcbdbputproc(TCBDB *bdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
no record corresponding the condition.
The cursor is set to the last record corresponding the key or the previous substitute if
completely matching record does not exist. */
-bool tcbdbcurjumpback(BDBCUR *cur, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcbdbcurjumpback(BDBCUR *cur, const void *kbuf, int ksiz);
/* Move a cursor object to the rear of records corresponding a key string.
no record corresponding the condition.
The cursor is set to the last record corresponding the key or the previous substitute if
completely matching record does not exist. */
-bool tcbdbcurjumpback2(BDBCUR *cur, const char *kstr);
+EJDB_EXPORT bool tcbdbcurjumpback2(BDBCUR *cur, const char *kstr);
/* Process each record atomically of a B+ tree database object.
If successful, the return value is true, else, it is false.
Note that the callback function can not perform any database operation because the function
is called in the critical section guarded by the same locks of database operations. */
-bool tcbdbforeach(TCBDB *bdb, TCITER iter, void *op);
+EJDB_EXPORT bool tcbdbforeach(TCBDB *bdb, TCITER iter, void *op);
/* global variables */
const char *g_progname; // program name
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
/* main routine */
int main(int argc, char **argv){
g_progname = argv[0];
- g_dbgfd = -1;
+ g_dbgfd = INVALID_HANDLE_VALUE;
const char *ebuf = getenv("TCDBGFD");
- if(ebuf) g_dbgfd = tcatoix(ebuf);
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "create")){
static int proccreate(const char *path, int lmemb, int nmemb,
int bnum, int apow, int fpow, TCCMP cmp, int opts){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbtune(bdb, lmemb, nmemb, bnum, apow, fpow, opts)){
/* perform inform command */
static int procinform(const char *path, int omode){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
tcbdbsetcmpfunc(bdb, mycmpfunc, NULL);
tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL);
if(!tcbdbopen(bdb, path, BDBOREADER | omode)){
printf("\n");
printf("max leaf member: %d\n", tcbdblmemb(bdb));
printf("max node member: %d\n", tcbdbnmemb(bdb));
- printf("leaf number: %llu\n", (unsigned long long)tcbdblnum(bdb));
- printf("node number: %llu\n", (unsigned long long)tcbdbnnum(bdb));
- printf("bucket number: %llu\n", (unsigned long long)tcbdbbnum(bdb));
+ printf("leaf number: %" PRIuMAX "\n", (unsigned long long)tcbdblnum(bdb));
+ printf("node number: %" PRIuMAX "\n", (unsigned long long)tcbdbnnum(bdb));
+ printf("bucket number: %" PRIuMAX "\n", (unsigned long long)tcbdbbnum(bdb));
if(bdb->hdb->cnt_writerec >= 0)
- printf("used bucket number: %lld\n", (long long)tcbdbbnumused(bdb));
+ printf("used bucket number: %" PRIdMAX "\n", (long long)tcbdbbnumused(bdb));
printf("alignment: %u\n", tcbdbalign(bdb));
printf("free block pool: %u\n", tcbdbfbpmax(bdb));
- printf("inode number: %lld\n", (long long)tcbdbinode(bdb));
+ printf("inode number: %" PRIdMAX "\n", (long long)tcbdbinode(bdb));
char date[48];
tcdatestrwww(tcbdbmtime(bdb), INT_MAX, date);
printf("modified time: %s\n", date);
if(opts & BDBTTCBS) printf(" tcbs");
if(opts & BDBTEXCODEC) printf(" excodec");
printf("\n");
- printf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- printf("file size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ printf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ printf("file size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
if(!tcbdbclose(bdb)){
if(!err) printerr(bdb);
err = true;
static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
TCCMP cmp, int omode, int dmode){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){
/* perform out command */
static int procout(const char *path, const char *kbuf, int ksiz, TCCMP cmp, int omode){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){
static int procget(const char *path, const char *kbuf, int ksiz, TCCMP cmp, int omode,
bool px, bool pz){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbopen(bdb, path, BDBOREADER | omode)){
static int proclist(const char *path, TCCMP cmp, int omode, int max, bool pv, bool px, bool bk,
const char *jstr, const char *bstr, const char *estr, const char *fmstr){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbopen(bdb, path, BDBOREADER | omode)){
static int procoptimize(const char *path, int lmemb, int nmemb,
int bnum, int apow, int fpow, TCCMP cmp, int opts, int omode, bool df){
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbopen(bdb, path, BDBOWRITER | omode)){
return 1;
}
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb);
if(!tcbdbopen(bdb, path, BDBOWRITER | BDBOCREAT | omode)){
printerr(bdb);
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
if(bdb->hdb->cnt_writerec < 0) return;
iprintf("max leaf member: %d\n", tcbdblmemb(bdb));
iprintf("max node member: %d\n", tcbdbnmemb(bdb));
- iprintf("leaf number: %lld\n", (long long)tcbdblnum(bdb));
- iprintf("node number: %lld\n", (long long)tcbdbnnum(bdb));
- iprintf("bucket number: %lld\n", (long long)tcbdbbnum(bdb));
- iprintf("used bucket number: %lld\n", (long long)tcbdbbnumused(bdb));
- iprintf("cnt_saveleaf: %lld\n", (long long)bdb->cnt_saveleaf);
- iprintf("cnt_loadleaf: %lld\n", (long long)bdb->cnt_loadleaf);
- iprintf("cnt_killleaf: %lld\n", (long long)bdb->cnt_killleaf);
- iprintf("cnt_adjleafc: %lld\n", (long long)bdb->cnt_adjleafc);
- iprintf("cnt_savenode: %lld\n", (long long)bdb->cnt_savenode);
- iprintf("cnt_loadnode: %lld\n", (long long)bdb->cnt_loadnode);
- iprintf("cnt_adjnodec: %lld\n", (long long)bdb->cnt_adjnodec);
- iprintf("cnt_writerec: %lld\n", (long long)bdb->hdb->cnt_writerec);
- iprintf("cnt_reuserec: %lld\n", (long long)bdb->hdb->cnt_reuserec);
- iprintf("cnt_moverec: %lld\n", (long long)bdb->hdb->cnt_moverec);
- iprintf("cnt_readrec: %lld\n", (long long)bdb->hdb->cnt_readrec);
- iprintf("cnt_searchfbp: %lld\n", (long long)bdb->hdb->cnt_searchfbp);
- iprintf("cnt_insertfbp: %lld\n", (long long)bdb->hdb->cnt_insertfbp);
- iprintf("cnt_splicefbp: %lld\n", (long long)bdb->hdb->cnt_splicefbp);
- iprintf("cnt_dividefbp: %lld\n", (long long)bdb->hdb->cnt_dividefbp);
- iprintf("cnt_mergefbp: %lld\n", (long long)bdb->hdb->cnt_mergefbp);
- iprintf("cnt_reducefbp: %lld\n", (long long)bdb->hdb->cnt_reducefbp);
- iprintf("cnt_appenddrp: %lld\n", (long long)bdb->hdb->cnt_appenddrp);
- iprintf("cnt_deferdrp: %lld\n", (long long)bdb->hdb->cnt_deferdrp);
- iprintf("cnt_flushdrp: %lld\n", (long long)bdb->hdb->cnt_flushdrp);
- iprintf("cnt_adjrecc: %lld\n", (long long)bdb->hdb->cnt_adjrecc);
- iprintf("cnt_defrag: %lld\n", (long long)bdb->hdb->cnt_defrag);
- iprintf("cnt_shiftrec: %lld\n", (long long)bdb->hdb->cnt_shiftrec);
- iprintf("cnt_trunc: %lld\n", (long long)bdb->hdb->cnt_trunc);
+ iprintf("leaf number: %" PRIdMAX "\n", (long long)tcbdblnum(bdb));
+ iprintf("node number: %" PRIdMAX "\n", (long long)tcbdbnnum(bdb));
+ iprintf("bucket number: %" PRIdMAX "\n", (long long)tcbdbbnum(bdb));
+ iprintf("used bucket number: %" PRIdMAX "\n", (long long)tcbdbbnumused(bdb));
+ iprintf("cnt_saveleaf: %" PRIdMAX "\n", (long long)bdb->cnt_saveleaf);
+ iprintf("cnt_loadleaf: %" PRIdMAX "\n", (long long)bdb->cnt_loadleaf);
+ iprintf("cnt_killleaf: %" PRIdMAX "\n", (long long)bdb->cnt_killleaf);
+ iprintf("cnt_adjleafc: %" PRIdMAX "\n", (long long)bdb->cnt_adjleafc);
+ iprintf("cnt_savenode: %" PRIdMAX "\n", (long long)bdb->cnt_savenode);
+ iprintf("cnt_loadnode: %" PRIdMAX "\n", (long long)bdb->cnt_loadnode);
+ iprintf("cnt_adjnodec: %" PRIdMAX "\n", (long long)bdb->cnt_adjnodec);
+ iprintf("cnt_writerec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_writerec);
+ iprintf("cnt_reuserec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_reuserec);
+ iprintf("cnt_moverec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_moverec);
+ iprintf("cnt_readrec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_readrec);
+ iprintf("cnt_searchfbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_searchfbp);
+ iprintf("cnt_insertfbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_insertfbp);
+ iprintf("cnt_splicefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_splicefbp);
+ iprintf("cnt_dividefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_dividefbp);
+ iprintf("cnt_mergefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_mergefbp);
+ iprintf("cnt_reducefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_reducefbp);
+ iprintf("cnt_appenddrp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_appenddrp);
+ iprintf("cnt_deferdrp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_deferdrp);
+ iprintf("cnt_flushdrp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_flushdrp);
+ iprintf("cnt_adjrecc: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_adjrecc);
+ iprintf("cnt_defrag: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_defrag);
+ iprintf("cnt_shiftrec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_shiftrec);
+ iprintf("cnt_trunc: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_trunc);
}
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum);
}
tcmapdel(map);
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(!tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
if(bdb->hdb->cnt_writerec < 0) return;
iprintf("max leaf member: %d\n", tcbdblmemb(bdb));
iprintf("max node member: %d\n", tcbdbnmemb(bdb));
- iprintf("leaf number: %lld\n", (long long)tcbdblnum(bdb));
- iprintf("node number: %lld\n", (long long)tcbdbnnum(bdb));
- iprintf("bucket number: %lld\n", (long long)tcbdbbnum(bdb));
- iprintf("used bucket number: %lld\n", (long long)tcbdbbnumused(bdb));
- iprintf("cnt_saveleaf: %lld\n", (long long)bdb->cnt_saveleaf);
- iprintf("cnt_loadleaf: %lld\n", (long long)bdb->cnt_loadleaf);
- iprintf("cnt_killleaf: %lld\n", (long long)bdb->cnt_killleaf);
- iprintf("cnt_adjleafc: %lld\n", (long long)bdb->cnt_adjleafc);
- iprintf("cnt_savenode: %lld\n", (long long)bdb->cnt_savenode);
- iprintf("cnt_loadnode: %lld\n", (long long)bdb->cnt_loadnode);
- iprintf("cnt_adjnodec: %lld\n", (long long)bdb->cnt_adjnodec);
- iprintf("cnt_writerec: %lld\n", (long long)bdb->hdb->cnt_writerec);
- iprintf("cnt_reuserec: %lld\n", (long long)bdb->hdb->cnt_reuserec);
- iprintf("cnt_moverec: %lld\n", (long long)bdb->hdb->cnt_moverec);
- iprintf("cnt_readrec: %lld\n", (long long)bdb->hdb->cnt_readrec);
- iprintf("cnt_searchfbp: %lld\n", (long long)bdb->hdb->cnt_searchfbp);
- iprintf("cnt_insertfbp: %lld\n", (long long)bdb->hdb->cnt_insertfbp);
- iprintf("cnt_splicefbp: %lld\n", (long long)bdb->hdb->cnt_splicefbp);
- iprintf("cnt_dividefbp: %lld\n", (long long)bdb->hdb->cnt_dividefbp);
- iprintf("cnt_mergefbp: %lld\n", (long long)bdb->hdb->cnt_mergefbp);
- iprintf("cnt_reducefbp: %lld\n", (long long)bdb->hdb->cnt_reducefbp);
- iprintf("cnt_appenddrp: %lld\n", (long long)bdb->hdb->cnt_appenddrp);
- iprintf("cnt_deferdrp: %lld\n", (long long)bdb->hdb->cnt_deferdrp);
- iprintf("cnt_flushdrp: %lld\n", (long long)bdb->hdb->cnt_flushdrp);
- iprintf("cnt_adjrecc: %lld\n", (long long)bdb->hdb->cnt_adjrecc);
- iprintf("cnt_defrag: %lld\n", (long long)bdb->hdb->cnt_defrag);
- iprintf("cnt_shiftrec: %lld\n", (long long)bdb->hdb->cnt_shiftrec);
- iprintf("cnt_trunc: %lld\n", (long long)bdb->hdb->cnt_trunc);
+ iprintf("leaf number: %" PRIdMAX "\n", (long long)tcbdblnum(bdb));
+ iprintf("node number: %" PRIdMAX "\n", (long long)tcbdbnnum(bdb));
+ iprintf("bucket number: %" PRIdMAX "\n", (long long)tcbdbbnum(bdb));
+ iprintf("used bucket number: %" PRIdMAX "\n", (long long)tcbdbbnumused(bdb));
+ iprintf("cnt_saveleaf: %" PRIdMAX "\n", (long long)bdb->cnt_saveleaf);
+ iprintf("cnt_loadleaf: %" PRIdMAX "\n", (long long)bdb->cnt_loadleaf);
+ iprintf("cnt_killleaf: %" PRIdMAX "\n", (long long)bdb->cnt_killleaf);
+ iprintf("cnt_adjleafc: %" PRIdMAX "\n", (long long)bdb->cnt_adjleafc);
+ iprintf("cnt_savenode: %" PRIdMAX "\n", (long long)bdb->cnt_savenode);
+ iprintf("cnt_loadnode: %" PRIdMAX "\n", (long long)bdb->cnt_loadnode);
+ iprintf("cnt_adjnodec: %" PRIdMAX "\n", (long long)bdb->cnt_adjnodec);
+ iprintf("cnt_writerec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_writerec);
+ iprintf("cnt_reuserec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_reuserec);
+ iprintf("cnt_moverec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_moverec);
+ iprintf("cnt_readrec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_readrec);
+ iprintf("cnt_searchfbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_searchfbp);
+ iprintf("cnt_insertfbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_insertfbp);
+ iprintf("cnt_splicefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_splicefbp);
+ iprintf("cnt_dividefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_dividefbp);
+ iprintf("cnt_mergefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_mergefbp);
+ iprintf("cnt_reducefbp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_reducefbp);
+ iprintf("cnt_appenddrp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_appenddrp);
+ iprintf("cnt_deferdrp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_deferdrp);
+ iprintf("cnt_flushdrp: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_flushdrp);
+ iprintf("cnt_adjrecc: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_adjrecc);
+ iprintf("cnt_defrag: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_defrag);
+ iprintf("cnt_shiftrec: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_shiftrec);
+ iprintf("cnt_trunc: %" PRIdMAX "\n", (long long)bdb->hdb->cnt_trunc);
}
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
break;
}
tcbdbcurdel(cur);
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
eprint(bdb, __LINE__, "tcbdbopen");
err = true;
}
- if(TCUSEPTHREAD){
+ if(1){
TCBDB *bdbdup = tcbdbnew();
if(tcbdbopen(bdbdup, path, BDBOREADER)){
eprint(bdb, __LINE__, "(validation)");
err = true;
}
tcbdbcurdel(cur);
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
if(!tcbdbclose(bdb)){
bool err = false;
double stime = tctime();
TCBDB *bdb = tcbdbnew();
- if(g_dbgfd >= 0) tcbdbsetdbgfd(bdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd);
if(mt && !tcbdbsetmutex(bdb)){
eprint(bdb, __LINE__, "tcbdbsetmutex");
err = true;
err = true;
}
tcbdbcurdel(cur);
- iprintf("record number: %llu\n", (unsigned long long)tcbdbrnum(bdb));
- iprintf("size: %llu\n", (unsigned long long)tcbdbfsiz(bdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcbdbrnum(bdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcbdbfsiz(bdb));
mprint(bdb);
sysprint();
tcmapdel(map);
/* Delete a fixed-length database object. */
void tcfdbdel(TCFDB *fdb){
assert(fdb);
- if(fdb->fd >= 0) tcfdbclose(fdb);
+ if(!INVALIDHANDLE(fdb->fd)) tcfdbclose(fdb);
if(fdb->mmtx){
pthread_key_delete(*(pthread_key_t *)fdb->eckey);
pthread_mutex_destroy(fdb->wmtx);
/* Set mutual exclusion control of a fixed-length database object for threading. */
bool tcfdbsetmutex(TCFDB *fdb){
assert(fdb);
- if(!TCUSEPTHREAD) return true;
- if(fdb->mmtx || fdb->fd >= 0){
+ if(fdb->mmtx || !INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
/* Set the tuning parameters of a fixed-length database object. */
bool tcfdbtune(TCFDB *fdb, int32_t width, int64_t limsiz){
assert(fdb);
- if(fdb->fd >= 0){
+ if(!INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
bool tcfdbopen(TCFDB *fdb, const char *path, int omode){
assert(fdb && path);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd >= 0){
+ if(!INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbclose(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbput(TCFDB *fdb, int64_t id, const void *vbuf, int vsiz){
assert(fdb && vbuf && vsiz >= 0);
if(!FDBLOCKMETHOD(fdb, id < 1)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbputkeep(TCFDB *fdb, int64_t id, const void *vbuf, int vsiz){
assert(fdb && vbuf && vsiz >= 0);
if(!FDBLOCKMETHOD(fdb, id < 1)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbputcat(TCFDB *fdb, int64_t id, const void *vbuf, int vsiz){
assert(fdb && vbuf && vsiz >= 0);
if(!FDBLOCKMETHOD(fdb, id < 1)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbout(TCFDB *fdb, int64_t id){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
void *tcfdbget(TCFDB *fdb, int64_t id, int *sp){
assert(fdb && sp);
if(!FDBLOCKMETHOD(fdb, false)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
int tcfdbget4(TCFDB *fdb, int64_t id, void *vbuf, int max){
assert(fdb && vbuf && max >= 0);
if(!FDBLOCKMETHOD(fdb, false)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
int tcfdbvsiz(TCFDB *fdb, int64_t id){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, false)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbiterinit(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
uint64_t tcfdbiternext(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
uint64_t id = tcfdbiternextimpl(fdb);
if(id < 1) return NULL;
char kbuf[TCNUMBUFSIZ];
- int ksiz = sprintf(kbuf, "%llu", (unsigned long long)id);
+ int ksiz = sprintf(kbuf, "%" PRIuMAX "", (unsigned long long)id);
*sp = ksiz;
return tcmemdup(kbuf, ksiz);
}
uint64_t *tcfdbrange(TCFDB *fdb, int64_t lower, int64_t upper, int max, int *np){
assert(fdb && np);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
*np = 0;
TCLIST *keys = tclistnew2(num);
for(int i = 0; i < num; i++){
char kbuf[TCNUMBUFSIZ];
- int ksiz = sprintf(kbuf, "%llu", (unsigned long long)ids[i]);
+ int ksiz = sprintf(kbuf, "%" PRIuMAX "", (unsigned long long)ids[i]);
TCLISTPUSH(keys, kbuf, ksiz);
}
TCFREE(ids);
TCLIST *keys = tclistnew2(num);
for(int i = 0; i < num; i++){
char kbuf[TCNUMBUFSIZ];
- int ksiz = sprintf(kbuf, "%llu", (unsigned long long)ids[i]);
+ int ksiz = sprintf(kbuf, "%" PRIuMAX "", (unsigned long long)ids[i]);
TCLISTPUSH(keys, kbuf, ksiz);
}
TCFREE(ids);
int tcfdbaddint(TCFDB *fdb, int64_t id, int num){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, id < 1)) return INT_MIN;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return INT_MIN;
double tcfdbadddouble(TCFDB *fdb, int64_t id, double num){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, id < 1)) return nan("");
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return nan("");
bool tcfdbsync(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->tran){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER) || fdb->tran){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdboptimize(TCFDB *fdb, int32_t width, int64_t limsiz){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->tran){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER) || fdb->tran){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbvanish(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->tran){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER) || fdb->tran){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbcopy(TCFDB *fdb, const char *path){
assert(fdb && path);
if(!FDBLOCKMETHOD(fdb, false)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
/* Begin the transaction of a fixed-length database object. */
bool tcfdbtranbegin(TCFDB *fdb){
assert(fdb);
- for(double wsec = 1.0 / sysconf(_SC_CLK_TCK); true; wsec *= 2){
+ for(double wsec = 1.0 / sysconf_SC_CLK_TCK; true; wsec *= 2){
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->fatal){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER) || fdb->fatal){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
FDBUNLOCKMETHOD(fdb);
return false;
}
- if((fdb->omode & FDBOTSYNC) && fsync(fdb->fd) == -1){
+ if((fdb->omode & FDBOTSYNC) && fsync(fdb->fd)){
tcfdbsetecode(fdb, TCESYNC, __FILE__, __LINE__, __func__);
return false;
}
- if(fdb->walfd < 0){
+ if(INVALIDHANDLE(fdb->walfd)){
char *tpath = tcsprintf("%s%c%s", fdb->path, MYEXTCHR, FDBWALSUFFIX);
- int walfd = open(tpath, O_RDWR | O_CREAT | O_TRUNC, FDBFILEMODE);
+ HANDLE walfd;
+#ifndef _WIN32
+ walfd = open(tpath, O_RDWR | O_CREAT | O_TRUNC, FDBFILEMODE);
+#else
+ walfd = CreateFile(tpath, (GENERIC_READ | GENERIC_WRITE), FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
TCFREE(tpath);
- if(walfd < 0){
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tcfdbsetecode(fdb, ecode, __FILE__, __LINE__, __func__);
+ if(INVALIDHANDLE(walfd)){
+ tcfdbsetecode(fdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
}
bool tcfdbtrancommit(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || fdb->fatal || !fdb->tran){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER) || fdb->fatal || !fdb->tran){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
}
bool err = false;
if(!tcfdbmemsync(fdb, fdb->omode & FDBOTSYNC)) err = true;
- if(!err && ftruncate(fdb->walfd, 0) == -1){
+ if(!err && !tcftruncate(fdb->walfd, 0)){
tcfdbsetecode(fdb, TCETRUNC, __FILE__, __LINE__, __func__);
err = true;
}
bool tcfdbtranabort(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER) || !fdb->tran){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER) || !fdb->tran){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
if(!tcfdbmemsync(fdb, false)) err = true;
if(!tcfdbwalrestore(fdb, fdb->path)) err = true;
char hbuf[FDBHEADSIZ];
- if(lseek(fdb->fd, 0, SEEK_SET) == -1){
+ if(!tcfseek(fdb->fd, 0, TCFSTART)){
tcfdbsetecode(fdb, TCESEEK, __FILE__, __LINE__, __func__);
err = false;
} else if(!tcread(fdb->fd, hbuf, FDBHEADSIZ)){
const char *tcfdbpath(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, false)) return NULL;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return NULL;
uint64_t tcfdbrnum(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, false)) return 0;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return 0;
uint64_t tcfdbfsiz(TCFDB *fdb){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, false)) return 0;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return 0;
/* Set the error code of a fixed-length database object. */
void tcfdbsetecode(TCFDB *fdb, int ecode, const char *filename, int line, const char *func){
assert(fdb && filename && line >= 1 && func);
- int myerrno = errno;
- if(!fdb->fatal){
- fdb->ecode = ecode;
- if(fdb->mmtx) pthread_setspecific(*(pthread_key_t *)fdb->eckey, (void *)(intptr_t)ecode);
- }
- if(ecode != TCEINVALID && ecode != TCEKEEP && ecode != TCENOREC){
- fdb->fatal = true;
- if(fdb->fd >= 0 && (fdb->omode & FDBOWRITER)) tcfdbsetflag(fdb, FDBFFATAL, true);
+ if(!fdb->fatal) {
+ if (fdb->eckey) {
+ pthread_setspecific(*(pthread_key_t *)fdb->eckey, (void *)(intptr_t)ecode);
+ }
+ fdb->ecode = ecode;
+ }
+ switch (ecode) { //Fatal errors
+ case TCETHREAD:
+ case TCENOFILE:
+ case TCENOPERM:
+ case TCEMETA:
+ case TCERHEAD:
+ case TCEOPEN:
+ case TCECLOSE:
+ case TCETRUNC:
+ case TCESYNC:
+ case TCESTAT:
+ case TCESEEK:
+ case TCEREAD:
+ case TCEWRITE:
+ case TCEMMAP:
+ case TCELOCK:
+ case TCEUNLINK:
+ case TCERENAME:
+ case TCEMKDIR:
+ case TCERMDIR:
+ {
+ fdb->fatal = true;
+ if (!INVALIDHANDLE(fdb->fd) && (fdb->omode & FDBOWRITER)) tcfdbsetflag(fdb, FDBFFATAL, true);
+ break;
+ }
+ case TCESUCCESS:
+ case TCENOREC:
+ case TCEKEEP:
+ return;
+ break;
+ default:
+ break;
}
- if(fdb->dbgfd >= 0 && (fdb->dbgfd != UINT16_MAX || fdb->fatal)){
- int dbgfd = (fdb->dbgfd == UINT16_MAX) ? 1 : fdb->dbgfd;
+#ifdef _WIN32
+ DWORD winerrno = GetLastError();
+#endif
+ int stderrno = errno;
+ if(!INVALIDHANDLE(fdb->dbgfd) || fdb->fatal) {
+ HANDLE dbgfd = INVALIDHANDLE(fdb->dbgfd) ? GET_STDERR_HANDLE() : (fdb->dbgfd);
char obuf[FDBIOBUFSIZ];
- int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s:%d:%s\n", filename, line, func,
- fdb->path ? fdb->path : "-", ecode, tcfdberrmsg(ecode),
- myerrno, strerror(myerrno));
+#ifdef _WIN32
+ LPTSTR errorText = NULL;
+ if (winerrno > 0) {
+ DWORD ret = FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, winerrno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &errorText, 0, NULL);
+ if (!ret) {
+ if (errorText) LocalFree(errorText);
+ errorText = NULL;
+ }
+ }
+ int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s:%d:%s:%d:%s\n",
+ filename, line,
+ func, (fdb->path ? fdb->path : "-"),
+ ecode, tcfdberrmsg(ecode),
+ winerrno, (errorText ? errorText : "-"),
+ stderrno, (stderrno > 0 ? strerror(stderrno) : "-"));
+ if (errorText) LocalFree(errorText);
+#else
+ int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s:%d:%s\n",
+ filename, line,
+ func, (fdb->path ? fdb->path : "-"),
+ ecode, tcfdberrmsg(ecode),
+ stderrno, strerror(stderrno));
+#endif
tcwrite(dbgfd, obuf, osiz);
}
}
/* Set the file descriptor for debugging output. */
-void tcfdbsetdbgfd(TCFDB *fdb, int fd){
- assert(fdb && fd >= 0);
+void tcfdbsetdbgfd(TCFDB *fdb, HANDLE fd){
+ assert(fdb);
fdb->dbgfd = fd;
}
/* Get the file descriptor for debugging output. */
-int tcfdbdbgfd(TCFDB *fdb){
+HANDLE tcfdbdbgfd(TCFDB *fdb){
assert(fdb);
return fdb->dbgfd;
}
/* Synchronize updating contents on memory of a fixed-length database object. */
bool tcfdbmemsync(TCFDB *fdb, bool phys){
assert(fdb);
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
tcfdbdumpmeta(fdb, hbuf);
memcpy(fdb->map, hbuf, FDBOPAQUEOFF);
if(phys){
-#ifndef __GNU__
- if(msync(fdb->map, fdb->limsiz, MS_SYNC) == -1){
+#ifdef _WIN32
+ if(!FlushViewOfFile(fdb->map, fdb->limsiz)){
+ tcfdbsetecode(fdb, TCEMMAP, __FILE__, __LINE__, __func__);
+ err = true;
+ }
+#elif !defined __GNU__
+ if(msync(fdb->map, fdb->limsiz, MS_SYNC)){
tcfdbsetecode(fdb, TCEMMAP, __FILE__, __LINE__, __func__);
err = true;
}
#endif
- if(fsync(fdb->fd) == -1){
+ if(fsync(fdb->fd)){
tcfdbsetecode(fdb, TCESYNC, __FILE__, __LINE__, __func__);
err = true;
}
/* Get the minimum ID number of records of a fixed-length database object. */
uint64_t tcfdbmin(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the maximum ID number of records of a fixed-length database object. */
uint64_t tcfdbmax(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the width of the value of each record of a fixed-length database object. */
uint32_t tcfdbwidth(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the limit file size of a fixed-length database object. */
uint64_t tcfdblimsiz(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the limit ID number of a fixed-length database object. */
uint64_t tcfdblimid(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the inode number of the database file of a fixed-length database object. */
uint64_t tcfdbinode(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the modification time of the database file of a fixed-length database object. */
time_t tcfdbmtime(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the connection mode of a fixed-length database object. */
int tcfdbomode(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the database type of a fixed-length database object. */
uint8_t tcfdbtype(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the additional flags of a fixed-length database object. */
uint8_t tcfdbflags(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the pointer to the opaque field of a fixed-length database object. */
char *tcfdbopaque(TCFDB *fdb){
assert(fdb);
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
return NULL;
}
bool tcfdbputproc(TCFDB *fdb, int64_t id, const void *vbuf, int vsiz, TCPDPROC proc, void *op){
assert(fdb && proc);
if(!FDBLOCKMETHOD(fdb, id < 1)) return false;
- if(fdb->fd < 0 || !(fdb->omode & FDBOWRITER)){
+ if(INVALIDHANDLE(fdb->fd) || !(fdb->omode & FDBOWRITER)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbiterinit2(TCFDB *fdb, int64_t id){
assert(fdb);
if(!FDBLOCKMETHOD(fdb, true)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
bool tcfdbforeach(TCFDB *fdb, TCITER iter, void *op){
assert(fdb && iter);
if(!FDBLOCKMETHOD(fdb, false)) return false;
- if(fdb->fd < 0){
+ if(INVALIDHANDLE(fdb->fd)){
tcfdbsetecode(fdb, TCEINVALID, __FILE__, __LINE__, __func__);
FDBUNLOCKMETHOD(fdb);
return false;
fdb->rsiz = 0;
fdb->limid = 0;
fdb->path = NULL;
- fdb->fd = -1;
+ fdb->fd = INVALID_HANDLE_VALUE;
fdb->omode = 0;
fdb->rnum = 0;
fdb->fsiz = 0;
fdb->inode = 0;
fdb->mtime = 0;
fdb->tran = false;
- fdb->walfd = -1;
+ fdb->walfd = INVALID_HANDLE_VALUE;
fdb->walend = 0;
- fdb->dbgfd = -1;
+ fdb->dbgfd = INVALID_HANDLE_VALUE;
fdb->cnt_writerec = -1;
fdb->cnt_readrec = -1;
fdb->cnt_truncfile = -1;
If successful, the return value is true, else, it is false. */
static bool tcfdbwalinit(TCFDB *fdb){
assert(fdb);
- if(lseek(fdb->walfd, 0, SEEK_SET) == -1){
+ if(!tcfseek(fdb->walfd, 0, TCFSTART)){
tcfdbsetecode(fdb, TCESEEK, __FILE__, __LINE__, __func__);
return false;
}
- if(ftruncate(fdb->walfd, 0) == -1){
+ if(!tcftruncate(fdb->walfd, 0)){
tcfdbsetecode(fdb, TCETRUNC, __FILE__, __LINE__, __func__);
return false;
}
return false;
}
if(buf != stack) TCFREE(buf);
- if((fdb->omode & FDBOTSYNC) && fsync(fdb->walfd) == -1){
+ if((fdb->omode & FDBOTSYNC) && fsync(fdb->walfd)){
tcfdbsetecode(fdb, TCESYNC, __FILE__, __LINE__, __func__);
FDBUNLOCKWAL(fdb);
return false;
static int tcfdbwalrestore(TCFDB *fdb, const char *path){
assert(fdb && path);
char *tpath = tcsprintf("%s%c%s", path, MYEXTCHR, FDBWALSUFFIX);
- int walfd = open(tpath, O_RDONLY, FDBFILEMODE);
+ HANDLE walfd;
+#ifndef _WIN32
+ walfd = open(tpath, O_RDONLY, FDBFILEMODE);
+#else
+ walfd = CreateFile(tpath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
TCFREE(tpath);
- if(walfd < 0) return false;
+ if(INVALIDHANDLE(walfd)) return false;
bool err = false;
uint64_t walsiz = 0;
struct stat sbuf;
- if(fstat(walfd, &sbuf) == 0){
+ if(!fstat(walfd, &sbuf)){
walsiz = sbuf.st_size;
} else {
tcfdbsetecode(fdb, TCESTAT, __FILE__, __LINE__, __func__);
err = true;
}
if(walsiz >= sizeof(walsiz) + FDBHEADSIZ){
- int dbfd = fdb->fd;
- int tfd = -1;
+ HANDLE dbfd = fdb->fd;
+ HANDLE tfd = INVALID_HANDLE_VALUE;
if(!(fdb->omode & FDBOWRITER)){
+#ifndef _WIN32
tfd = open(path, O_WRONLY, FDBFILEMODE);
- if(tfd >= 0){
+#else
+ tfd = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ if(!INVALIDHANDLE(tfd)){
dbfd = tfd;
} else {
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tcfdbsetecode(fdb, ecode, __FILE__, __LINE__, __func__);
+ tcfdbsetecode(fdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
err = true;
}
}
uint64_t off = *(uint64_t *)rec;
rec += sizeof(off);
size -= sizeof(off);
- if(lseek(dbfd, off, SEEK_SET) == -1){
+ if(!tcfseek(dbfd, off, TCFSTART)){
tcfdbsetecode(fdb, TCESEEK, __FILE__, __LINE__, __func__);
err = true;
break;
}
}
tclistdel(list);
- if(ftruncate(dbfd, fsiz) == -1){
+ if(!tcftruncate(dbfd, fsiz)){
tcfdbsetecode(fdb, TCETRUNC, __FILE__, __LINE__, __func__);
err = true;
}
- if((fdb->omode & FDBOTSYNC) && fsync(dbfd) == -1){
+ if((fdb->omode & FDBOTSYNC) && fsync(dbfd)){
tcfdbsetecode(fdb, TCESYNC, __FILE__, __LINE__, __func__);
err = true;
}
- if(tfd >= 0 && close(tfd) == -1){
+ if(!INVALIDHANDLE(tfd) && !CLOSEFH(tfd)){
tcfdbsetecode(fdb, TCECLOSE, __FILE__, __LINE__, __func__);
err = true;
}
} else {
err = true;
}
- if(close(walfd) == -1){
+ if(!CLOSEFH(walfd)){
tcfdbsetecode(fdb, TCECLOSE, __FILE__, __LINE__, __func__);
err = true;
}
assert(fdb && path);
char *tpath = tcsprintf("%s%c%s", path, MYEXTCHR, FDBWALSUFFIX);
bool err = false;
- if(unlink(tpath) == -1 && errno != ENOENT){
+ if(unlink(tpath) && errno != ENOENT){
tcfdbsetecode(fdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
If successful, the return value is true, else, it is false. */
static bool tcfdbopenimpl(TCFDB *fdb, const char *path, int omode){
assert(fdb && path);
+ HANDLE fd;
+#ifndef _WIN32
int mode = O_RDONLY;
if(omode & FDBOWRITER){
mode = O_RDWR;
if(omode & FDBOCREAT) mode |= O_CREAT;
}
- int fd = open(path, mode, FDBFILEMODE);
- if(fd < 0){
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tcfdbsetecode(fdb, ecode, __FILE__, __LINE__, __func__);
+ fd = open(path, mode, FDBFILEMODE);
+#else
+ DWORD mode, cmode;
+ mode = GENERIC_READ;
+ cmode = OPEN_EXISTING;
+ if(omode & FDBOWRITER) {
+ mode |= GENERIC_WRITE;
+ if(omode & (FDBOTRUNC|FDBOCREAT))
+ cmode = CREATE_ALWAYS;
+ else if(omode & FDBOTRUNC)
+ cmode = TRUNCATE_EXISTING;
+ else if(omode & FDBOCREAT)
+ cmode = CREATE_NEW;
+ }
+ fd = CreateFile(path, mode, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, cmode, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ if(INVALIDHANDLE(fd)){
+ tcfdbsetecode(fdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
return false;
}
if(!(omode & FDBONOLCK)){
if(!tclock(fd, omode & FDBOWRITER, omode & FDBOLCKNB)){
tcfdbsetecode(fdb, TCELOCK, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
if((omode & FDBOWRITER) && (omode & FDBOTRUNC)){
- if(ftruncate(fd, 0) == -1){
+ if(!tcftruncate(fd, 0)){
tcfdbsetecode(fdb, TCETRUNC, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(!tcfdbwalremove(fdb, path)){
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
struct stat sbuf;
- if(fstat(fd, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)){
+ if(fstat(fd, &sbuf) || !S_ISREG(sbuf.st_mode)){
tcfdbsetecode(fdb, TCESTAT, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
char hbuf[FDBHEADSIZ];
tcfdbdumpmeta(fdb, hbuf);
if(!tcwrite(fd, hbuf, FDBHEADSIZ)){
tcfdbsetecode(fdb, TCEWRITE, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
sbuf.st_size = fdb->fsiz;
}
- if(lseek(fd, 0, SEEK_SET) == -1){
+ if(!tcfseek(fd, 0, TCFSTART)){
tcfdbsetecode(fdb, TCESEEK, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(!tcread(fd, hbuf, FDBHEADSIZ)){
tcfdbsetecode(fdb, TCEREAD, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
int type = fdb->type;
tcfdbloadmeta(fdb, hbuf);
if((fdb->flags & FDBFOPEN) && tcfdbwalrestore(fdb, path)){
- if(lseek(fd, 0, SEEK_SET) == -1){
+ if(!tcfseek(fd, 0, TCFSTART)){
tcfdbsetecode(fdb, TCESEEK, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(!tcread(fd, hbuf, FDBHEADSIZ)){
tcfdbsetecode(fdb, TCEREAD, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
tcfdbloadmeta(fdb, hbuf);
if(!tcfdbwalremove(fdb, path)){
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
fdb->width < 1 || sbuf.st_size < fdb->fsiz || fdb->limsiz < FDBHEADSIZ ||
fdb->fsiz > fdb->limsiz){
tcfdbsetecode(fdb, TCEMETA, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(sbuf.st_size > fdb->fsiz) fdb->fsiz = sbuf.st_size;
}
- void *map = mmap(0, fdb->limsiz, PROT_READ | ((omode & FDBOWRITER) ? PROT_WRITE : 0),
+#ifndef _WIN32
+ void *map = mmap(0, fdb->limsiz, (PROT_READ | ((omode & FDBOWRITER) ? PROT_WRITE : 0)),
MAP_SHARED, fd, 0);
if(map == MAP_FAILED){
+#else
+ LARGE_INTEGER limit;
+ limit.QuadPart = fdb->limsiz;
+ fdb->fileMapping = CreateFileMapping(fd, NULL,
+ ((omode & FDBOWRITER) ? PAGE_READWRITE : PAGE_READONLY),
+ limit.HighPart, limit.LowPart, NULL);
+ void *map = MapViewOfFile(fdb->fileMapping,
+ ((omode & FDBOWRITER) ? FILE_MAP_WRITE : FILE_MAP_READ),
+ 0, 0, 0);
+ if(map == NULL){
+#endif
tcfdbsetecode(fdb, TCEMMAP, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(fdb->width <= UINT8_MAX){
fdb->inode = (uint64_t)sbuf.st_ino;
fdb->mtime = sbuf.st_mtime;
fdb->tran = false;
- fdb->walfd = -1;
+ fdb->walfd = INVALID_HANDLE_VALUE;
fdb->walend = 0;
if(fdb->omode & FDBOWRITER) tcfdbsetflag(fdb, FDBFOPEN, true);
return true;
bool err = false;
if(fdb->omode & FDBOWRITER) tcfdbsetflag(fdb, FDBFOPEN, false);
if((fdb->omode & FDBOWRITER) && !tcfdbmemsync(fdb, false)) err = true;
- if(munmap(fdb->map, fdb->limsiz) == -1){
+#ifndef _WIN32
+ if(munmap(fdb->map, fdb->limsiz)){
+#else
+ if(UnmapViewOfFile(fdb->map) && CloseHandle(fdb->fileMapping));
+ else{
+#endif
tcfdbsetecode(fdb, TCEMMAP, __FILE__, __LINE__, __func__);
err = true;
}
if(!tcfdbwalrestore(fdb, fdb->path)) err = true;
fdb->tran = false;
}
- if(fdb->walfd >= 0){
- if(close(fdb->walfd) == -1){
+ if(!INVALIDHANDLE(fdb->walfd)){
+ if(!CLOSEFH(fdb->walfd)){
tcfdbsetecode(fdb, TCECLOSE, __FILE__, __LINE__, __func__);
err = true;
}
if(!fdb->fatal && !tcfdbwalremove(fdb, fdb->path)) err = true;
}
- if(close(fdb->fd) == -1){
+ if(!CLOSEFH(fdb->fd)){
tcfdbsetecode(fdb, TCECLOSE, __FILE__, __LINE__, __func__);
err = true;
}
TCFREE(fdb->path);
fdb->path = NULL;
- fdb->fd = -1;
+ fdb->fd = INVALID_HANDLE_VALUE;
return !err;
}
return false;
}
if(nsiz + fdb->rsiz * FDBTRUNCALW < fdb->limsiz) nsiz += fdb->rsiz * FDBTRUNCALW;
- if(ftruncate(fdb->fd, nsiz) == -1){
+ if(!tcftruncate(fdb->fd, nsiz)){
tcfdbsetecode(fdb, TCETRUNC, __FILE__, __LINE__, __func__);
FDBUNLOCKATTR(fdb);
return false;
If successful, the return value is true, else, it is false. */
static bool tcfdboptimizeimpl(TCFDB *fdb, int32_t width, int64_t limsiz){
assert(fdb);
- char *tpath = tcsprintf("%s%ctmp%c%llu", fdb->path, MYEXTCHR, MYEXTCHR, fdb->inode);
+ char *tpath = tcsprintf("%s%ctmp%c%" PRIuMAX "", fdb->path, MYEXTCHR, MYEXTCHR, fdb->inode);
+ char *opath;
+ int omode = (fdb->omode & ~FDBOCREAT) & ~FDBOTRUNC;
TCFDB *tfdb = tcfdbnew();
tfdb->dbgfd = fdb->dbgfd;
if(width < 1) width = fdb->width;
err = true;
}
tcfdbdel(tfdb);
- if(unlink(fdb->path) == -1){
+ opath = tcstrdup(fdb->path);
+ if(!tcfdbcloseimpl(fdb)){
+ TCFREE(tpath);
+ TCFREE(opath);
+ return false;
+ }
+ if(unlink(opath)){
tcfdbsetecode(fdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
- if(rename(tpath, fdb->path) == -1){
+ if(rename(tpath, opath)){
tcfdbsetecode(fdb, TCERENAME, __FILE__, __LINE__, __func__);
err = true;
}
TCFREE(tpath);
- if(err) return false;
- tpath = tcstrdup(fdb->path);
- int omode = (fdb->omode & ~FDBOCREAT) & ~FDBOTRUNC;
- if(!tcfdbcloseimpl(fdb)){
- TCFREE(tpath);
+ if(err) {
+ TCFREE(opath);
return false;
}
- bool rv = tcfdbopenimpl(fdb, tpath, omode);
- TCFREE(tpath);
+ bool rv = tcfdbopenimpl(fdb, opath, omode);
+ TCFREE(opath);
return rv;
}
}
if(*path == '@'){
char tsbuf[TCNUMBUFSIZ];
- sprintf(tsbuf, "%llu", (unsigned long long)(tctime() * 1000000));
+ sprintf(tsbuf, "%" PRIuMAX "", (unsigned long long)(tctime() * 1000000));
const char *args[3];
args[0] = path + 1;
args[1] = fdb->path;
const void *vbuf = tcfdbgetimpl(fdb, id, &vsiz);
if(vbuf){
char kbuf[TCNUMBUFSIZ];
- int ksiz = sprintf(kbuf, "%llu", (unsigned long long)id);
+ int ksiz = sprintf(kbuf, "%" PRIuMAX "", (unsigned long long)id);
if(!iter(kbuf, ksiz, vbuf, vsiz, op)) break;
} else {
tcfdbsetecode(fdb, TCEMISC, __FILE__, __LINE__, __func__);
`fdb' specifies the fixed-length database object. */
void tcfdbprintmeta(TCFDB *fdb){
assert(fdb);
- if(fdb->dbgfd < 0) return;
- int dbgfd = (fdb->dbgfd == UINT16_MAX) ? 1 : fdb->dbgfd;
+ HANDLE dbgfd = INVALIDHANDLE(fdb->dbgfd) ? GET_STDOUT_HANDLE() : fdb->dbgfd;
char buf[FDBIOBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "META:");
wp += sprintf(wp, " type=%02X", fdb->type);
wp += sprintf(wp, " flags=%02X", fdb->flags);
wp += sprintf(wp, " width=%u", fdb->width);
- wp += sprintf(wp, " limsiz=%llu", (unsigned long long)fdb->limsiz);
+ wp += sprintf(wp, " limsiz=%" PRIuMAX "", (unsigned long long)fdb->limsiz);
wp += sprintf(wp, " wsiz=%u", fdb->wsiz);
wp += sprintf(wp, " rsiz=%u", fdb->rsiz);
- wp += sprintf(wp, " limid=%llu", (unsigned long long)fdb->limid);
+ wp += sprintf(wp, " limid=%" PRIuMAX "", (unsigned long long)fdb->limid);
wp += sprintf(wp, " path=%s", fdb->path ? fdb->path : "-");
wp += sprintf(wp, " fd=%d", fdb->fd);
wp += sprintf(wp, " omode=%u", fdb->omode);
- wp += sprintf(wp, " rnum=%llu", (unsigned long long)fdb->rnum);
- wp += sprintf(wp, " fsiz=%llu", (unsigned long long)fdb->fsiz);
- wp += sprintf(wp, " min=%llu", (unsigned long long)fdb->min);
- wp += sprintf(wp, " max=%llu", (unsigned long long)fdb->max);
- wp += sprintf(wp, " iter=%llu", (unsigned long long)fdb->iter);
+ wp += sprintf(wp, " rnum=%" PRIuMAX "", (unsigned long long)fdb->rnum);
+ wp += sprintf(wp, " fsiz=%" PRIuMAX "", (unsigned long long)fdb->fsiz);
+ wp += sprintf(wp, " min=%" PRIuMAX "", (unsigned long long)fdb->min);
+ wp += sprintf(wp, " max=%" PRIuMAX "", (unsigned long long)fdb->max);
+ wp += sprintf(wp, " iter=%" PRIuMAX "", (unsigned long long)fdb->iter);
wp += sprintf(wp, " map=%p", (void *)fdb->map);
wp += sprintf(wp, " array=%p", (void *)fdb->array);
wp += sprintf(wp, " ecode=%d", fdb->ecode);
wp += sprintf(wp, " fatal=%u", fdb->fatal);
- wp += sprintf(wp, " inode=%llu", (unsigned long long)fdb->inode);
- wp += sprintf(wp, " mtime=%llu", (unsigned long long)fdb->mtime);
+ wp += sprintf(wp, " inode=%" PRIuMAX "", (unsigned long long)fdb->inode);
+ wp += sprintf(wp, " mtime=%" PRIuMAX "", (unsigned long long)fdb->mtime);
wp += sprintf(wp, " tran=%d", fdb->tran);
wp += sprintf(wp, " walfd=%d", fdb->walfd);
- wp += sprintf(wp, " walend=%llu", (unsigned long long)fdb->walend);
+ wp += sprintf(wp, " walend=%" PRIuMAX "", (unsigned long long)fdb->walend);
wp += sprintf(wp, " dbgfd=%d", fdb->dbgfd);
- wp += sprintf(wp, " cnt_writerec=%lld", (long long)fdb->cnt_writerec);
- wp += sprintf(wp, " cnt_readrec=%lld", (long long)fdb->cnt_readrec);
- wp += sprintf(wp, " cnt_truncfile=%lld", (long long)fdb->cnt_truncfile);
+ wp += sprintf(wp, " cnt_writerec=%" PRIdMAX "", (long long)fdb->cnt_writerec);
+ wp += sprintf(wp, " cnt_readrec=%" PRIdMAX "", (long long)fdb->cnt_readrec);
+ wp += sprintf(wp, " cnt_truncfile=%" PRIdMAX "", (long long)fdb->cnt_truncfile);
*(wp++) = '\n';
tcwrite(dbgfd, buf, wp - buf);
}
int rsiz; /* size of each record */
uint64_t limid; /* limit ID number */
char *path; /* path of the database file */
- int fd; /* file descriptor of the database file */
+ HANDLE fd; /* file descriptor of the database file */
uint32_t omode; /* open mode */
uint64_t rnum; /* number of the records */
uint64_t fsiz; /* size of the database file */
uint64_t iter; /* ID number of the iterator */
char *map; /* pointer to the mapped memory */
unsigned char *array; /* pointer to the array region */
- int ecode; /* last happened error code */
+ volatile int ecode; /* last happened error code */
bool fatal; /* whether a fatal error occured */
uint64_t inode; /* inode number */
time_t mtime; /* modification time */
bool tran; /* whether in the transaction */
- int walfd; /* file descriptor of write ahead logging */
+ HANDLE walfd; /* file descriptor of write ahead logging */
uint64_t walend; /* end offset of write ahead logging */
- int dbgfd; /* file descriptor for debugging */
+ HANDLE dbgfd; /* file descriptor for debugging */
int64_t cnt_writerec; /* tesing counter for record write times */
int64_t cnt_readrec; /* tesing counter for record read times */
int64_t cnt_truncfile; /* tesing counter for file truncate times */
+#ifdef _WIN32
+ volatile HANDLE fileMapping; /* win32 file mappings for mmap */
+#endif
} TCFDB;
enum { /* enumeration for additional flags */
/* Set the file descriptor for debugging output.
`fdb' specifies the fixed-length database object.
`fd' specifies the file descriptor for debugging output. */
-void tcfdbsetdbgfd(TCFDB *fdb, int fd);
+void tcfdbsetdbgfd(TCFDB *fdb, HANDLE fd);
/* Get the file descriptor for debugging output.
`fdb' specifies the fixed-length database object.
The return value is the file descriptor for debugging output. */
-int tcfdbdbgfd(TCFDB *fdb);
+HANDLE tcfdbdbgfd(TCFDB *fdb);
/* Check whether mutual exclusion control is set to a fixed-length database object.
/* global variables */
const char *g_progname; // program name
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
/* main routine */
int main(int argc, char **argv){
g_progname = argv[0];
- g_dbgfd = -1;
+ g_dbgfd = INVALID_HANDLE_VALUE;
const char *ebuf = getenv("TCDBGFD");
- if(ebuf) g_dbgfd = tcatoix(ebuf);
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "create")){
/* perform create command */
static int proccreate(const char *path, int width, int64_t limsiz){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbtune(fdb, width, limsiz)){
printerr(fdb);
tcfdbdel(fdb);
/* perform inform command */
static int procinform(const char *path, int omode){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOREADER | omode)){
printerr(fdb);
tcfdbdel(fdb);
if(flags & FDBFOPEN) printf(" open");
if(flags & FDBFFATAL) printf(" fatal");
printf("\n");
- printf("minimum ID number: %llu\n", (unsigned long long)tcfdbmin(fdb));
- printf("maximum ID number: %llu\n", (unsigned long long)tcfdbmax(fdb));
+ printf("minimum ID number: %" PRIuMAX "\n", (unsigned long long)tcfdbmin(fdb));
+ printf("maximum ID number: %" PRIuMAX "\n", (unsigned long long)tcfdbmax(fdb));
printf("width of the value: %u\n", (unsigned int)tcfdbwidth(fdb));
- printf("limit file size: %llu\n", (unsigned long long)tcfdblimsiz(fdb));
- printf("limit ID number: %llu\n", (unsigned long long)tcfdblimid(fdb));
- printf("inode number: %lld\n", (long long)tcfdbinode(fdb));
+ printf("limit file size: %" PRIuMAX "\n", (unsigned long long)tcfdblimsiz(fdb));
+ printf("limit ID number: %" PRIuMAX "\n", (unsigned long long)tcfdblimid(fdb));
+ printf("inode number: %" PRIdMAX "\n", (long long)tcfdbinode(fdb));
char date[48];
tcdatestrwww(tcfdbmtime(fdb), INT_MAX, date);
printf("modified time: %s\n", date);
- printf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- printf("file size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ printf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ printf("file size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
if(!tcfdbclose(fdb)){
if(!err) printerr(fdb);
err = true;
static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
int omode, int dmode){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOWRITER | omode)){
printerr(fdb);
tcfdbdel(fdb);
/* perform out command */
static int procout(const char *path, const char *kbuf, int ksiz, int omode){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOWRITER | omode)){
printerr(fdb);
tcfdbdel(fdb);
/* perform get command */
static int procget(const char *path, const char *kbuf, int ksiz, int omode, bool px, bool pz){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOREADER | omode)){
printerr(fdb);
tcfdbdel(fdb);
static int proclist(const char *path, int omode, int max, bool pv, bool px,
const char *rlstr, const char *rustr, const char *ristr){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOREADER | omode)){
printerr(fdb);
tcfdbdel(fdb);
int cnt = 0;
uint64_t id;
while((id = tcfdbiternext(fdb)) > 0){
- printf("%llu", (unsigned long long)id);
+ printf("%" PRIuMAX "", (unsigned long long)id);
if(pv){
int vsiz;
char *vbuf = tcfdbget(fdb, id, &vsiz);
/* perform optimize command */
static int procoptimize(const char *path, int width, int64_t limsiz, int omode){
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOWRITER | omode)){
printerr(fdb);
tcfdbdel(fdb);
return 1;
}
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbopen(fdb, path, FDBOWRITER | FDBOCREAT | omode)){
printerr(fdb);
tcfdbdel(fdb);
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
/* print members of fixed-length database */
static void mprint(TCFDB *fdb){
if(fdb->cnt_writerec < 0) return;
- iprintf("minimum ID number: %llu\n", (unsigned long long)tcfdbmin(fdb));
- iprintf("maximum ID number: %llu\n", (unsigned long long)tcfdbmax(fdb));
+ iprintf("minimum ID number: %" PRIuMAX "\n", (unsigned long long)tcfdbmin(fdb));
+ iprintf("maximum ID number: %" PRIuMAX "\n", (unsigned long long)tcfdbmax(fdb));
iprintf("width of the value: %u\n", (unsigned int)tcfdbwidth(fdb));
- iprintf("limit file size: %llu\n", (unsigned long long)tcfdblimsiz(fdb));
- iprintf("limit ID number: %llu\n", (unsigned long long)tcfdblimid(fdb));
- iprintf("cnt_writerec: %lld\n", (long long)fdb->cnt_writerec);
- iprintf("cnt_readrec: %lld\n", (long long)fdb->cnt_readrec);
- iprintf("cnt_truncfile: %lld\n", (long long)fdb->cnt_truncfile);
+ iprintf("limit file size: %" PRIuMAX "\n", (unsigned long long)tcfdblimsiz(fdb));
+ iprintf("limit ID number: %" PRIuMAX "\n", (unsigned long long)tcfdblimid(fdb));
+ iprintf("cnt_writerec: %" PRIdMAX "\n", (long long)fdb->cnt_writerec);
+ iprintf("cnt_readrec: %" PRIdMAX "\n", (long long)fdb->cnt_readrec);
+ iprintf("cnt_truncfile: %" PRIdMAX "\n", (long long)fdb->cnt_truncfile);
}
/* perform write command */
static int procwrite(const char *path, int tnum, int rnum, int width, int64_t limsiz,
int omode, bool rnd){
- iprintf("<Writing Test>\n seed=%u path=%s tnum=%d rnum=%d width=%d limsiz=%lld"
- " omode=%d rnd=%d\n\n",
+ iprintf("<Writing Test>\n seed=%u path=%s tnum=%d rnum=%d width=%d limsiz=%" PRIdMAX " omode=%d rnd=%d\n\n",
g_randseed, path, tnum, rnum, width, (long long)limsiz, omode, rnd);
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum);
}
tcmapdel(map);
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
/* perform typical command */
static int proctypical(const char *path, int tnum, int rnum, int width, int64_t limsiz,
int omode, bool nc, int rratio){
- iprintf("<Typical Access Test>\n seed=%u path=%s tnum=%d rnum=%d width=%d limsiz=%lld"
- " omode=%d nc=%d rratio=%d\n\n",
+ iprintf("<Typical Access Test>\n seed=%u path=%s tnum=%d rnum=%d width=%d limsiz=%" PRIdMAX " omode=%d nc=%d rratio=%d\n\n",
g_randseed, path, tnum, rnum, width, (long long)limsiz, omode, nc, rratio);
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(!tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
for(int i = 1; i <= rnum && !err; i++){
uint64_t kid = myrand(rnum * (id + 1)) + 1;
char kbuf[RECBUFSIZ];
- int ksiz = sprintf(kbuf, "%llu", (unsigned long long)kid);
+ int ksiz = sprintf(kbuf, "%" PRIuMAX "", (unsigned long long)kid);
char vbuf[RECBUFSIZ];
int vsiz = myrand(RECBUFSIZ);
memset(vbuf, '*', vsiz);
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
const char *ebuf = getenv("TCRNDSEED");
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
+ g_dbgfd = INVALID_HANDLE_VALUE;
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
static void eprint(TCFDB *fdb, int line, const char *func){
const char *path = tcfdbpath(fdb);
int ecode = tcfdbecode(fdb);
- fprintf(stderr, "%s: %s: %d: %s: error: %d: %s\n",
- g_progname, path ? path : "-", line, func, ecode, tcfdberrmsg(ecode));
+ int stderrno = errno;
+#ifdef _WIN32
+ DWORD myerrno = GetLastError();
+ LPTSTR errorText = NULL;
+ DWORD ret = FormatMessage(
+ // use system message tables to retrieve error text
+ FORMAT_MESSAGE_FROM_SYSTEM
+ // allocate buffer on local heap for error text
+ |FORMAT_MESSAGE_ALLOCATE_BUFFER
+ // Important! will fail otherwise, since we're not
+ // (and CANNOT) pass insertion parameters
+ |FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, // unused with FORMAT_MESSAGE_FROM_SYSTEM
+ myerrno,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)&errorText, // output
+ 0, // minimum size for output buffer
+ NULL); // arguments - see note
+ if (!ret) {
+ if (errorText) LocalFree(errorText);
+ errorText = NULL;
+ }
+ fprintf(stderr, "%s: %s: %d: %s: error: %d:%s:%d:%s:%d:%s\n",
+ g_progname, path ? path : "-",
+ line, func,
+ ecode, tcfdberrmsg(ecode),
+ myerrno, errorText ? errorText : "-",
+ stderrno, strerror(stderrno));
+
+ if (errorText) LocalFree(errorText);
+#else
+ fprintf(stderr, "%s: %s: %d: %s: error: %d:%s:%d:%s\n",
+ g_progname, path ? path : "-",
+ line, func,
+ ecode, tcfdberrmsg(ecode),
+ stderrno, strerror(stderrno));
+#endif
}
/* print members of fixed-length database */
static void mprint(TCFDB *fdb){
if(fdb->cnt_writerec < 0) return;
- iprintf("minimum ID number: %llu\n", (unsigned long long)tcfdbmin(fdb));
- iprintf("maximum ID number: %llu\n", (unsigned long long)tcfdbmax(fdb));
+ iprintf("minimum ID number: %" PRIuMAX "\n", (unsigned long long)tcfdbmin(fdb));
+ iprintf("maximum ID number: %" PRIuMAX "\n", (unsigned long long)tcfdbmax(fdb));
iprintf("width of the value: %u\n", (unsigned int)tcfdbwidth(fdb));
- iprintf("limit file size: %llu\n", (unsigned long long)tcfdblimsiz(fdb));
- iprintf("limit ID number: %llu\n", (unsigned long long)tcfdblimid(fdb));
- iprintf("cnt_writerec: %lld\n", (long long)fdb->cnt_writerec);
- iprintf("cnt_readrec: %lld\n", (long long)fdb->cnt_readrec);
- iprintf("cnt_truncfile: %lld\n", (long long)fdb->cnt_truncfile);
+ iprintf("limit file size: %" PRIuMAX "\n", (unsigned long long)tcfdblimsiz(fdb));
+ iprintf("limit ID number: %" PRIuMAX "\n", (unsigned long long)tcfdblimid(fdb));
+ iprintf("cnt_writerec: %" PRIdMAX "\n", (long long)fdb->cnt_writerec);
+ iprintf("cnt_readrec: %" PRIdMAX "\n", (long long)fdb->cnt_readrec);
+ iprintf("cnt_truncfile: %" PRIdMAX "\n", (long long)fdb->cnt_truncfile);
}
/* perform write command */
static int procwrite(const char *path, int rnum, int width, int64_t limsiz,
bool mt, int omode, bool rnd){
- iprintf("<Writing Test>\n seed=%u path=%s rnum=%d width=%d limsiz=%lld mt=%d omode=%d"
+ iprintf("<Writing Test>\n seed=%u path=%s rnum=%d width=%d limsiz=%" PRIdMAX " mt=%d omode=%d"
" rnd=%d\n\n", g_randseed, path, rnum, width, (long long)limsiz, mt, omode, rnd);
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(mt && !tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(mt && !tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(mt && !tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
static int procrcat(const char *path, int rnum, int width, int64_t limsiz,
bool mt, int omode, int pnum, bool dai, bool dad, bool rl, bool ru){
iprintf("<Random Concatenating Test>\n"
- " seed=%u path=%s rnum=%d width=%d limsiz=%lld mt=%d omode=%d pnum=%d"
+ " seed=%u path=%s rnum=%d width=%d limsiz=%" PRIdMAX " mt=%d omode=%d pnum=%d"
" dai=%d dad=%d rl=%d ru=%d\n\n",
g_randseed, path, rnum, width, (long long)limsiz, mt, omode, pnum, dai, dad, rl, ru);
if(pnum < 1) pnum = rnum;
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(mt && !tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(mt && !tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
eprint(fdb, __LINE__, "tcfdbopen");
err = true;
}
- if(TCUSEPTHREAD){
+ if(1){
TCFDB *fdbdup = tcfdbnew();
if(tcfdbopen(fdbdup, path, FDBOREADER)){
eprint(fdb, __LINE__, "(validation)");
err = true;
}
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
if(!tcfdbclose(fdb)){
bool err = false;
double stime = tctime();
TCFDB *fdb = tcfdbnew();
- if(g_dbgfd >= 0) tcfdbsetdbgfd(fdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tcfdbsetdbgfd(fdb, g_dbgfd);
if(mt && !tcfdbsetmutex(fdb)){
eprint(fdb, __LINE__, "tcfdbsetmutex");
err = true;
for(int i = 1; i <= rnum && !err; i++){
uint64_t id = myrand(rnum) + 1;
char kbuf[RECBUFSIZ];
- int ksiz = sprintf(kbuf, "%llu", (unsigned long long)id);
+ int ksiz = sprintf(kbuf, "%" PRIuMAX "", (unsigned long long)id);
char vbuf[RECBUFSIZ];
int vsiz = myrand(RECBUFSIZ);
memset(vbuf, '*', vsiz);
eprint(fdb, __LINE__, "(validation)");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tcfdbrnum(fdb));
- iprintf("size: %llu\n", (unsigned long long)tcfdbfsiz(fdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcfdbrnum(fdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcfdbfsiz(fdb));
mprint(fdb);
sysprint();
tcmapdel(map);
#define HDBIOBUFSIZ 8192 // size of an I/O buffer
#define HDBMAGICDATA "ToKyO CaBiNeT" // magic data for identification
-#define HDBHEADSIZ 256 // size of the reagion of the header
+#define HDBHEADSIZ 256 // size of the region of the header
#define HDBTYPEOFF 32 // offset of the region for the database type
#define HDBFLAGSOFF 33 // offset of the region for the additional flags
#define HDBAPOWOFF 34 // offset of the region for the alignment power
#define HDBFSIZOFF 56 // offset of the region for the file size
#define HDBFRECOFF 64 // offset of the region for the first record offset
#define HDBOPAQUEOFF 128 // offset of the region for the opaque field
+#define HDBOPAQUESZ HDBHEADSIZ - HDBOPAQUEOFF //opaque data size
+#define HDBB64(TC_hdb) ((uint64_t *) ((char *)((TC_hdb)->map) + HDBHEADSIZ))
+#define HDBB32(TC_hdb) ((uint32_t *) ((char *)((TC_hdb)->map) + HDBHEADSIZ))
#define HDBDEFBNUM 131071 // default bucket number
#define HDBDEFAPOW 4 // default alignment power
#define HDBMAXAPOW 16 // maximum alignment power
#define HDBDEFFPOW 10 // default free block pool power
#define HDBMAXFPOW 20 // maximum free block pool power
+
+#ifdef _WIN32
+#define HDBDEFXMSIZ _maxof(off_t) // default size of the extra mapped memory
+#define HDBXFSIZINC 1048576 // 1MB on win32
+#else
#define HDBDEFXMSIZ (64LL<<20) // default size of the extra mapped memory
#define HDBXFSIZINC 32768 // increment of extra file size
+#endif
#define HDBMINRUNIT 48 // minimum record reading unit
#define HDBMAXHSIZ 32 // maximum record header size
#define HDBFBPALWRAT 2 // allowance ratio of the free block pool
} HDBPDPROCOP;
+enum {
+ HDBWRITENOWALL = 1, //do not write into wall in tchdbseekwrite
+ HDBWRITENOLOCK = 1 << 1 //do not use shared write lock in tchdbseekwrite & tchdbftruncate
+};
+
/* private macros */
#define HDBLOCKMETHOD(TC_hdb, TC_wr) \
((TC_hdb)->mmtx ? tchdblockmethod((TC_hdb), (TC_wr)) : true)
((TC_hdb)->mmtx ? tchdblockdb(TC_hdb) : true)
#define HDBUNLOCKDB(TC_hdb) \
((TC_hdb)->mmtx ? tchdbunlockdb(TC_hdb) : true)
+
+#define HDBLOCKSMEM(TC_hdb, TC_wr) \
+ ((TC_hdb)->smtx ? tchdblocksmem((TC_hdb), (TC_wr)) : true)
+#define HDBUNLOCKSMEM(TC_hdb) \
+ ((TC_hdb)->smtx ? tchdbunlocksmem(TC_hdb) : true)
+
#define HDBLOCKWAL(TC_hdb) \
((TC_hdb)->mmtx ? tchdblockwal(TC_hdb) : true)
#define HDBUNLOCKWAL(TC_hdb) \
/* private function prototypes */
static uint64_t tcgetprime(uint64_t num);
static bool tchdbseekwrite(TCHDB *hdb, off_t off, const void *buf, size_t size);
+static bool tchdbseekwrite2(TCHDB *hdb, off_t off, const void *buf, size_t size, int opts);
static bool tchdbseekread(TCHDB *hdb, off_t off, void *buf, size_t size);
static bool tchdbseekreadtry(TCHDB *hdb, off_t off, void *buf, size_t size);
static void tchdbdumpmeta(TCHDB *hdb, char *hbuf);
static void tchdbcacheadjust(TCHDB *hdb);
static bool tchdbwalinit(TCHDB *hdb);
static bool tchdbwalwrite(TCHDB *hdb, uint64_t off, int64_t size);
-static int tchdbwalrestore(TCHDB *hdb, const char *path);
+static bool tchdbwalrestore(TCHDB *hdb, const char *path);
static bool tchdbwalremove(TCHDB *hdb, const char *path);
static bool tchdbopenimpl(TCHDB *hdb, const char *path, int omode);
static bool tchdbcloseimpl(TCHDB *hdb);
static bool tchdbdefragimpl(TCHDB *hdb, int64_t step);
static bool tchdbiterjumpimpl(TCHDB *hdb, const char *kbuf, int ksiz);
static bool tchdbforeachimpl(TCHDB *hdb, TCITER iter, void *op);
-static bool tchdblockmethod(TCHDB *hdb, bool wr);
-static bool tchdbunlockmethod(TCHDB *hdb);
-static bool tchdblockrecord(TCHDB *hdb, uint8_t bidx, bool wr);
-static bool tchdbunlockrecord(TCHDB *hdb, uint8_t bidx);
-static bool tchdblockallrecords(TCHDB *hdb, bool wr);
-static bool tchdbunlockallrecords(TCHDB *hdb);
-static bool tchdblockdb(TCHDB *hdb);
-static bool tchdbunlockdb(TCHDB *hdb);
-static bool tchdblockwal(TCHDB *hdb);
-static bool tchdbunlockwal(TCHDB *hdb);
-
+static bool tchdbftruncate(TCHDB *hdb, off_t length);
+static bool tchdbftruncate2(TCHDB *hdb, off_t length, int opts);
+
+EJDB_INLINE bool tchdblockmethod(TCHDB *hdb, bool wr);
+EJDB_INLINE bool tchdbunlockmethod(TCHDB *hdb);
+EJDB_INLINE bool tchdblocksmem(TCHDB *hdb, bool wr);
+EJDB_INLINE bool tchdbunlocksmem(TCHDB *hdb);
+EJDB_INLINE bool tchdblockrecord(TCHDB *hdb, uint8_t bidx, bool wr);
+EJDB_INLINE bool tchdbunlockrecord(TCHDB *hdb, uint8_t bidx);
+EJDB_INLINE bool tchdblockallrecords(TCHDB *hdb, bool wr);
+EJDB_INLINE bool tchdbunlockallrecords(TCHDB *hdb);
+EJDB_INLINE bool tchdblockdb(TCHDB *hdb);
+EJDB_INLINE bool tchdbunlockdb(TCHDB *hdb);
+EJDB_INLINE bool tchdblockwal(TCHDB *hdb);
+EJDB_INLINE bool tchdbunlockwal(TCHDB *hdb);
/* debugging function prototypes */
void tchdbprintmeta(TCHDB *hdb);
/* Delete a hash database object. */
void tchdbdel(TCHDB *hdb){
assert(hdb);
- if(hdb->fd >= 0) tchdbclose(hdb);
+ if(!INVALIDHANDLE(hdb->fd)) tchdbclose(hdb);
if(hdb->mmtx){
pthread_mutex_destroy(hdb->wmtx);
pthread_mutex_destroy(hdb->dmtx);
pthread_rwlock_destroy((pthread_rwlock_t *)hdb->rmtxs + i);
}
pthread_rwlock_destroy(hdb->mmtx);
+ pthread_rwlock_destroy(hdb->smtx);
TCFREE(hdb->wmtx);
TCFREE(hdb->dmtx);
+ TCFREE(hdb->smtx);
TCFREE(hdb->rmtxs);
TCFREE(hdb->mmtx);
}
/* Set mutual exclusion control of a hash database object for threading. */
bool tchdbsetmutex(TCHDB *hdb){
assert(hdb);
- if(!TCUSEPTHREAD) return true;
- if(hdb->mmtx || hdb->fd >= 0){
+ if(hdb->mmtx || !INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
pthread_mutexattr_t rma;
pthread_mutexattr_init(&rma);
TCMALLOC(hdb->mmtx, sizeof(pthread_rwlock_t));
+ TCMALLOC(hdb->smtx, sizeof(pthread_rwlock_t));
TCMALLOC(hdb->rmtxs, (UINT8_MAX + 1) * sizeof(pthread_rwlock_t));
TCMALLOC(hdb->dmtx, sizeof(pthread_mutex_t));
TCMALLOC(hdb->wmtx, sizeof(pthread_mutex_t));
bool err = false;
if(pthread_mutexattr_settype(&rma, PTHREAD_MUTEX_RECURSIVE) != 0) err = true;
+ if(pthread_rwlock_init(hdb->smtx, NULL) != 0) err = true;
if(pthread_rwlock_init(hdb->mmtx, NULL) != 0) err = true;
for(int i = 0; i <= UINT8_MAX; i++){
if(pthread_rwlock_init((pthread_rwlock_t *)hdb->rmtxs + i, NULL) != 0) err = true;
TCFREE(hdb->wmtx);
TCFREE(hdb->dmtx);
TCFREE(hdb->rmtxs);
+ TCFREE(hdb->smtx);
TCFREE(hdb->mmtx);
hdb->wmtx = NULL;
hdb->dmtx = NULL;
hdb->rmtxs = NULL;
+ hdb->smtx = NULL;
hdb->mmtx = NULL;
return false;
}
/* Set the tuning parameters of a hash database object. */
bool tchdbtune(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){
assert(hdb);
- if(hdb->fd >= 0){
+ if(!INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
/* Set the caching parameters of a hash database object. */
bool tchdbsetcache(TCHDB *hdb, int32_t rcnum){
assert(hdb);
- if(hdb->fd >= 0){
+ if(!INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
/* Set the size of the extra mapped memory of a hash database object. */
bool tchdbsetxmsiz(TCHDB *hdb, int64_t xmsiz){
+#ifdef _WIN32
+ fprintf(stderr, "\ntchdbsetxmsiz does not takes effect on windows platform\n");
+ return true;
+#else
assert(hdb);
- if(hdb->fd >= 0){
+ if(!INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
hdb->xmsiz = (xmsiz > 0) ? tcpagealign(xmsiz) : 0;
return true;
+#endif
}
/* Set the unit step number of auto defragmentation of a hash database object. */
bool tchdbsetdfunit(TCHDB *hdb, int32_t dfunit){
assert(hdb);
- if(hdb->fd >= 0){
+ if(!INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
bool tchdbopen(TCHDB *hdb, const char *path, int omode){
assert(hdb && path);
if(!HDBLOCKMETHOD(hdb, true)) return false;
+ if(!INVALIDHANDLE(hdb->fd)){
+ tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
if (!hdb->eckey) {
TCMALLOC(hdb->eckey, sizeof(pthread_key_t));
if(pthread_key_create(hdb->eckey, NULL)) {
return false;
}
}
- if(hdb->fd >= 0){
- tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
- HDBUNLOCKMETHOD(hdb);
- return false;
- }
char *rpath = tcrealpath(path);
if(!rpath){
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tchdbsetecode(hdb, ecode, __FILE__, __LINE__, __func__);
+ tchdbsetecode(hdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
}
bool tchdbclose(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(!HDBLOCKMETHOD(hdb, false)) return false;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(!HDBLOCKMETHOD(hdb, false)) return false;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(!HDBLOCKMETHOD(hdb, false)) return false;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
hdb->async = true;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(!HDBLOCKMETHOD(hdb, false)) return false;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(!HDBLOCKMETHOD(hdb, false)) return NULL;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return NULL;
if (!HDBLOCKMETHOD(hdb, false)) return -1;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if (hdb->fd < 0) {
+ if (INVALIDHANDLE(hdb->fd)) {
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return -1;
if(!HDBLOCKMETHOD(hdb, false)) return -1;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return -1;
if(!HDBLOCKMETHOD(hdb, false)) return -1;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return -1;
bool tchdbiterinit(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbiterinit4(TCHDB *hdb, uint64_t *iter){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
return true;
}
-
/* Get the next key of the iterator of a hash database object. */
void *tchdbiternext(TCHDB *hdb, int *sp){
assert(hdb && sp);
if(!HDBLOCKMETHOD(hdb, true)) return NULL;
- if(hdb->fd < 0 || hdb->iter < 1){
+ if(INVALIDHANDLE(hdb->fd) || hdb->iter < 1){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return NULL;
bool tchdbiternext3(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr){
assert(hdb && kxstr && vxstr);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || hdb->iter < 1){
+ if(INVALIDHANDLE(hdb->fd) || hdb->iter < 1){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbiternext4(TCHDB *hdb, uint64_t *iter, TCXSTR *kxstr, TCXSTR *vxstr){
assert(hdb && kxstr && vxstr && iter);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || *iter < 1){
+ if(INVALIDHANDLE(hdb->fd) || *iter < 1){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
assert(hdb && pbuf && psiz >= 0);
TCLIST* keys = tclistnew();
if(!HDBLOCKMETHOD(hdb, true)) return keys;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return keys;
if(!HDBLOCKMETHOD(hdb, false)) return INT_MIN;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return INT_MIN;
if(!HDBLOCKMETHOD(hdb, false)) return nan("");
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return nan("");
bool tchdbsync(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->tran){
+ if (hdb->tran) {
+ tchdbsetecode(hdb, TCETR, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdboptimize(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->tran){
+ if (hdb->tran) {
+ tchdbsetecode(hdb, TCETR, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbvanish(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->tran){
+ if (hdb->tran) {
+ tchdbsetecode(hdb, TCETR, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbcopy(TCHDB *hdb, const char *path){
assert(hdb && path);
if(!HDBLOCKMETHOD(hdb, false)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
/* Begin the transaction of a hash database object. */
bool tchdbtranbegin(TCHDB *hdb){
assert(hdb);
- for(double wsec = 1.0 / sysconf(_SC_CLK_TCK); true; wsec *= 2){
+ for(double wsec = 1.0 / sysconf_SC_CLK_TCK; true; wsec *= 2){
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->fatal){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER) || hdb->fatal){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
HDBUNLOCKMETHOD(hdb);
return false;
}
- if(!tchdbmemsync(hdb, false)){
+ if(!tchdbmemsync(hdb, (hdb->omode & HDBOTSYNC))){
HDBUNLOCKMETHOD(hdb);
return false;
}
- if((hdb->omode & HDBOTSYNC) && fsync(hdb->fd) == -1){
- tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__);
- return false;
- }
- if(hdb->walfd < 0){
+ if(INVALIDHANDLE(hdb->walfd)){
char *tpath = tcsprintf("%s%c%s", hdb->path, MYEXTCHR, HDBWALSUFFIX);
- int walfd = open(tpath, O_RDWR | O_CREAT | O_TRUNC, HDBFILEMODE);
+#ifndef _WIN32
+ HANDLE walfd = open(tpath, O_RDWR | O_CREAT | O_TRUNC, HDBFILEMODE);
+#else
+ HANDLE walfd = CreateFile(tpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
TCFREE(tpath);
- if(walfd < 0){
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tchdbsetecode(hdb, ecode, __FILE__, __LINE__, __func__);
+ if(INVALIDHANDLE(walfd)){
+ tchdbsetecode(hdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
}
bool tchdbtrancommit(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->fatal || !hdb->tran){
+ if (!hdb->tran) {
+ tchdbsetecode(hdb, TCETR, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER) || hdb->fatal){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
}
bool err = false;
if(hdb->async && !tchdbflushdrp(hdb)) err = true;
- if(!tchdbmemsync(hdb, hdb->omode & HDBOTSYNC)) err = true;
- if(!err && ftruncate(hdb->walfd, 0) == -1){
+ if(!tchdbmemsync(hdb, (hdb->omode & HDBOTSYNC))) err = true;
+ if(!err && !tcftruncate(hdb->walfd, 0)){
tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
err = true;
}
bool tchdbtranabort(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || !hdb->tran){
+ if (!hdb->tran) {
+ tchdbsetecode(hdb, TCETR, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(hdb->async && !tchdbflushdrp(hdb)) err = true;
if(!tchdbmemsync(hdb, false)) err = true;
if(!tchdbwalrestore(hdb, hdb->path)) err = true;
- char hbuf[HDBHEADSIZ];
- if(lseek(hdb->fd, 0, SEEK_SET) == -1){
- tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
- err = false;
- } else if(!tcread(hdb->fd, hbuf, HDBHEADSIZ)){
- tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
- err = false;
- } else {
- tchdbloadmeta(hdb, hbuf);
- }
hdb->dfcur = hdb->frec;
hdb->iter = 0;
- hdb->xfsiz = 0;
hdb->fbpnum = 0;
if(hdb->recc) tcmdbvanish(hdb->recc);
hdb->tran = false;
const char *tchdbpath(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, false)) return NULL;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return NULL;
uint64_t tchdbrnum(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, false)) return 0;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return 0;
uint64_t tchdbfsiz(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, false)) return 0;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return 0;
/* Set the error code of a hash database object. */
void tchdbsetecode(TCHDB *hdb, int ecode, const char *filename, int line, const char *func){
assert(hdb && filename && line >= 1 && func);
- int myerrno = errno;
- if(!hdb->fatal){
+ if(!hdb->fatal) {
if (hdb->eckey) {
pthread_setspecific(*(pthread_key_t *)hdb->eckey, (void *)(intptr_t)ecode);
- } else {
- hdb->ecode = ecode;
}
+ hdb->ecode = ecode;
}
- if (ecode == TCESUCCESS) {
- return;
- }
-
switch (ecode) { //Fatal errors
case TCETHREAD:
case TCENOFILE:
case TCERENAME:
case TCEMKDIR:
case TCERMDIR:
- case TCEMISC:
{
hdb->fatal = true;
- if (hdb->fd >= 0 && (hdb->omode & HDBOWRITER)) tchdbsetflag(hdb, HDBFFATAL, true);
+ if (!INVALIDHANDLE(hdb->fd) && (hdb->omode & HDBOWRITER)) tchdbsetflag(hdb, HDBFFATAL, true);
break;
}
+ case TCESUCCESS:
+ case TCENOREC:
+ case TCEKEEP:
+ return;
+ break;
default:
break;
}
-
- if(ecode != TCENOREC && hdb->dbgfd >= 0 && (hdb->dbgfd != UINT16_MAX || hdb->fatal)){
- int dbgfd = (hdb->dbgfd == UINT16_MAX) ? 1 : hdb->dbgfd;
+#ifdef _WIN32
+ DWORD winerrno = GetLastError();
+#endif
+ int stderrno = errno;
+ if(!INVALIDHANDLE(hdb->dbgfd) || hdb->fatal) {
+ HANDLE dbgfd = INVALIDHANDLE(hdb->dbgfd) ? GET_STDERR_HANDLE() : (hdb->dbgfd);
char obuf[HDBIOBUFSIZ];
- int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s:%d:%s\n", filename, line, func,
- hdb->path ? hdb->path : "-", ecode, tchdberrmsg(ecode),
- myerrno, strerror(myerrno));
+#ifdef _WIN32
+ LPTSTR errorText = NULL;
+ if (winerrno > 0) {
+ DWORD ret = FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, winerrno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &errorText, 0, NULL);
+ if (!ret) {
+ if (errorText) LocalFree(errorText);
+ errorText = NULL;
+ }
+ }
+ int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s:%d:%s:%d:%s\n",
+ filename, line,
+ func, (hdb->path ? hdb->path : "-"),
+ ecode, tchdberrmsg(ecode),
+ winerrno, (errorText ? errorText : "-"),
+ stderrno, (stderrno > 0 ? strerror(stderrno) : "-"));
+ if (errorText) LocalFree(errorText);
+#else
+ int osiz = sprintf(obuf, "ERROR:%s:%d:%s:%s:%d:%s:%d:%s\n",
+ filename, line,
+ func, (hdb->path ? hdb->path : "-"),
+ ecode, tchdberrmsg(ecode),
+ stderrno, strerror(stderrno));
+#endif
tcwrite(dbgfd, obuf, osiz);
}
}
-
/* Set the type of a hash database object. */
void tchdbsettype(TCHDB *hdb, uint8_t type){
assert(hdb);
- if(hdb->fd >= 0){
+ if(!INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return;
}
/* Set the file descriptor for debugging output. */
-void tchdbsetdbgfd(TCHDB *hdb, int fd){
- assert(hdb && fd >= 0);
+void tchdbsetdbgfd(TCHDB *hdb, HANDLE fd){
+ assert(hdb);
hdb->dbgfd = fd;
}
/* Get the file descriptor for debugging output. */
-int tchdbdbgfd(TCHDB *hdb){
+HANDLE tchdbdbgfd(TCHDB *hdb){
assert(hdb);
return hdb->dbgfd;
}
/* Synchronize updating contents on memory of a hash database object. */
bool tchdbmemsync(TCHDB *hdb, bool phys){
assert(hdb);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ bool err = false;
+ char hbuf[HDBHEADSIZ];
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
}
- bool err = false;
- char hbuf[HDBHEADSIZ];
tchdbdumpmeta(hdb, hbuf);
- memcpy(hdb->map, hbuf, HDBOPAQUEOFF);
+ if (!HDBLOCKSMEM(hdb, true)) return false;
+ memcpy((void *) hdb->map, hbuf, HDBOPAQUEOFF);
+ HDBUNLOCKSMEM(hdb);
if(phys){
+ if (!HDBLOCKSMEM(hdb, false)) return false;
+#ifdef _WIN32
+ if(!FlushViewOfFile((PCVOID) hdb->map, 0)){
+ tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
+ err = true;
+ }
+#elif !defined __GNU__
size_t xmsiz = (hdb->xmsiz > hdb->msiz) ? hdb->xmsiz : hdb->msiz;
-#ifndef __GNU__
- if(msync(hdb->map, xmsiz, MS_SYNC) == -1){
+ if(msync(hdb->map, xmsiz, MS_SYNC)){
tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
err = true;
}
-#endif
- if(fsync(hdb->fd) == -1){
+#endif
+ if(fsync(hdb->fd)){
tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__);
err = true;
}
+ HDBUNLOCKSMEM(hdb);
}
return !err;
}
/* Get the number of elements of the bucket array of a hash database object. */
uint64_t tchdbbnum(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the record alignment a hash database object. */
uint32_t tchdbalign(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the maximum number of the free block pool of a a hash database object. */
uint32_t tchdbfbpmax(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the size of the extra mapped memory of a hash database object. */
uint64_t tchdbxmsiz(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the inode number of the database file of a hash database object. */
uint64_t tchdbinode(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the modification time of the database file of a hash database object. */
time_t tchdbmtime(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the connection mode of a hash database object. */
int tchdbomode(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the database type of a hash database object. */
uint8_t tchdbtype(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the additional flags of a hash database object. */
uint8_t tchdbflags(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
/* Get the options of a hash database object. */
uint8_t tchdbopts(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
return hdb->opts;
}
-
-/* Get the pointer to the opaque field of a hash database object. */
-char *tchdbopaque(TCHDB *hdb){
- assert(hdb);
- if(hdb->fd < 0){
- tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
- return NULL;
- }
- return hdb->map + HDBOPAQUEOFF;
+bool tchdbcopyopaque(TCHDB *dst, TCHDB *src, int off, int rsz) {
+ assert(dst && src);
+ if (rsz == -1) {
+ rsz = HDBOPAQUESZ;
+ }
+ char odata[HDBOPAQUESZ];
+ rsz = tchdbreadopaque(src, odata, off, rsz);
+ if (rsz == -1) {
+ tchdbsetecode(dst, tchdbecode(src), __FILE__, __LINE__, __func__);
+ return false;
+ }
+ return (tchdbwriteopaque(dst, odata, off, rsz) == rsz);
}
+int tchdbreadopaque(TCHDB *hdb, void *dst, int off, int bsiz) {
+ assert(hdb && dst);
+ if (bsiz == -1) {
+ bsiz = HDBOPAQUESZ;
+ }
+ if (off > HDBOPAQUESZ) {
+ tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
+ return -1;
+ }
+ bsiz = MIN(bsiz, HDBOPAQUESZ - off);
+ if (bsiz <= 0) {
+ tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
+ return -1;
+ }
+ if (!HDBLOCKSMEM(hdb, false)) return -1;
+ assert(hdb->map);
+ memcpy((void *) dst, (void *) (hdb->map + HDBOPAQUEOFF + off), bsiz);
+ HDBUNLOCKSMEM(hdb);
+ return bsiz;
+}
+
+int tchdbwriteopaque(TCHDB *hdb, const void *src, int off, int nb) {
+ assert(hdb && src);
+ if (nb == -1) {
+ nb = HDBOPAQUESZ;
+ }
+ if (off > HDBOPAQUESZ) {
+ tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
+ return -1;
+ }
+ nb = MIN(nb, HDBOPAQUESZ - off);
+ if (nb <= 0) {
+ tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
+ return -1;
+ }
+ if (!HDBLOCKSMEM(hdb, true)) return -1;
+ memcpy((void *) (hdb->map + HDBOPAQUEOFF + off), src, nb);
+ HDBUNLOCKSMEM(hdb);
+ return nb;
+}
/* Get the number of used elements of the bucket array of a hash database object. */
uint64_t tchdbbnumused(TCHDB *hdb){
assert(hdb);
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
return 0;
}
+ if (!HDBLOCKSMEM(hdb, false)) return false;
uint64_t unum = 0;
if(hdb->ba64){
- uint64_t *buckets = hdb->ba64;
+ uint64_t *buckets = HDBB64(hdb);
for(int i = 0; i < hdb->bnum; i++){
if(buckets[i]) unum++;
}
} else {
- uint32_t *buckets = hdb->ba32;
+ uint32_t *buckets = HDBB32(hdb);
for(int i = 0; i < hdb->bnum; i++){
if(buckets[i]) unum++;
}
}
+ HDBUNLOCKSMEM(hdb);
return unum;
}
bool tchdbsetcodecfunc(TCHDB *hdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop){
assert(hdb && enc && dec);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd >= 0){
+ if(!INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
assert(hdb);
if(step > 0){
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
return rv;
}
if(!HDBLOCKMETHOD(hdb, false)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbcacheclear(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
if(!HDBLOCKMETHOD(hdb, false)) return false;
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER)){
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
void *tchdbgetnext(TCHDB *hdb, const void *kbuf, int ksiz, int *sp){
assert(hdb && sp);
if(!HDBLOCKMETHOD(hdb, true)) return NULL;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return NULL;
char *tchdbgetnext3(TCHDB *hdb, const char *kbuf, int ksiz, int *sp, const char **vbp, int *vsp){
assert(hdb && sp && vbp && vsp);
if(!HDBLOCKMETHOD(hdb, true)) return NULL;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return NULL;
bool tchdbiterinit2(TCHDB *hdb, const void *kbuf, int ksiz){
assert(hdb && kbuf && ksiz >= 0);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbforeach(TCHDB *hdb, TCITER iter, void *op){
assert(hdb && iter);
if(!HDBLOCKMETHOD(hdb, false)) return false;
- if(hdb->fd < 0){
+ if(INVALIDHANDLE(hdb->fd)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
bool tchdbtranvoid(TCHDB *hdb){
assert(hdb);
if(!HDBLOCKMETHOD(hdb, true)) return false;
- if(hdb->fd < 0 || !(hdb->omode & HDBOWRITER) || hdb->fatal || !hdb->tran){
+ if (!hdb->tran) {
+ tchdbsetecode(hdb, TCETR, __FILE__, __LINE__, __func__);
+ HDBUNLOCKMETHOD(hdb);
+ return false;
+ }
+ if(INVALIDHANDLE(hdb->fd) || !(hdb->omode & HDBOWRITER) || hdb->fatal){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
HDBUNLOCKMETHOD(hdb);
return false;
* private features
*************************************************************************************************/
-
/* Get a natural prime number not less than a floor number.
`num' specified the floor number.
The return value is a prime number not less than the floor number. */
return primes[i-1];
}
+static bool tchdbseekwrite(TCHDB *hdb, off_t off, const void *buf, size_t size){
+ return tchdbseekwrite2(hdb, off, buf, size, 0);
+}
+
/* Seek and write data into a file.
`hdb' specifies the hash database object.
`buf' specifies the buffer to store into.
`size' specifies the size of the buffer.
The return value is true if successful, else, it is false. */
-static bool tchdbseekwrite(TCHDB *hdb, off_t off, const void *buf, size_t size){
+static bool tchdbseekwrite2(TCHDB *hdb, off_t off, const void *buf, size_t size, int opts){
assert(hdb && off >= 0 && buf && size >= 0);
- if(hdb->tran && !tchdbwalwrite(hdb, off, size)) return false;
+ if(hdb->tran && !(opts & HDBWRITENOWALL) && !tchdbwalwrite(hdb, off, size)) return false;
off_t end = off + size;
- if(end <= hdb->xmsiz){
- if(end >= hdb->fsiz && end >= hdb->xfsiz){
- uint64_t xfsiz = end + HDBXFSIZINC;
- if(ftruncate(hdb->fd, xfsiz) == -1){
+ if(end >= hdb->xfsiz){
+ if(!tchdbftruncate2(hdb, end + HDBXFSIZINC, opts)){
tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
return false;
}
- hdb->xfsiz = xfsiz;
+ }
+ if(end <= hdb->xmsiz){
+ if (opts & HDBWRITENOLOCK) {
+ memcpy((void *) (hdb->map + off), buf, size);
+ } else {
+ if (!HDBLOCKSMEM(hdb, true)) return false;
+ memcpy((void *) (hdb->map + off), buf, size);
+ HDBUNLOCKSMEM(hdb);
}
- memcpy(hdb->map + off, buf, size);
return true;
}
if(!TCUBCACHE && off < hdb->xmsiz){
- if(end >= hdb->fsiz && end >= hdb->xfsiz){
- uint64_t xfsiz = end + HDBXFSIZINC;
- if(ftruncate(hdb->fd, xfsiz) == -1){
- tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
- return false;
- }
- hdb->xfsiz = xfsiz;
- }
int head = hdb->xmsiz - off;
- memcpy(hdb->map + off, buf, head);
+ if (opts & HDBWRITENOLOCK) {
+ memcpy((void *) (hdb->map + off), buf, head);
+ } else {
+ if (!HDBLOCKSMEM(hdb, true)) return false;
+ memcpy((void *) (hdb->map + off), buf, head);
+ HDBUNLOCKSMEM(hdb);
+ }
off += head;
buf = (char *)buf + head;
size -= head;
off += wb;
} else if(wb == -1){
if(errno != EINTR){
- tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__);
+ tchdbsetecode(hdb, tcfilerrno2tcerr(TCEWRITE), __FILE__, __LINE__, __func__);
return false;
}
} else {
if(size > 0){
- tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__);
+ tchdbsetecode(hdb, tcfilerrno2tcerr(TCEWRITE), __FILE__, __LINE__, __func__);
return false;
}
}
static bool tchdbseekread(TCHDB *hdb, off_t off, void *buf, size_t size){
assert(hdb && off >= 0 && buf && size >= 0);
if(off + size <= hdb->xmsiz){
- memcpy(buf, hdb->map + off, size);
+ if (!HDBLOCKSMEM(hdb, false)) return false;
+ memcpy(buf, (void *) (hdb->map + off), size);
+ HDBUNLOCKSMEM(hdb);
return true;
}
if(!TCUBCACHE && off < hdb->xmsiz){
int head = hdb->xmsiz - off;
- memcpy(buf, hdb->map + off, head);
+ if (!HDBLOCKSMEM(hdb, false)) return false;
+ memcpy(buf, (void *) (hdb->map + off), head);
+ HDBUNLOCKSMEM(hdb);
off += head;
buf = (char *)buf + head;
size -= head;
off_t end = off + size;
if(end > hdb->fsiz) return false;
if(end <= hdb->xmsiz){
- memcpy(buf, hdb->map + off, size);
+ if (!HDBLOCKSMEM(hdb, false)) return false;
+ memcpy(buf, (void *) (hdb->map + off), size);
+ HDBUNLOCKSMEM(hdb);
return true;
}
if(!TCUBCACHE && off < hdb->xmsiz){
int head = hdb->xmsiz - off;
- memcpy(buf, hdb->map + off, head);
+ if (!HDBLOCKSMEM(hdb, false)) return false;
+ memcpy(buf, (void *)(hdb->map + off), head);
+ HDBUNLOCKSMEM(hdb);
off += head;
buf = (char *)buf + head;
size -= head;
static void tchdbclear(TCHDB *hdb){
assert(hdb);
hdb->mmtx = NULL;
+ hdb->smtx = NULL;
hdb->rmtxs = NULL;
hdb->dmtx = NULL;
hdb->wmtx = NULL;
hdb->fpow = HDBDEFFPOW;
hdb->opts = 0;
hdb->path = NULL;
- hdb->fd = -1;
+ hdb->fd = INVALID_HANDLE_VALUE;
hdb->omode = 0;
hdb->rnum = 0;
hdb->fsiz = 0;
hdb->msiz = 0;
hdb->xmsiz = HDBDEFXMSIZ;
hdb->xfsiz = 0;
- hdb->ba32 = NULL;
- hdb->ba64 = NULL;
+ hdb->ba64 = false;
hdb->align = 0;
hdb->runit = 0;
hdb->zmode = false;
hdb->dfunit = 0;
hdb->dfcnt = 0;
hdb->tran = false;
- hdb->walfd = -1;
+ hdb->walfd = INVALID_HANDLE_VALUE;
hdb->walend = 0;
- hdb->dbgfd = -1;
+ hdb->dbgfd = INVALID_HANDLE_VALUE;
hdb->cnt_writerec = -1;
hdb->cnt_reuserec = -1;
hdb->cnt_moverec = -1;
hdb->cnt_defrag = -1;
hdb->cnt_shiftrec = -1;
hdb->cnt_trunc = -1;
+#ifdef _WIN32
+ hdb->w32hmap = INVALID_HANDLE_VALUE;
+#endif
TCDODEBUG(hdb->cnt_writerec = 0);
TCDODEBUG(hdb->cnt_reuserec = 0);
TCDODEBUG(hdb->cnt_moverec = 0);
`sign' specifies the sign. */
static void tchdbsetflag(TCHDB *hdb, int flag, bool sign){
assert(hdb);
+ if (!HDBLOCKSMEM(hdb, true)) return;
char *fp = (char *)hdb->map + HDBFLAGSOFF;
if(sign){
*fp |= (uint8_t)flag;
*fp &= ~(uint8_t)flag;
}
hdb->flags = *fp;
+ HDBUNLOCKSMEM(hdb);
}
The return value is the offset of the record. */
static off_t tchdbgetbucket(TCHDB *hdb, uint64_t bidx){
assert(hdb && bidx >= 0);
+ if (!HDBLOCKSMEM(hdb, false)) return -1;
+ off_t ret;
if(hdb->ba64){
- uint64_t llnum = hdb->ba64[bidx];
- return TCITOHLL(llnum) << hdb->apow;
+ uint64_t llnum = HDBB64(hdb)[bidx];
+ ret = TCITOHLL(llnum) << hdb->apow;
+ } else {
+ uint32_t lnum = HDBB32(hdb)[bidx];
+ ret = (off_t)TCITOHL(lnum) << hdb->apow;
}
- uint32_t lnum = hdb->ba32[bidx];
- return (off_t)TCITOHL(lnum) << hdb->apow;
+ HDBUNLOCKSMEM(hdb);
+ return ret;
}
if(hdb->ba64){
uint64_t llnum = off >> hdb->apow;
if(hdb->tran) tchdbwalwrite(hdb, HDBHEADSIZ + bidx * sizeof(llnum), sizeof(llnum));
- hdb->ba64[bidx] = TCHTOILL(llnum);
+ bool l = HDBLOCKSMEM(hdb, true);
+ uint64_t *ba = HDBB64(hdb);
+ ba[bidx] = TCHTOILL(llnum);
+ if (l) HDBUNLOCKSMEM(hdb);
} else {
uint32_t lnum = off >> hdb->apow;
if(hdb->tran) tchdbwalwrite(hdb, HDBHEADSIZ + bidx * sizeof(lnum), sizeof(lnum));
- hdb->ba32[bidx] = TCHTOIL(lnum);
+ bool l = HDBLOCKSMEM(hdb, true);
+ uint32_t *ba = HDBB32(hdb);
+ ba[bidx] = TCHTOIL(lnum);
+ if (l) HDBUNLOCKSMEM(hdb);
}
}
uint32_t lnum = TCHTOIL(rsiz);
memcpy(wp, &lnum, sizeof(lnum));
wp += sizeof(lnum);
- if(!tchdbseekwrite(hdb, off, rbuf, wp - rbuf)) return false;
- return true;
+ return tchdbseekwrite(hdb, off, rbuf, wp - rbuf);
}
hdb->fsiz += finc;
uint64_t llnum = hdb->fsiz;
llnum = TCHTOILL(llnum);
- memcpy(hdb->map + HDBFSIZOFF, &llnum, sizeof(llnum));
+ if (!HDBLOCKSMEM(hdb, true)) return false;
+ memcpy((void *)(hdb->map + HDBFSIZOFF), &llnum, sizeof(llnum));
+ HDBUNLOCKSMEM(hdb);
}
if(rbuf != stack) TCFREE(rbuf);
if(entoff > 0){
The return value is true if successful, else, it is false. */
static bool tchdbremoverec(TCHDB *hdb, TCHREC *rec, char *rbuf, uint64_t bidx, off_t entoff){
assert(hdb && rec);
+ bool err = false;
if(!tchdbwritefb(hdb, rec->off, rec->rsiz)) return false;
if(!HDBLOCKDB(hdb)) return false;
tchdbfbpinsert(hdb, rec->off, rec->rsiz);
uint32_t lnum = right >> hdb->apow;
lnum = TCHTOIL(lnum);
if(!tchdbseekwrite(hdb, toff, &lnum, sizeof(uint32_t))) return false;
+ }
}
- }
if(entoff > 0){
- if(hdb->ba64){
+ if(hdb->ba64){
uint64_t llnum = child >> hdb->apow;
llnum = TCHTOILL(llnum);
if(!tchdbseekwrite(hdb, entoff, &llnum, sizeof(uint64_t))) return false;
uint32_t lnum = child >> hdb->apow;
lnum = TCHTOIL(lnum);
if(!tchdbseekwrite(hdb, entoff, &lnum, sizeof(uint32_t))) return false;
- }
+ }
} else {
tchdbsetbucket(hdb, bidx, child);
}
hdb->rnum--;
uint64_t llnum = hdb->rnum;
llnum = TCHTOILL(llnum);
- memcpy(hdb->map + HDBRNUMOFF, &llnum, sizeof(llnum));
+ if (HDBLOCKSMEM(hdb, true)) {
+ memcpy((void *)(hdb->map + HDBRNUMOFF), &llnum, sizeof(llnum));
+ HDBUNLOCKSMEM(hdb);
+ } else {
+ err = true;
+ }
HDBUNLOCKDB(hdb);
- return true;
+ return !err;
}
static bool tchdbshiftrec(TCHDB *hdb, TCHREC *rec, char *rbuf, off_t destoff){
assert(hdb && rec && rbuf && destoff >= 0);
TCDODEBUG(hdb->cnt_shiftrec++);
- if(!rec->vbuf && !tchdbreadrecbody(hdb, rec)) return false;
+ if(!rec->vbuf && !tchdbreadrecbody(hdb, rec)) {
+ return false;
+ }
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, rec->kbuf, rec->ksiz, &hash);
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return false;
if(rec->off == off){
bool err = false;
rec->off = destoff;
The return value is true if successful, else, it is false. */
static bool tchdbflushdrp(TCHDB *hdb){
assert(hdb);
+ bool err = false;
if(!HDBLOCKDB(hdb)) return false;
if(!hdb->drpool){
HDBUNLOCKDB(hdb);
hdb->drpool = NULL;
hdb->drpdef = NULL;
hdb->drpoff = 0;
- uint64_t llnum;
- llnum = hdb->rnum;
- llnum = TCHTOILL(llnum);
- memcpy(hdb->map + HDBRNUMOFF, &llnum, sizeof(llnum));
- llnum = hdb->fsiz;
- llnum = TCHTOILL(llnum);
- memcpy(hdb->map + HDBFSIZOFF, &llnum, sizeof(llnum));
+ if (HDBLOCKSMEM(hdb, true)) {
+ uint64_t llnum;
+ llnum = hdb->rnum;
+ llnum = TCHTOILL(llnum);
+ memcpy((void *)(hdb->map + HDBRNUMOFF), &llnum, sizeof(llnum));
+ llnum = hdb->fsiz;
+ llnum = TCHTOILL(llnum);
+ memcpy((void *)(hdb->map + HDBFSIZOFF), &llnum, sizeof(llnum));
+ HDBUNLOCKSMEM(hdb);
+ } else {
+ err = true;
+ }
HDBUNLOCKDB(hdb);
- return true;
+ return !err;
}
If successful, the return value is true, else, it is false. */
static bool tchdbwalinit(TCHDB *hdb){
assert(hdb);
- if(lseek(hdb->walfd, 0, SEEK_SET) == -1){
+ if(!tcfseek(hdb->walfd, 0, TCFSTART)){
tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
return false;
}
- if(ftruncate(hdb->walfd, 0) == -1){
+ if(!tcftruncate(hdb->walfd, 0)){
tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
return false;
}
return false;
}
wp += size;
- if(!HDBLOCKWAL(hdb)) return false;
+ if(!HDBLOCKWAL(hdb)) {
+ if(buf != stack) TCFREE(buf);
+ return false;
+ }
if(!tcwrite(hdb->walfd, buf, wp - buf)){
tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__);
if(buf != stack) TCFREE(buf);
return false;
}
if(buf != stack) TCFREE(buf);
- if((hdb->omode & HDBOTSYNC) && fsync(hdb->walfd) == -1){
+ if((hdb->omode & HDBOTSYNC) && fsync(hdb->walfd)){
tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__);
HDBUNLOCKWAL(hdb);
return false;
`hdb' specifies the hash database object.
`path' specifies the path of the database file.
If successful, the return value is true, else, it is false. */
-static int tchdbwalrestore(TCHDB *hdb, const char *path){
- assert(hdb && path);
- char *tpath = tcsprintf("%s%c%s", path, MYEXTCHR, HDBWALSUFFIX);
- int walfd = open(tpath, O_RDONLY, HDBFILEMODE);
- TCFREE(tpath);
- if(walfd < 0) return false;
- bool err = false;
- uint64_t walsiz = 0;
- struct stat sbuf;
- if(fstat(walfd, &sbuf) == 0){
- walsiz = sbuf.st_size;
- } else {
- tchdbsetecode(hdb, TCESTAT, __FILE__, __LINE__, __func__);
- err = true;
- }
- if(walsiz >= sizeof(walsiz) + HDBHEADSIZ){
- int dbfd = hdb->fd;
- int tfd = -1;
- if(!(hdb->omode & HDBOWRITER)){
- tfd = open(path, O_WRONLY, HDBFILEMODE);
- if(tfd >= 0){
- dbfd = tfd;
- } else {
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tchdbsetecode(hdb, ecode, __FILE__, __LINE__, __func__);
+static bool tchdbwalrestore(TCHDB *hdb, const char *path) {
+ bool err = false;
+ uint64_t walsiz = 0;
+ HANDLE walfd;
+ if (!HDBLOCKWAL(hdb)) {
+ return false;
+ }
+ char *tpath = tcsprintf("%s%c%s", path, MYEXTCHR, HDBWALSUFFIX);
+#ifndef _WIN32
+ walfd = open(tpath, O_RDONLY, HDBFILEMODE);
+#else
+ walfd = CreateFile(tpath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ TCFREE(tpath);
+ if (INVALIDHANDLE(walfd)) {
+ tchdbsetecode(hdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
+ HDBUNLOCKWAL(hdb);
err = true;
- }
+ goto finish;
+ }
+ struct stat sbuf;
+ if (!fstat(walfd, &sbuf)) {
+ walsiz = sbuf.st_size;
+ }
+ if (!(hdb->omode & HDBOWRITER) || walsiz < sizeof (walsiz) + HDBHEADSIZ) {
+ HDBUNLOCKWAL(hdb);
+ err = true;
+ goto finish;
}
uint64_t fsiz = 0;
- if(tcread(walfd, &fsiz, sizeof(fsiz))){
- fsiz = TCITOHLL(fsiz);
+ if (tcread(walfd, &fsiz, sizeof (fsiz))) {
+ fsiz = TCITOHLL(fsiz);
} else {
- tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
- err = true;
+ HDBUNLOCKWAL(hdb);
+ tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
+ err = true;
+ goto finish;
}
TCLIST *list = tclistnew();
- uint64_t waloff = sizeof(fsiz);
+ uint64_t waloff = sizeof (fsiz);
char stack[HDBIOBUFSIZ];
- while(waloff < walsiz){
- uint64_t off;
- uint32_t size;
- if(!tcread(walfd, stack, sizeof(off) + sizeof(size))){
- tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
- err = true;
- break;
- }
- memcpy(&off, stack, sizeof(off));
- off = TCITOHLL(off);
- memcpy(&size, stack + sizeof(off), sizeof(size));
- size = TCITOHL(size);
- char *buf;
- if(sizeof(off) + size <= HDBIOBUFSIZ){
- buf = stack;
- } else {
- TCMALLOC(buf, sizeof(off) + size);
- }
- *(uint64_t *)buf = off;
- if(!tcread(walfd, buf + sizeof(off), size)){
- tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
- err = true;
- if(buf != stack) TCFREE(buf);
- break;
- }
- TCLISTPUSH(list, buf, sizeof(off) + size);
- if(buf != stack) TCFREE(buf);
- waloff += sizeof(off) + sizeof(size) + size;
- }
- size_t xmsiz = 0;
- if(hdb->fd >= 0 && hdb->map) xmsiz = (hdb->xmsiz > hdb->msiz) ? hdb->xmsiz : hdb->msiz;
- for(int i = TCLISTNUM(list) - 1; i >= 0; i--){
- const char *rec;
- int size;
- TCLISTVAL(rec, list, i, size);
- uint64_t off = *(uint64_t *)rec;
- rec += sizeof(off);
- size -= sizeof(off);
- if(lseek(dbfd, off, SEEK_SET) == -1){
- tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
- err = true;
- break;
- }
- if(!tcwrite(dbfd, rec, size)){
- tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__);
+ while (waloff < walsiz) {
+ uint64_t off;
+ uint32_t size;
+ if (!tcread(walfd, stack, sizeof (off) + sizeof (size))) {
+ tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
+ err = true;
+ break;
+ }
+ memcpy(&off, stack, sizeof (off));
+ off = TCITOHLL(off);
+ memcpy(&size, stack + sizeof (off), sizeof (size));
+ size = TCITOHL(size);
+ char *buf;
+ if (sizeof (off) + size <= HDBIOBUFSIZ) {
+ buf = stack;
+ } else {
+ TCMALLOC(buf, sizeof (off) + size);
+ }
+ *(uint64_t *) buf = off;
+ if (!tcread(walfd, buf + sizeof (off), size)) {
+ tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
+ err = true;
+ if (buf != stack) TCFREE(buf);
+ break;
+ }
+ TCLISTPUSH(list, buf, sizeof (off) + size);
+ if (buf != stack) TCFREE(buf);
+ waloff += sizeof (off) + sizeof (size) + size;
+ }
+ HDBUNLOCKWAL(hdb);
+
+ if (HDBLOCKSMEM(hdb, true)) {
+ for (int i = TCLISTNUM(list) - 1; i >= 0; i--) {
+ const char *rec;
+ int size;
+ TCLISTVAL(rec, list, i, size);
+ uint64_t off = *(uint64_t *) rec;
+ rec += sizeof (off);
+ size -= sizeof (off);
+ if (!tchdbseekwrite2(hdb, off, rec, size, HDBWRITENOWALL | HDBWRITENOLOCK)) {
+ err = true;
+ break;
+ }
+ }
+ HDBUNLOCKSMEM(hdb);
+ } else {
err = true;
- break;
- }
- if(!TCUBCACHE && off < xmsiz){
- size = (size <= xmsiz - off) ? size : xmsiz - off;
- memcpy(hdb->map + off, rec, size);
- }
}
tclistdel(list);
- if(ftruncate(dbfd, fsiz) == -1){
- tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
- err = true;
+
+ char hbuf[HDBHEADSIZ];
+ if (!err && tchdbseekread(hdb, 0, hbuf, HDBHEADSIZ)) {
+ tchdbloadmeta(hdb, hbuf);
+ } else {
+ err = true;
}
- if((hdb->omode & HDBOTSYNC) && fsync(dbfd) == -1){
- tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__);
- err = true;
+ if (!tchdbmemsync(hdb, (hdb->omode & HDBOTSYNC))) {
+ tchdbsetecode(hdb, TCESYNC, __FILE__, __LINE__, __func__);
+ err = true;
}
- if(tfd >= 0 && close(tfd) == -1){
- tchdbsetecode(hdb, TCECLOSE, __FILE__, __LINE__, __func__);
- err = true;
+finish:
+ if (!INVALIDHANDLE(walfd) && !CLOSEFH(walfd)) {
+ err = true;
}
- } else {
- err = true;
- }
- if(close(walfd) == -1){
- tchdbsetecode(hdb, TCECLOSE, __FILE__, __LINE__, __func__);
- err = true;
- }
- return !err;
+ return !err;
}
assert(hdb && path);
char *tpath = tcsprintf("%s%c%s", path, MYEXTCHR, HDBWALSUFFIX);
bool err = false;
- if(unlink(tpath) == -1 && errno != ENOENT){
+ if(unlink(tpath) && errno != ENOENT){
tchdbsetecode(hdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
If successful, the return value is true, else, it is false. */
static bool tchdbopenimpl(TCHDB *hdb, const char *path, int omode){
assert(hdb && path);
+ HANDLE fd;
+#ifndef _WIN32
int mode = O_RDONLY;
if(omode & HDBOWRITER){
mode = O_RDWR;
if(omode & HDBOCREAT) mode |= O_CREAT;
}
- int fd = open(path, mode, HDBFILEMODE);
- if(fd < 0){
- int ecode = TCEOPEN;
- switch(errno){
- case EACCES: ecode = TCENOPERM; break;
- case ENOENT: ecode = TCENOFILE; break;
- case ENOTDIR: ecode = TCENOFILE; break;
- }
- tchdbsetecode(hdb, ecode, __FILE__, __LINE__, __func__);
+ fd = open(path, mode, HDBFILEMODE);
+#else
+ DWORD mode, cmode;
+ mode = GENERIC_READ;
+ cmode = OPEN_EXISTING;
+ if (omode & HDBOWRITER) {
+ mode |= GENERIC_WRITE;
+ }
+ if (omode & (HDBOTRUNC | HDBOCREAT)) {
+ cmode = CREATE_ALWAYS;
+ } else if (omode & HDBOTRUNC) {
+ cmode = TRUNCATE_EXISTING;
+ } else if (omode & HDBOCREAT) {
+ cmode = CREATE_NEW;
+ }
+ fd = CreateFile(path, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, cmode, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ if(INVALIDHANDLE(fd)){
+ tchdbsetecode(hdb, tcfilerrno2tcerr(TCEOPEN), __FILE__, __LINE__, __func__);
return false;
}
if(!(omode & HDBONOLCK)){
if(!tclock(fd, omode & HDBOWRITER, omode & HDBOLCKNB)){
tchdbsetecode(hdb, TCELOCK, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
+ hdb->omode = omode;
+ hdb->fd = fd;
if((omode & HDBOWRITER) && (omode & HDBOTRUNC)){
- if(ftruncate(fd, 0) == -1){
+ if(!tchdbftruncate(hdb, 0)){
tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(!tchdbwalremove(hdb, path)){
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
struct stat sbuf;
- if(fstat(fd, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)){
+ if(fstat(fd, &sbuf) || !S_ISREG(sbuf.st_mode)){
tchdbsetecode(hdb, TCESTAT, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
char hbuf[HDBHEADSIZ];
- if((omode & HDBOWRITER) && sbuf.st_size < 1){
+ if((omode & HDBOWRITER) && (sbuf.st_size < 1 || (omode & HDBOTRUNC))){
hdb->flags = 0;
hdb->rnum = 0;
uint32_t fbpmax = 1 << hdb->fpow;
}
if(err){
tchdbsetecode(hdb, TCEWRITE, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
sbuf.st_size = hdb->fsiz;
}
- if(lseek(fd, 0, SEEK_SET) == -1){
+ if(!tcfseek(fd, 0, TCFSTART)){
tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(!tcread(fd, hbuf, HDBHEADSIZ)){
tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
int type = hdb->type;
tchdbloadmeta(hdb, hbuf);
if((hdb->flags & HDBFOPEN) && tchdbwalrestore(hdb, path)){
- if(lseek(fd, 0, SEEK_SET) == -1){
+ if(!tcfseek(fd, 0, TCFSTART)){
tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
if(!tcread(fd, hbuf, HDBHEADSIZ)){
tchdbsetecode(hdb, TCEREAD, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
tchdbloadmeta(hdb, hbuf);
if(!tchdbwalremove(hdb, path)){
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
if(memcmp(hbuf, HDBMAGICDATA, strlen(HDBMAGICDATA)) || hdb->type != type ||
hdb->frec < msiz + HDBFBPBSIZ || hdb->frec > hdb->fsiz || sbuf.st_size < hdb->fsiz){
tchdbsetecode(hdb, TCEMETA, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
}
if(((hdb->opts & HDBTDEFLATE) && !_tc_deflate) ||
- ((hdb->opts & HDBTBZIP) && !_tc_bzcompress) || ((hdb->opts & HDBTEXCODEC) && !hdb->enc)){
+ ((hdb->opts & HDBTBZIP) && !_tc_bzcompress) ||
+ ((hdb->opts & HDBTEXCODEC) && !hdb->enc)){
tchdbsetecode(hdb, TCEINVALID, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
+#ifndef _WIN32
size_t xmsiz = (hdb->xmsiz > msiz) ? hdb->xmsiz : msiz;
if(!(omode & HDBOWRITER) && xmsiz > hdb->fsiz) xmsiz = hdb->fsiz;
void *map = mmap(0, xmsiz, PROT_READ | ((omode & HDBOWRITER) ? PROT_WRITE : 0),
MAP_SHARED, fd, 0);
if(map == MAP_FAILED){
tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
- close(fd);
+ CLOSEFH(fd);
return false;
}
+ hdb->map = map;
+ hdb->xfsiz = sbuf.st_size;
+#else
+ if(!tchdbftruncate(hdb, sbuf.st_size)){
+ tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
+ CLOSEFH(fd);
+ return false;
+ }
+#endif
hdb->fbpmax = 1 << hdb->fpow;
if(omode & HDBOWRITER){
TCMALLOC(hdb->fbpool, hdb->fbpmax * HDBFBPALWRAT * sizeof(HDBFB));
hdb->drpoff = 0;
hdb->recc = (hdb->rcnum > 0) ? tcmdbnew2(hdb->rcnum * 2 + 1) : NULL;
hdb->path = tcstrdup(path);
- hdb->fd = fd;
- hdb->omode = omode;
hdb->dfcur = hdb->frec;
hdb->iter = 0;
- hdb->map = map;
+ hdb->ba64 = (hdb->opts & HDBTLARGE);
hdb->msiz = msiz;
- hdb->xfsiz = 0;
- if(hdb->opts & HDBTLARGE){
- hdb->ba32 = NULL;
- hdb->ba64 = (uint64_t *)((char *)map + HDBHEADSIZ);
- } else {
- hdb->ba32 = (uint32_t *)((char *)map + HDBHEADSIZ);
- hdb->ba64 = NULL;
- }
hdb->align = 1 << hdb->apow;
hdb->runit = tclmin(tclmax(hdb->align, HDBMINRUNIT), HDBIOBUFSIZ);
hdb->zmode = (hdb->opts & HDBTDEFLATE) || (hdb->opts & HDBTBZIP) ||
hdb->mtime = sbuf.st_mtime;
hdb->dfcnt = 0;
hdb->tran = false;
- hdb->walfd = -1;
+ hdb->walfd = INVALID_HANDLE_VALUE;
hdb->walend = 0;
if(hdb->omode & HDBOWRITER){
bool err = false;
if(err){
TCFREE(hdb->path);
TCFREE(hdb->fbpool);
+ bool l = HDBLOCKSMEM(hdb, true);
+#ifdef _WIN32
+ FlushViewOfFile((PCVOID) hdb->map, 0);
+ UnmapViewOfFile((LPCVOID) hdb->map);
+ CLOSEFH(hdb->w32hmap);
+#else
munmap(hdb->map, xmsiz);
- close(fd);
- hdb->fd = -1;
+#endif
+ if (l) HDBUNLOCKSMEM(hdb);
+ CLOSEFH(fd);
+ hdb->fd = INVALID_HANDLE_VALUE;
return false;
}
tchdbsetflag(hdb, HDBFOPEN, true);
tchdbsetflag(hdb, HDBFOPEN, false);
}
if((hdb->omode & HDBOWRITER) && !tchdbmemsync(hdb, false)) err = true;
+ if((hdb->omode & HDBOWRITER) && !tchdbftruncate(hdb, hdb->fsiz)){
+ tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
+ err = true;
+ }
+ if(hdb->tran){ //todo!!
+ if(!tchdbwalrestore(hdb, hdb->path)) {
+ err = true;
+ }
+ hdb->tran = false;
+ }
+
+ if (!HDBLOCKSMEM(hdb, true)) err = true;
+#ifndef _WIN32
size_t xmsiz = (hdb->xmsiz > hdb->msiz) ? hdb->xmsiz : hdb->msiz;
if(!(hdb->omode & HDBOWRITER) && xmsiz > hdb->fsiz) xmsiz = hdb->fsiz;
if(munmap(hdb->map, xmsiz) == -1){
+#else
+ FlushViewOfFile((PCVOID) hdb->map, 0);
+ if (UnmapViewOfFile((LPVOID) hdb->map) && CloseHandle(hdb->w32hmap)) {
+ hdb->w32hmap = INVALID_HANDLE_VALUE;
+ }else{
+#endif
tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
err = true;
}
hdb->map = NULL;
- if((hdb->omode & HDBOWRITER) && ftruncate(hdb->fd, hdb->fsiz) == -1){
- tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
- err = true;
- }
- if(hdb->tran){
- if(!tchdbwalrestore(hdb, hdb->path)) err = true;
- hdb->tran = false;
- }
- if(hdb->walfd >= 0){
- if(close(hdb->walfd) == -1){
+ HDBUNLOCKSMEM(hdb);
+
+ if(!INVALIDHANDLE(hdb->walfd)){
+ if(!CLOSEFH(hdb->walfd)){
tchdbsetecode(hdb, TCECLOSE, __FILE__, __LINE__, __func__);
err = true;
}
- if(!hdb->fatal && !tchdbwalremove(hdb, hdb->path)) err = true;
+ if(!hdb->fatal && !tchdbwalremove(hdb, hdb->path)) {
+ err = true;
+ }
}
- if(close(hdb->fd) == -1){
+ if(!CLOSEFH(hdb->fd)){
tchdbsetecode(hdb, TCECLOSE, __FILE__, __LINE__, __func__);
err = true;
}
TCFREE(hdb->path);
hdb->path = NULL;
- hdb->fd = -1;
+ hdb->fd = INVALID_HANDLE_VALUE;
+ hdb->walfd = INVALID_HANDLE_VALUE;
return !err;
}
assert(hdb && kbuf && ksiz >= 0);
if(hdb->recc) tcmdbout(hdb->recc, kbuf, ksiz);
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return false;
off_t entoff = 0;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
+ bool err = false;
while(off > 0){
rec.off = off;
if(!tchdbreadrec(hdb, &rec, rbuf)) return false;
hdb->rnum++;
uint64_t llnum = hdb->rnum;
llnum = TCHTOILL(llnum);
- memcpy(hdb->map + HDBRNUMOFF, &llnum, sizeof(llnum));
+ if (HDBLOCKSMEM(hdb, true)) {
+ memcpy((void *)(hdb->map + HDBRNUMOFF), &llnum, sizeof(llnum));
+ HDBUNLOCKSMEM(hdb);
+ } else {
+ err = true;
+ }
HDBUNLOCKDB(hdb);
- return true;
+ return !err;
}
hdb->drpoff = hdb->fsiz;
}
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return false;
off_t entoff = 0;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
assert(hdb && kbuf && ksiz >= 0);
if(hdb->recc) tcmdbout(hdb->recc, kbuf, ksiz);
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return false;
off_t entoff = 0;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
}
}
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return NULL;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
while(off > 0){
}
}
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return -1;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
while(off > 0){
}
}
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return -1;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
while(off > 0){
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return NULL;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
while(off > 0){
}
}
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return -1;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
while(off > 0){
If successful, the return value is true, else, it is false. */
static bool tchdboptimizeimpl(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts){
assert(hdb);
- char *tpath = tcsprintf("%s%ctmp%c%llu", hdb->path, MYEXTCHR, MYEXTCHR, hdb->inode);
+ bool err = false;
+ char *tpath = tcsprintf("%s%ctmp%c%" PRIuMAX "", hdb->path, MYEXTCHR, MYEXTCHR, hdb->inode);
+ int omode = (hdb->omode & ~HDBOCREAT) & ~HDBOTRUNC;
TCHDB *thdb = tchdbnew();
thdb->dbgfd = hdb->dbgfd;
thdb->enc = hdb->enc;
if(fpow < 0) fpow = hdb->fpow;
if(opts == UINT8_MAX) opts = hdb->opts;
tchdbtune(thdb, bnum, apow, fpow, opts);
- if(!tchdbopen(thdb, tpath, HDBOWRITER | HDBOCREAT | HDBOTRUNC)){
- tchdbsetecode(hdb, thdb->ecode, __FILE__, __LINE__, __func__);
+ if(!tchdbopen(thdb, tpath, HDBOWRITER | HDBOCREAT | HDBOTRUNC) ||
+ !tchdbcopyopaque(thdb, hdb, 0, HDBOPAQUESZ)){
tchdbdel(thdb);
TCFREE(tpath);
return false;
}
- memcpy(tchdbopaque(thdb), tchdbopaque(hdb), HDBHEADSIZ - HDBOPAQUEOFF);
- bool err = false;
+
uint64_t off = hdb->frec;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
TCFREE(tpath);
return false;
}
+ char *opath = tcstrdup(hdb->path);
+ if(!tchdbcloseimpl(hdb)){
+ TCFREE(opath);
+ TCFREE(tpath);
+ return false;
+ }
if(esc){
char *bpath = tcsprintf("%s%cbroken", tpath, MYEXTCHR);
- if(rename(hdb->path, bpath) == -1){
+ if(rename(opath, bpath)){
tchdbsetecode(hdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
TCFREE(bpath);
} else {
- if(unlink(hdb->path) == -1){
+ if(unlink(opath)){
tchdbsetecode(hdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
}
- if(rename(tpath, hdb->path) == -1){
+ if(rename(tpath, opath)){
tchdbsetecode(hdb, TCERENAME, __FILE__, __LINE__, __func__);
err = true;
}
TCFREE(tpath);
- if(err) return false;
- tpath = tcstrdup(hdb->path);
- int omode = (hdb->omode & ~HDBOCREAT) & ~HDBOTRUNC;
- if(!tchdbcloseimpl(hdb)){
- TCFREE(tpath);
+ if(err) {
+ TCFREE(opath);
return false;
}
- bool rv = tchdbopenimpl(hdb, tpath, omode);
- TCFREE(tpath);
+ bool rv = tchdbopenimpl(hdb, opath, omode);
+ TCFREE(opath);
return rv;
}
}
if(*path == '@'){
char tsbuf[TCNUMBUFSIZ];
- sprintf(tsbuf, "%llu", (unsigned long long)(tctime() * 1000000));
+ sprintf(tsbuf, "%" PRIuMAX "", (unsigned long long)(tctime() * 1000000));
const char *args[3];
args[0] = path + 1;
args[1] = hdb->path;
hdb->dfcnt = 0;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
+ bool err = false;
while(true){
if(hdb->dfcur >= hdb->fsiz){
hdb->dfcur = hdb->frec;
rec.rsiz -= diff;
fbsiz += diff;
}
- if(!tchdbshiftrec(hdb, &rec, rbuf, dest)) return false;
+ if(!tchdbshiftrec(hdb, &rec, rbuf, dest)) {
+ fprintf(stderr, "\n %d %d %d %d @000010\n", (int) cur, (int) hdb->fsiz, (int) (hdb->fsiz - cur), (int) rsiz);
+ return false;
+ }
if(hdb->iter == cur) hdb->iter = dest;
dest += rec.rsiz;
step--;
hdb->dfcur = cur - fbsiz;
} else {
TCDODEBUG(hdb->cnt_trunc++);
- if(hdb->tran && !tchdbwalwrite(hdb, dest, fbsiz)) return false;
+ if(hdb->tran && !tchdbwalwrite(hdb, dest, fbsiz)) {
+ return false;
+ }
tchdbfbptrim(hdb, base, cur, 0, 0);
hdb->dfcur = hdb->frec;
hdb->fsiz = dest;
uint64_t llnum = hdb->fsiz;
llnum = TCHTOILL(llnum);
- memcpy(hdb->map + HDBFSIZOFF, &llnum, sizeof(llnum));
+ if (HDBLOCKSMEM(hdb, true)) {
+ memcpy((void *)(hdb->map + HDBFSIZOFF), &llnum, sizeof(llnum));
+ HDBUNLOCKSMEM(hdb);
+ } else {
+ err = true;
+ }
if(hdb->iter >= hdb->fsiz) hdb->iter = UINT64_MAX;
if(!hdb->tran){
- if(ftruncate(hdb->fd, hdb->fsiz) == -1){
+ if(!tchdbftruncate(hdb, hdb->fsiz)){
tchdbsetecode(hdb, TCETRUNC, __FILE__, __LINE__, __func__);
return false;
}
- hdb->xfsiz = 0;
}
}
- return true;
+ return !err;
}
uint8_t hash;
uint64_t bidx = tchdbbidx(hdb, kbuf, ksiz, &hash);
off_t off = tchdbgetbucket(hdb, bidx);
+ if (off == -1) return false;
TCHREC rec;
char rbuf[HDBIOBUFSIZ];
while(off > 0){
`hdb' specifies the hash database object.
`wr' specifies whether the lock is writer or not.
If successful, the return value is true, else, it is false. */
-static bool tchdblockmethod(TCHDB *hdb, bool wr){
+EJDB_INLINE bool tchdblockmethod(TCHDB *hdb, bool wr){
assert(hdb);
if(wr ? pthread_rwlock_wrlock(hdb->mmtx) != 0 : pthread_rwlock_rdlock(hdb->mmtx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
/* Unlock a method of the hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false. */
-static bool tchdbunlockmethod(TCHDB *hdb){
+EJDB_INLINE bool tchdbunlockmethod(TCHDB *hdb){
assert(hdb);
if(pthread_rwlock_unlock(hdb->mmtx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
return true;
}
+/* Lock shared memory */
+EJDB_INLINE bool tchdblocksmem(TCHDB *hdb, bool wr){
+ assert(hdb);
+ if(wr ? pthread_rwlock_wrlock(hdb->smtx) != 0 : pthread_rwlock_rdlock(hdb->smtx) != 0){
+ tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
+ return false;
+ }
+ TCTESTYIELD();
+ return true;
+}
+
+/* Unlock shared memory */
+EJDB_INLINE bool tchdbunlocksmem(TCHDB *hdb){
+ assert(hdb);
+ if(pthread_rwlock_unlock(hdb->smtx) != 0){
+ tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
+ return false;
+ }
+ TCTESTYIELD();
+ return true;
+}
/* Lock a record of the hash database object.
`hdb' specifies the hash database object.
`bidx' specifies the bucket index of the record.
`wr' specifies whether the lock is writer or not.
If successful, the return value is true, else, it is false. */
-static bool tchdblockrecord(TCHDB *hdb, uint8_t bidx, bool wr){
+EJDB_INLINE bool tchdblockrecord(TCHDB *hdb, uint8_t bidx, bool wr){
assert(hdb);
if(wr ? pthread_rwlock_wrlock((pthread_rwlock_t *)hdb->rmtxs + bidx) != 0 :
pthread_rwlock_rdlock((pthread_rwlock_t *)hdb->rmtxs + bidx) != 0){
`hdb' specifies the hash database object.
`bidx' specifies the bucket index of the record.
If successful, the return value is true, else, it is false. */
-static bool tchdbunlockrecord(TCHDB *hdb, uint8_t bidx){
+EJDB_INLINE bool tchdbunlockrecord(TCHDB *hdb, uint8_t bidx){
assert(hdb);
if(pthread_rwlock_unlock((pthread_rwlock_t *)hdb->rmtxs + bidx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
`hdb' specifies the hash database object.
`wr' specifies whether the lock is writer or not.
If successful, the return value is true, else, it is false. */
-static bool tchdblockallrecords(TCHDB *hdb, bool wr){
+EJDB_INLINE bool tchdblockallrecords(TCHDB *hdb, bool wr){
assert(hdb);
for(int i = 0; i <= UINT8_MAX; i++){
if(wr ? pthread_rwlock_wrlock((pthread_rwlock_t *)hdb->rmtxs + i) != 0 :
/* Unlock all records of the hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false. */
-static bool tchdbunlockallrecords(TCHDB *hdb){
+EJDB_INLINE bool tchdbunlockallrecords(TCHDB *hdb){
assert(hdb);
bool err = false;
for(int i = UINT8_MAX; i >= 0; i--){
/* Lock the whole database of the hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false. */
-static bool tchdblockdb(TCHDB *hdb){
+EJDB_INLINE bool tchdblockdb(TCHDB *hdb){
assert(hdb);
if(pthread_mutex_lock(hdb->dmtx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
/* Unlock the whole database of the hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false. */
-static bool tchdbunlockdb(TCHDB *hdb){
+EJDB_INLINE bool tchdbunlockdb(TCHDB *hdb){
assert(hdb);
if(pthread_mutex_unlock(hdb->dmtx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
/* Lock the write ahead logging file of the hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false. */
-static bool tchdblockwal(TCHDB *hdb){
+EJDB_INLINE bool tchdblockwal(TCHDB *hdb){
assert(hdb);
if(pthread_mutex_lock(hdb->wmtx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
/* Unlock the write ahead logging file of the hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false. */
-static bool tchdbunlockwal(TCHDB *hdb){
+EJDB_INLINE bool tchdbunlockwal(TCHDB *hdb){
assert(hdb);
if(pthread_mutex_unlock(hdb->wmtx) != 0){
tchdbsetecode(hdb, TCETHREAD, __FILE__, __LINE__, __func__);
return true;
}
+static bool tchdbftruncate(TCHDB *hdb, off_t length) {
+ return tchdbftruncate2(hdb, length, 0);
+}
+static bool tchdbftruncate2(TCHDB *hdb, off_t length, int opts) {
+#ifndef _WIN32
+ if (!(hdb->omode & HDBOWRITER)) {
+ return true;
+ }
+ bool err = (ftruncate(hdb->fd, length) != -1);
+ hdb->xfsiz = (err ? 0 : length);
+ return !err;
+#else
+ bool err = false;
+ LARGE_INTEGER size;
+ size.QuadPart = (hdb->omode & HDBOWRITER) ? tcpagealign((length == 0) ? 1 : length) : length; //MSDN: Applications should test for files with a length of 0 (zero) and reject those files.
+ if (hdb->map && length > 0 && (size.QuadPart <= hdb->xfsiz || size.QuadPart <= hdb->fsiz || !(hdb->omode & HDBOWRITER))) {
+ return true;
+ }
+ if (!(opts & HDBWRITENOLOCK) && !HDBLOCKSMEM(hdb, true)) {
+ return false;
+ }
+ if (hdb->map) {
+ FlushViewOfFile((PCVOID) hdb->map, 0);
+ if (!UnmapViewOfFile((LPCVOID) hdb->map) || !CloseHandle(hdb->w32hmap)) {
+ tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
+ err = true;
+ goto finish;
+ }
+ hdb->map = NULL;
+ hdb->w32hmap = INVALID_HANDLE_VALUE;
+ }
+ if (hdb->omode & HDBOWRITER) {
+ if (!SetFilePointerEx(hdb->fd, size, NULL, FILE_BEGIN) || !SetEndOfFile(hdb->fd)) {
+ tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
+ err = true;
+ goto finish;
+ }
+ }
+ hdb->w32hmap = CreateFileMapping(hdb->fd, NULL,
+ ((hdb->omode & HDBOWRITER) ? PAGE_READWRITE : PAGE_READONLY),
+ size.HighPart, size.LowPart, NULL);
+ if (INVALIDHANDLE(hdb->w32hmap)) {
+ tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
+ err = true;
+ goto finish;
+ }
+ hdb->map = MapViewOfFile(hdb->w32hmap,
+ ((hdb->omode & HDBOWRITER) ? FILE_MAP_WRITE : FILE_MAP_READ),
+ 0, 0, 0);
+ if (hdb->map == NULL) {
+ tchdbsetecode(hdb, TCEMMAP, __FILE__, __LINE__, __func__);
+ err = true;
+ goto finish;
+ }
+ hdb->xfsiz = size.QuadPart;
+ if (length == 0) {
+ size.QuadPart = 0;
+ if (!SetFilePointerEx(hdb->fd, size, NULL, FILE_BEGIN)) {
+ tchdbsetecode(hdb, TCESEEK, __FILE__, __LINE__, __func__);
+ err = true;
+ goto finish;
+ }
+ }
+finish:
+ if (!(opts & HDBWRITENOLOCK)) HDBUNLOCKSMEM(hdb);
+ return !err;
+#endif
+}
/*************************************************************************************************
* debugging functions
`hdb' specifies the hash database object. */
void tchdbprintmeta(TCHDB *hdb){
assert(hdb);
- if(hdb->dbgfd < 0) return;
- int dbgfd = (hdb->dbgfd == UINT16_MAX) ? 1 : hdb->dbgfd;
+ HANDLE dbgfd = hdb->dbgfd;
+ if(INVALIDHANDLE(dbgfd)) {
+ dbgfd = GET_STDOUT_HANDLE();
+ }
char buf[HDBIOBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "META:");
wp += sprintf(wp, " mmtx=%p", (void *)hdb->mmtx);
wp += sprintf(wp, " rmtxs=%p", (void *)hdb->rmtxs);
wp += sprintf(wp, " dmtx=%p", (void *)hdb->dmtx);
+ wp += sprintf(wp, " smtx=%p", (void *)hdb->smtx);
wp += sprintf(wp, " wmtx=%p", (void *)hdb->wmtx);
wp += sprintf(wp, " eckey=%p", (void *)hdb->eckey);
wp += sprintf(wp, " rpath=%s", hdb->rpath ? hdb->rpath : "-");
wp += sprintf(wp, " type=%02X", hdb->type);
wp += sprintf(wp, " flags=%02X", hdb->flags);
- wp += sprintf(wp, " bnum=%llu", (unsigned long long)hdb->bnum);
+ wp += sprintf(wp, " bnum=%" PRIuMAX "", (unsigned long long)hdb->bnum);
wp += sprintf(wp, " apow=%u", hdb->apow);
wp += sprintf(wp, " fpow=%u", hdb->fpow);
wp += sprintf(wp, " opts=%u", hdb->opts);
wp += sprintf(wp, " path=%s", hdb->path ? hdb->path : "-");
wp += sprintf(wp, " fd=%d", hdb->fd);
wp += sprintf(wp, " omode=%u", hdb->omode);
- wp += sprintf(wp, " rnum=%llu", (unsigned long long)hdb->rnum);
- wp += sprintf(wp, " fsiz=%llu", (unsigned long long)hdb->fsiz);
- wp += sprintf(wp, " frec=%llu", (unsigned long long)hdb->frec);
- wp += sprintf(wp, " dfcur=%llu", (unsigned long long)hdb->dfcur);
- wp += sprintf(wp, " iter=%llu", (unsigned long long)hdb->iter);
+ wp += sprintf(wp, " rnum=%" PRIuMAX "", (unsigned long long)hdb->rnum);
+ wp += sprintf(wp, " fsiz=%" PRIuMAX "", (unsigned long long)hdb->fsiz);
+ wp += sprintf(wp, " frec=%" PRIuMAX "", (unsigned long long)hdb->frec);
+ wp += sprintf(wp, " dfcur=%" PRIuMAX "", (unsigned long long)hdb->dfcur);
+ wp += sprintf(wp, " iter=%" PRIuMAX "", (unsigned long long)hdb->iter);
wp += sprintf(wp, " map=%p", (void *)hdb->map);
- wp += sprintf(wp, " msiz=%llu", (unsigned long long)hdb->msiz);
- wp += sprintf(wp, " ba32=%p", (void *)hdb->ba32);
- wp += sprintf(wp, " ba64=%p", (void *)hdb->ba64);
+ wp += sprintf(wp, " msiz=%" PRIuMAX "", (unsigned long long)hdb->msiz);
+ wp += sprintf(wp, " ba64=%d", hdb->ba64);
wp += sprintf(wp, " align=%u", hdb->align);
wp += sprintf(wp, " runit=%u", hdb->runit);
wp += sprintf(wp, " zmode=%u", hdb->zmode);
wp += sprintf(wp, " fbpmis=%d", hdb->fbpmis);
wp += sprintf(wp, " drpool=%p", (void *)hdb->drpool);
wp += sprintf(wp, " drpdef=%p", (void *)hdb->drpdef);
- wp += sprintf(wp, " drpoff=%llu", (unsigned long long)hdb->drpoff);
+ wp += sprintf(wp, " drpoff=%" PRIuMAX "", (unsigned long long)hdb->drpoff);
wp += sprintf(wp, " recc=%p", (void *)hdb->recc);
wp += sprintf(wp, " rcnum=%u", hdb->rcnum);
wp += sprintf(wp, " ecode=%d", hdb->ecode);
wp += sprintf(wp, " fatal=%u", hdb->fatal);
- wp += sprintf(wp, " inode=%llu", (unsigned long long)(uint64_t)hdb->inode);
- wp += sprintf(wp, " mtime=%llu", (unsigned long long)(uint64_t)hdb->mtime);
+ wp += sprintf(wp, " inode=%" PRIuMAX "", (unsigned long long)(uint64_t)hdb->inode);
+ wp += sprintf(wp, " mtime=%" PRIuMAX "", (unsigned long long)(uint64_t)hdb->mtime);
wp += sprintf(wp, " dfunit=%u", hdb->dfunit);
wp += sprintf(wp, " dfcnt=%u", hdb->dfcnt);
wp += sprintf(wp, " tran=%d", hdb->tran);
wp += sprintf(wp, " walfd=%d", hdb->walfd);
- wp += sprintf(wp, " walend=%llu", (unsigned long long)hdb->walend);
+ wp += sprintf(wp, " walend=%" PRIuMAX "", (unsigned long long)hdb->walend);
wp += sprintf(wp, " dbgfd=%d", hdb->dbgfd);
- wp += sprintf(wp, " cnt_writerec=%lld", (long long)hdb->cnt_writerec);
- wp += sprintf(wp, " cnt_reuserec=%lld", (long long)hdb->cnt_reuserec);
- wp += sprintf(wp, " cnt_moverec=%lld", (long long)hdb->cnt_moverec);
- wp += sprintf(wp, " cnt_readrec=%lld", (long long)hdb->cnt_readrec);
- wp += sprintf(wp, " cnt_searchfbp=%lld", (long long)hdb->cnt_searchfbp);
- wp += sprintf(wp, " cnt_insertfbp=%lld", (long long)hdb->cnt_insertfbp);
- wp += sprintf(wp, " cnt_splicefbp=%lld", (long long)hdb->cnt_splicefbp);
- wp += sprintf(wp, " cnt_dividefbp=%lld", (long long)hdb->cnt_dividefbp);
- wp += sprintf(wp, " cnt_mergefbp=%lld", (long long)hdb->cnt_mergefbp);
- wp += sprintf(wp, " cnt_reducefbp=%lld", (long long)hdb->cnt_reducefbp);
- wp += sprintf(wp, " cnt_appenddrp=%lld", (long long)hdb->cnt_appenddrp);
- wp += sprintf(wp, " cnt_deferdrp=%lld", (long long)hdb->cnt_deferdrp);
- wp += sprintf(wp, " cnt_flushdrp=%lld", (long long)hdb->cnt_flushdrp);
- wp += sprintf(wp, " cnt_adjrecc=%lld", (long long)hdb->cnt_adjrecc);
- wp += sprintf(wp, " cnt_defrag=%lld", (long long)hdb->cnt_defrag);
- wp += sprintf(wp, " cnt_shiftrec=%lld", (long long)hdb->cnt_shiftrec);
- wp += sprintf(wp, " cnt_trunc=%lld", (long long)hdb->cnt_trunc);
+ wp += sprintf(wp, " cnt_writerec=%" PRIdMAX "", (long long)hdb->cnt_writerec);
+ wp += sprintf(wp, " cnt_reuserec=%" PRIdMAX "", (long long)hdb->cnt_reuserec);
+ wp += sprintf(wp, " cnt_moverec=%" PRIdMAX "", (long long)hdb->cnt_moverec);
+ wp += sprintf(wp, " cnt_readrec=%" PRIdMAX "", (long long)hdb->cnt_readrec);
+ wp += sprintf(wp, " cnt_searchfbp=%" PRIdMAX "", (long long)hdb->cnt_searchfbp);
+ wp += sprintf(wp, " cnt_insertfbp=%" PRIdMAX "", (long long)hdb->cnt_insertfbp);
+ wp += sprintf(wp, " cnt_splicefbp=%" PRIdMAX "", (long long)hdb->cnt_splicefbp);
+ wp += sprintf(wp, " cnt_dividefbp=%" PRIdMAX "", (long long)hdb->cnt_dividefbp);
+ wp += sprintf(wp, " cnt_mergefbp=%" PRIdMAX "", (long long)hdb->cnt_mergefbp);
+ wp += sprintf(wp, " cnt_reducefbp=%" PRIdMAX "", (long long)hdb->cnt_reducefbp);
+ wp += sprintf(wp, " cnt_appenddrp=%" PRIdMAX "", (long long)hdb->cnt_appenddrp);
+ wp += sprintf(wp, " cnt_deferdrp=%" PRIdMAX "", (long long)hdb->cnt_deferdrp);
+ wp += sprintf(wp, " cnt_flushdrp=%" PRIdMAX "", (long long)hdb->cnt_flushdrp);
+ wp += sprintf(wp, " cnt_adjrecc=%" PRIdMAX "", (long long)hdb->cnt_adjrecc);
+ wp += sprintf(wp, " cnt_defrag=%" PRIdMAX "", (long long)hdb->cnt_defrag);
+ wp += sprintf(wp, " cnt_shiftrec=%" PRIdMAX "", (long long)hdb->cnt_shiftrec);
+ wp += sprintf(wp, " cnt_trunc=%" PRIdMAX "", (long long)hdb->cnt_trunc);
*(wp++) = '\n';
tcwrite(dbgfd, buf, wp - buf);
}
`rec' specifies the record. */
void tchdbprintrec(TCHDB *hdb, TCHREC *rec){
assert(hdb && rec);
- if(hdb->dbgfd < 0) return;
- int dbgfd = (hdb->dbgfd == UINT16_MAX) ? 1 : hdb->dbgfd;
+ HANDLE dbgfd = hdb->dbgfd;
+ if(INVALIDHANDLE(dbgfd)) {
+ dbgfd = GET_STDOUT_HANDLE();
+ }
char buf[HDBIOBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "REC:");
- wp += sprintf(wp, " off=%llu", (unsigned long long)rec->off);
+ wp += sprintf(wp, " off=%" PRIuMAX "", (unsigned long long)rec->off);
wp += sprintf(wp, " rsiz=%u", rec->rsiz);
wp += sprintf(wp, " magic=%02X", rec->magic);
wp += sprintf(wp, " hash=%02X", rec->hash);
- wp += sprintf(wp, " left=%llu", (unsigned long long)rec->left);
- wp += sprintf(wp, " right=%llu", (unsigned long long)rec->right);
+ wp += sprintf(wp, " left=%" PRIuMAX "", (unsigned long long)rec->left);
+ wp += sprintf(wp, " right=%" PRIuMAX "", (unsigned long long)rec->right);
wp += sprintf(wp, " ksiz=%u", rec->ksiz);
wp += sprintf(wp, " vsiz=%u", rec->vsiz);
wp += sprintf(wp, " psiz=%u", rec->psiz);
wp += sprintf(wp, " kbuf=%p", (void *)rec->kbuf);
wp += sprintf(wp, " vbuf=%p", (void *)rec->vbuf);
- wp += sprintf(wp, " boff=%llu", (unsigned long long)rec->boff);
+ wp += sprintf(wp, " boff=%" PRIuMAX "", (unsigned long long)rec->boff);
wp += sprintf(wp, " bbuf=%p", (void *)rec->bbuf);
*(wp++) = '\n';
tcwrite(dbgfd, buf, wp - buf);
void *mmtx; /* mutex for method */
void *rmtxs; /* mutexes for records */
void *dmtx; /* mutex for the while database */
+ void *smtx; /* rw mutex for shared memory */
void *wmtx; /* mutex for write ahead logging */
void *eckey; /* key for thread specific error code */
char *rpath; /* real path for locking */
uint8_t fpow; /* power of free block pool number */
uint8_t opts; /* options */
char *path; /* path of the database file */
- int fd; /* file descriptor of the database file */
+ HANDLE fd; /* file descriptor of the database file */
uint32_t omode; /* open mode */
uint64_t rnum; /* number of the records */
uint64_t fsiz; /* size of the database file */
uint64_t frec; /* offset of the first record */
uint64_t dfcur; /* offset of the cursor for defragmentation */
uint64_t iter; /* offset of the iterator */
- char *map; /* pointer to the mapped memory */
+ volatile char *map; /* pointer to the mapped memory */
uint64_t msiz; /* size of the mapped memory */
uint64_t xmsiz; /* size of the extra mapped memory */
uint64_t xfsiz; /* extra size of the file for mapped memory */
- uint32_t *ba32; /* 32-bit bucket array */
- uint64_t *ba64; /* 64-bit bucket array */
+ bool ba64; /* using of 64-bit bucket array */
uint32_t align; /* record alignment */
uint32_t runit; /* record reading unit */
bool zmode; /* whether compression is used */
void *encop; /* opaque object for the encoding functions */
TCCODEC dec; /* pointer to the decoding function */
void *decop; /* opaque object for the decoding functions */
- int ecode; /* last happened error code */
+ volatile int ecode; /* last happened error code */
bool fatal; /* whether a fatal error occured */
uint64_t inode; /* inode number */
time_t mtime; /* modification time */
uint32_t dfunit; /* unit step number of auto defragmentation */
uint32_t dfcnt; /* counter of auto defragmentation */
bool tran; /* whether in the transaction */
- int walfd; /* file descriptor of write ahead logging */
+ HANDLE walfd; /* file descriptor of write ahead logging */
uint64_t walend; /* end offset of write ahead logging */
- int dbgfd; /* file descriptor for debugging */
+ HANDLE dbgfd; /* file descriptor for debugging */
volatile int64_t cnt_writerec; /* tesing counter for record write times */
volatile int64_t cnt_reuserec; /* tesing counter for record reuse times */
volatile int64_t cnt_moverec; /* tesing counter for record move times */
volatile int64_t cnt_defrag; /* tesing counter for defragmentation times */
volatile int64_t cnt_shiftrec; /* tesing counter for record shift times */
volatile int64_t cnt_trunc; /* tesing counter for truncation times */
+#ifdef _WIN32
+ volatile HANDLE w32hmap; /* win32 file mappings for mmap */
+#endif
} TCHDB;
enum { /* enumeration for additional flags */
/* Get the message string corresponding to an error code.
`ecode' specifies the error code.
The return value is the message string of the error code. */
-const char *tchdberrmsg(int ecode);
+EJDB_EXPORT const char *tchdberrmsg(int ecode);
/* Create a hash database object.
The return value is the new hash database object. */
-TCHDB *tchdbnew(void);
+EJDB_EXPORT TCHDB *tchdbnew(void);
/* Delete a hash database object.
`hdb' specifies the hash database object.
If the database is not closed, it is closed implicitly. Note that the deleted object and its
derivatives can not be used anymore. */
-void tchdbdel(TCHDB *hdb);
+EJDB_EXPORT void tchdbdel(TCHDB *hdb);
/* Get the last happened error code of a hash database object.
for unlink error, `TCERENAME' for rename error, `TCEMKDIR' for mkdir error, `TCERMDIR' for
rmdir error, `TCEKEEP' for existing record, `TCENOREC' for no record found, and `TCEMISC' for
miscellaneous error. */
-int tchdbecode(TCHDB *hdb);
+EJDB_EXPORT int tchdbecode(TCHDB *hdb);
/* Set mutual exclusion control of a hash database object for threading.
If successful, the return value is true, else, it is false.
Note that the mutual exclusion control is needed if the object is shared by plural threads and
this function should be called before the database is opened. */
-bool tchdbsetmutex(TCHDB *hdb);
+EJDB_EXPORT bool tchdbsetmutex(TCHDB *hdb);
/* Set the tuning parameters of a hash database object.
BZIP2 encoding, `HDBTTCBS' specifies that each record is compressed with TCBS encoding.
If successful, the return value is true, else, it is false.
Note that the tuning parameters should be set before the database is opened. */
-bool tchdbtune(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
+EJDB_EXPORT bool tchdbtune(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
/* Set the caching parameters of a hash database object.
record cache is disabled. It is disabled by default.
If successful, the return value is true, else, it is false.
Note that the caching parameters should be set before the database is opened. */
-bool tchdbsetcache(TCHDB *hdb, int32_t rcnum);
+EJDB_EXPORT bool tchdbsetcache(TCHDB *hdb, int32_t rcnum);
/* Set the size of the extra mapped memory of a hash database object.
mapped memory is disabled. The default size is 67108864.
If successful, the return value is true, else, it is false.
Note that the mapping parameters should be set before the database is opened. */
-bool tchdbsetxmsiz(TCHDB *hdb, int64_t xmsiz);
+EJDB_EXPORT bool tchdbsetxmsiz(TCHDB *hdb, int64_t xmsiz);
/* Set the unit step number of auto defragmentation of a hash database object.
is disabled. It is disabled by default.
If successful, the return value is true, else, it is false.
Note that the defragmentation parameters should be set before the database is opened. */
-bool tchdbsetdfunit(TCHDB *hdb, int32_t dfunit);
+EJDB_EXPORT bool tchdbsetdfunit(TCHDB *hdb, int32_t dfunit);
/* Open a database file and connect a hash database object.
bitwise-or: `HDBONOLCK', which means it opens the database file without file locking, or
`HDBOLCKNB', which means locking is performed without blocking.
If successful, the return value is true, else, it is false. */
-bool tchdbopen(TCHDB *hdb, const char *path, int omode);
+EJDB_EXPORT bool tchdbopen(TCHDB *hdb, const char *path, int omode);
/* Close a hash database object.
If successful, the return value is true, else, it is false.
Update of a database is assured to be written when the database is closed. If a writer opens
a database but does not close it appropriately, the database will be broken. */
-bool tchdbclose(TCHDB *hdb);
+EJDB_EXPORT bool tchdbclose(TCHDB *hdb);
/* Store a record into a hash database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tchdbput(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tchdbput(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into a hash database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tchdbput2(TCHDB *hdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tchdbput2(TCHDB *hdb, const char *kstr, const char *vstr);
/* Store a new record into a hash database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tchdbputkeep(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tchdbputkeep(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into a hash database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tchdbputkeep2(TCHDB *hdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tchdbputkeep2(TCHDB *hdb, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the existing record in a hash database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tchdbputcat(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tchdbputcat(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string value at the end of the existing record in a hash database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tchdbputcat2(TCHDB *hdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tchdbputcat2(TCHDB *hdb, const char *kstr, const char *vstr);
/* Store a record into a hash database object in asynchronous fashion.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. Records passed to
this function are accumulated into the inner buffer and wrote into the file at a blast. */
-bool tchdbputasync(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tchdbputasync(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into a hash database object in asynchronous fashion.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. Records passed to
this function are accumulated into the inner buffer and wrote into the file at a blast. */
-bool tchdbputasync2(TCHDB *hdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tchdbputasync2(TCHDB *hdb, const char *kstr, const char *vstr);
/* Remove a record of a hash database object.
`kbuf' specifies the pointer to the region of the key.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true, else, it is false. */
-bool tchdbout(TCHDB *hdb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tchdbout(TCHDB *hdb, const void *kbuf, int ksiz);
/* Remove a string record of a hash database object.
`hdb' specifies the hash database object connected as a writer.
`kstr' specifies the string of the key.
If successful, the return value is true, else, it is false. */
-bool tchdbout2(TCHDB *hdb, const char *kstr);
+EJDB_EXPORT bool tchdbout2(TCHDB *hdb, const char *kstr);
/* Retrieve a record in a hash database object.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tchdbget(TCHDB *hdb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tchdbget(TCHDB *hdb, const void *kbuf, int ksiz, int *sp);
/**
* @param xstr specifies extensible string object data will be stored into.
* @return
*/
-int tchdbgetintoxstr(TCHDB *hdb, const void *kbuf, int ksiz, TCXSTR *xstr);
+EJDB_EXPORT int tchdbgetintoxstr(TCHDB *hdb, const void *kbuf, int ksiz, TCXSTR *xstr);
/* Retrieve a string record in a hash database object.
`NULL' is returned if no record corresponds.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tchdbget2(TCHDB *hdb, const char *kstr);
+EJDB_EXPORT char *tchdbget2(TCHDB *hdb, const char *kstr);
/* Retrieve a record in a hash database object and write the value into a buffer.
returned if no record corresponds to the specified key.
Note that an additional zero code is not appended at the end of the region of the writing
buffer. */
-int tchdbget3(TCHDB *hdb, const void *kbuf, int ksiz, void *vbuf, int max);
+EJDB_EXPORT int tchdbget3(TCHDB *hdb, const void *kbuf, int ksiz, void *vbuf, int max);
/* Get the size of the value of a record in a hash database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tchdbvsiz(TCHDB *hdb, const void *kbuf, int ksiz);
+EJDB_EXPORT int tchdbvsiz(TCHDB *hdb, const void *kbuf, int ksiz);
/* Get the size of the value of a string record in a hash database object.
`kstr' specifies the string of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tchdbvsiz2(TCHDB *hdb, const char *kstr);
+EJDB_EXPORT int tchdbvsiz2(TCHDB *hdb, const char *kstr);
/* Initialize the iterator of a hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false.
The iterator is used in order to access the key of every record stored in a database. */
-bool tchdbiterinit(TCHDB *hdb);
-bool tchdbiterinit4(TCHDB *hdb, uint64_t *iter);
+EJDB_EXPORT bool tchdbiterinit(TCHDB *hdb);
+EJDB_EXPORT bool tchdbiterinit4(TCHDB *hdb, uint64_t *iter);
/* Get the next key of the iterator of a hash database object.
However, it is not assured if updating the database is occurred while the iteration. Besides,
the order of this traversal access method is arbitrary, so it is not assured that the order of
storing matches the one of the traversal access. */
-void *tchdbiternext(TCHDB *hdb, int *sp);
+EJDB_EXPORT void *tchdbiternext(TCHDB *hdb, int *sp);
/* Get the next key string of the iterator of a hash database object.
database is occurred while the iteration. Besides, the order of this traversal access method
is arbitrary, so it is not assured that the order of storing matches the one of the traversal
access. */
-char *tchdbiternext2(TCHDB *hdb);
+EJDB_EXPORT char *tchdbiternext2(TCHDB *hdb);
/* Get the next extensible objects of the iterator of a hash database object.
`vxstr' specifies the object into which the next value is wrote down.
If successful, the return value is true, else, it is false. False is returned when no record
is to be get out of the iterator. */
-bool tchdbiternext3(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr);
-bool tchdbiternext4(TCHDB *hdb, uint64_t *iter, TCXSTR *kxstr, TCXSTR *vxstr);
+EJDB_EXPORT bool tchdbiternext3(TCHDB *hdb, TCXSTR *kxstr, TCXSTR *vxstr);
+EJDB_EXPORT bool tchdbiternext4(TCHDB *hdb, uint64_t *iter, TCXSTR *kxstr, TCXSTR *vxstr);
/* Get forward matching keys in a hash database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tchdbfwmkeys(TCHDB *hdb, const void *pbuf, int psiz, int max);
+EJDB_EXPORT TCLIST *tchdbfwmkeys(TCHDB *hdb, const void *pbuf, int psiz, int max);
/* Get forward matching string keys in a hash database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tchdbfwmkeys2(TCHDB *hdb, const char *pstr, int max);
+EJDB_EXPORT TCLIST *tchdbfwmkeys2(TCHDB *hdb, const char *pstr, int max);
/* Add an integer to a record in a hash database object.
If successful, the return value is the summation value, else, it is `INT_MIN'.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tchdbaddint(TCHDB *hdb, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tchdbaddint(TCHDB *hdb, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in a hash database object.
If successful, the return value is the summation value, else, it is Not-a-Number.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tchdbadddouble(TCHDB *hdb, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tchdbadddouble(TCHDB *hdb, const void *kbuf, int ksiz, double num);
/* Synchronize updated contents of a hash database object with the file and the device.
`hdb' specifies the hash database object connected as a writer.
If successful, the return value is true, else, it is false.
This function is useful when another process connects to the same database file. */
-bool tchdbsync(TCHDB *hdb);
+EJDB_EXPORT bool tchdbsync(TCHDB *hdb);
/* Optimize the file of a hash database object.
If successful, the return value is true, else, it is false.
This function is useful to reduce the size of the database file with data fragmentation by
successive updating. */
-bool tchdboptimize(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
+EJDB_EXPORT bool tchdboptimize(TCHDB *hdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
/* Remove all records of a hash database object.
`hdb' specifies the hash database object connected as a writer.
If successful, the return value is true, else, it is false. */
-bool tchdbvanish(TCHDB *hdb);
+EJDB_EXPORT bool tchdbvanish(TCHDB *hdb);
/* Copy the database file of a hash database object.
The database file is assured to be kept synchronized and not modified while the copying or
executing operation is in progress. So, this function is useful to create a backup file of
the database file. */
-bool tchdbcopy(TCHDB *hdb, const char *path);
+EJDB_EXPORT bool tchdbcopy(TCHDB *hdb, const char *path);
/* Begin the transaction of a hash database object.
assumed if every database operation is performed in the transaction. All updated regions are
kept track of by write ahead logging while the transaction. If the database is closed during
transaction, the transaction is aborted implicitly. */
-bool tchdbtranbegin(TCHDB *hdb);
+EJDB_EXPORT bool tchdbtranbegin(TCHDB *hdb);
/* Commit the transaction of a hash database object.
`hdb' specifies the hash database object connected as a writer.
If successful, the return value is true, else, it is false.
Update in the transaction is fixed when it is committed successfully. */
-bool tchdbtrancommit(TCHDB *hdb);
+EJDB_EXPORT bool tchdbtrancommit(TCHDB *hdb);
/* Abort the transaction of a hash database object.
If successful, the return value is true, else, it is false.
Update in the transaction is discarded when it is aborted. The state of the database is
rollbacked to before transaction. */
-bool tchdbtranabort(TCHDB *hdb);
+EJDB_EXPORT bool tchdbtranabort(TCHDB *hdb);
/* Get the file path of a hash database object.
`hdb' specifies the hash database object.
The return value is the path of the database file or `NULL' if the object does not connect to
any database file. */
-const char *tchdbpath(TCHDB *hdb);
+EJDB_EXPORT const char *tchdbpath(TCHDB *hdb);
/* Get the number of records of a hash database object.
`hdb' specifies the hash database object.
The return value is the number of records or 0 if the object does not connect to any database
file. */
-uint64_t tchdbrnum(TCHDB *hdb);
+EJDB_EXPORT uint64_t tchdbrnum(TCHDB *hdb);
/* Get the size of the database file of a hash database object.
`hdb' specifies the hash database object.
The return value is the size of the database file or 0 if the object does not connect to any
database file. */
-uint64_t tchdbfsiz(TCHDB *hdb);
+EJDB_EXPORT uint64_t tchdbfsiz(TCHDB *hdb);
`file' specifies the file name of the code.
`line' specifies the line number of the code.
`func' specifies the function name of the code. */
-void tchdbsetecode(TCHDB *hdb, int ecode, const char *filename, int line, const char *func);
+EJDB_EXPORT void tchdbsetecode(TCHDB *hdb, int ecode, const char *filename, int line, const char *func);
/* Set the type of a hash database object.
`hdb' specifies the hash database object.
`type' specifies the database type. */
-void tchdbsettype(TCHDB *hdb, uint8_t type);
+EJDB_EXPORT void tchdbsettype(TCHDB *hdb, uint8_t type);
/* Set the file descriptor for debugging output.
`hdb' specifies the hash database object.
`fd' specifies the file descriptor for debugging output. */
-void tchdbsetdbgfd(TCHDB *hdb, int fd);
+EJDB_EXPORT void tchdbsetdbgfd(TCHDB *hdb, HANDLE fd);
/* Get the file descriptor for debugging output.
`hdb' specifies the hash database object.
The return value is the file descriptor for debugging output. */
-int tchdbdbgfd(TCHDB *hdb);
+EJDB_EXPORT HANDLE tchdbdbgfd(TCHDB *hdb);
/* Check whether mutual exclusion control is set to a hash database object.
`hdb' specifies the hash database object.
If mutual exclusion control is set, it is true, else it is false. */
-bool tchdbhasmutex(TCHDB *hdb);
+EJDB_EXPORT bool tchdbhasmutex(TCHDB *hdb);
/* Synchronize updating contents on memory of a hash database object.
`hdb' specifies the hash database object.
The return value is the number of elements of the bucket array or 0 if the object does not
connect to any database file. */
-uint64_t tchdbbnum(TCHDB *hdb);
+EJDB_EXPORT uint64_t tchdbbnum(TCHDB *hdb);
/* Get the record alignment of a hash database object.
`hdb' specifies the hash database object.
The return value is the record alignment or 0 if the object does not connect to any database
file. */
-uint32_t tchdbalign(TCHDB *hdb);
+EJDB_EXPORT uint32_t tchdbalign(TCHDB *hdb);
/* Get the maximum number of the free block pool of a a hash database object.
`hdb' specifies the hash database object.
The return value is the maximum number of the free block pool or 0 if the object does not
connect to any database file. */
-uint32_t tchdbfbpmax(TCHDB *hdb);
+EJDB_EXPORT uint32_t tchdbfbpmax(TCHDB *hdb);
/* Get the size of the extra mapped memory of a hash database object.
`hdb' specifies the hash database object.
The return value is the size of the extra mapped memory or 0 if the object does not connect to
any database file. */
-uint64_t tchdbxmsiz(TCHDB *hdb);
+EJDB_EXPORT uint64_t tchdbxmsiz(TCHDB *hdb);
/* Get the inode number of the database file of a hash database object.
`hdb' specifies the hash database object.
The return value is the inode number of the database file or 0 if the object does not connect
to any database file. */
-uint64_t tchdbinode(TCHDB *hdb);
+EJDB_EXPORT uint64_t tchdbinode(TCHDB *hdb);
/* Get the modification time of the database file of a hash database object.
`hdb' specifies the hash database object.
The return value is the inode number of the database file or 0 if the object does not connect
to any database file. */
-time_t tchdbmtime(TCHDB *hdb);
+EJDB_EXPORT time_t tchdbmtime(TCHDB *hdb);
/* Get the connection mode of a hash database object.
`hdb' specifies the hash database object.
The return value is the connection mode. */
-int tchdbomode(TCHDB *hdb);
+EJDB_EXPORT int tchdbomode(TCHDB *hdb);
/* Get the database type of a hash database object.
`hdb' specifies the hash database object.
The return value is the database type. */
-uint8_t tchdbtype(TCHDB *hdb);
+EJDB_EXPORT uint8_t tchdbtype(TCHDB *hdb);
/* Get the additional flags of a hash database object.
`hdb' specifies the hash database object.
The return value is the additional flags. */
-uint8_t tchdbflags(TCHDB *hdb);
+EJDB_EXPORT uint8_t tchdbflags(TCHDB *hdb);
/* Get the options of a hash database object.
`hdb' specifies the hash database object.
The return value is the options. */
-uint8_t tchdbopts(TCHDB *hdb);
+EJDB_EXPORT uint8_t tchdbopts(TCHDB *hdb);
-/* Get the pointer to the opaque field of a hash database object.
- `hdb' specifies the hash database object.
- The return value is the pointer to the opaque field whose size is 128 bytes. */
-char *tchdbopaque(TCHDB *hdb);
+/**
+ * Get opaque data into specified buffer `dst`
+ * `bsiz` Max size to be read.
+ * Return -1 if error, otherwise number of bytes writen in dst.
+ */
+int tchdbreadopaque(TCHDB *hdb, void *dst, int off, int bsiz);
+
+/**
+ * Write opaque data.
+ * Number of bytes specified bt `nb`
+ * can be truncated if it greater than max opaque data size.
+ * Return -1 if error, otherwise number of bytes read from src.
+ */
+int tchdbwriteopaque(TCHDB *hdb, const void *src, int off, int nb);
+/**
+ * Copy opaque data between databases
+ */
+bool tchdbcopyopaque(TCHDB *dst, TCHDB *src, int off, int nb);
/* Get the number of used elements of the bucket array of a hash database object.
`hdb' specifies the hash database object.
The return value is the number of used elements of the bucket array or 0 if the object does
not connect to any database file. */
-uint64_t tchdbbnumused(TCHDB *hdb);
-
+EJDB_EXPORT uint64_t tchdbbnumused(TCHDB *hdb);
/* Set the custom codec functions of a hash database object.
`hdb' specifies the hash database object.
If successful, the return value is true, else, it is false.
Note that the custom codec functions should be set before the database is opened and should be
set every time the database is being opened. */
-bool tchdbsetcodecfunc(TCHDB *hdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop);
+EJDB_EXPORT bool tchdbsetcodecfunc(TCHDB *hdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop);
/* Get the custom codec functions of a hash database object.
function is assigned
`dop' specifies the pointer to a variable into which the arbitrary pointer to be given to the
decoding function is assigned. */
-void tchdbcodecfunc(TCHDB *hdb, TCCODEC *ep, void **eop, TCCODEC *dp, void **dop);
+EJDB_EXPORT void tchdbcodecfunc(TCHDB *hdb, TCCODEC *ep, void **eop, TCCODEC *dp, void **dop);
/* Get the unit step number of auto defragmentation of a hash database object.
`hdb' specifies the hash database object.
The return value is the unit step number of auto defragmentation. */
-uint32_t tchdbdfunit(TCHDB *hdb);
+EJDB_EXPORT uint32_t tchdbdfunit(TCHDB *hdb);
/* Perform dynamic defragmentation of a hash database object.
`step' specifie the number of steps. If it is not more than 0, the whole file is defragmented
gradually without keeping a continuous lock.
If successful, the return value is true, else, it is false. */
-bool tchdbdefrag(TCHDB *hdb, int64_t step);
+EJDB_EXPORT bool tchdbdefrag(TCHDB *hdb, int64_t step);
/* Clear the cache of a hash tree database object.
`hdb' specifies the hash tree database object.
If successful, the return value is true, else, it is false. */
-bool tchdbcacheclear(TCHDB *hdb);
+EJDB_EXPORT bool tchdbcacheclear(TCHDB *hdb);
/* Store a record into a hash database object with a duplication handler.
If successful, the return value is true, else, it is false.
Note that the callback function can not perform any database operation because the function
is called in the critical section guarded by the same locks of database operations. */
-bool tchdbputproc(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tchdbputproc(TCHDB *hdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tchdbgetnext(TCHDB *hdb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tchdbgetnext(TCHDB *hdb, const void *kbuf, int ksiz, int *sp);
/* Retrieve the next string record in a hash database object.
returned if no record corresponds.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tchdbgetnext2(TCHDB *hdb, const char *kstr);
+EJDB_EXPORT char *tchdbgetnext2(TCHDB *hdb, const char *kstr);
/* Retrieve the key and the value of the next record of a record in a hash database object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. The retion pointed to by `vbp'
should not be released. */
-char *tchdbgetnext3(TCHDB *hdb, const char *kbuf, int ksiz, int *sp, const char **vbp, int *vsp);
+EJDB_EXPORT char *tchdbgetnext3(TCHDB *hdb, const char *kbuf, int ksiz, int *sp, const char **vbp, int *vsp);
/* Move the iterator to the record corresponding a key of a hash database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true, else, it is false. False is returned if there is
no record corresponding the condition. */
-bool tchdbiterinit2(TCHDB *hdb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tchdbiterinit2(TCHDB *hdb, const void *kbuf, int ksiz);
/* Move the iterator to the record corresponding a key string of a hash database object.
`kstr' specifies the string of the key.
If successful, the return value is true, else, it is false. False is returned if there is
no record corresponding the condition. */
-bool tchdbiterinit3(TCHDB *hdb, const char *kstr);
+EJDB_EXPORT bool tchdbiterinit3(TCHDB *hdb, const char *kstr);
/* Process each record atomically of a hash database object.
If successful, the return value is true, else, it is false.
Note that the callback function can not perform any database operation because the function
is called in the critical section guarded by the same locks of database operations. */
-bool tchdbforeach(TCHDB *hdb, TCITER iter, void *op);
+EJDB_EXPORT bool tchdbforeach(TCHDB *hdb, TCITER iter, void *op);
/* Void the transaction of a hash database object.
`hdb' specifies the hash database object connected as a writer.
If successful, the return value is true, else, it is false.
This function should be called only when no update in the transaction. */
-bool tchdbtranvoid(TCHDB *hdb);
+EJDB_EXPORT bool tchdbtranvoid(TCHDB *hdb);
/* global variables */
const char *g_progname; // program name
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
/* main routine */
int main(int argc, char **argv){
g_progname = argv[0];
- g_dbgfd = -1;
+ g_dbgfd = INVALID_HANDLE_VALUE;
const char *ebuf = getenv("TCDBGFD");
- if(ebuf) g_dbgfd = tcatoix(ebuf);
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "create")){
/* perform create command */
static int proccreate(const char *path, int bnum, int apow, int fpow, int opts){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbtune(hdb, bnum, apow, fpow, opts)){
printerr(hdb);
/* perform inform command */
static int procinform(const char *path, int omode){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL);
if(!tchdbopen(hdb, path, HDBOREADER | omode)){
printerr(hdb);
if(flags & HDBFOPEN) printf(" open");
if(flags & HDBFFATAL) printf(" fatal");
printf("\n");
- printf("bucket number: %llu\n", (unsigned long long)tchdbbnum(hdb));
+ printf("bucket number: %" PRIuMAX "\n", (unsigned long long)tchdbbnum(hdb));
if(hdb->cnt_writerec >= 0)
- printf("used bucket number: %lld\n", (long long)tchdbbnumused(hdb));
+ printf("used bucket number: %" PRIdMAX "\n", (long long)tchdbbnumused(hdb));
printf("alignment: %u\n", tchdbalign(hdb));
printf("free block pool: %u\n", tchdbfbpmax(hdb));
- printf("inode number: %lld\n", (long long)tchdbinode(hdb));
+ printf("inode number: %" PRIdMAX "\n", (long long)tchdbinode(hdb));
char date[48];
tcdatestrwww(tchdbmtime(hdb), INT_MAX, date);
printf("modified time: %s\n", date);
if(opts & HDBTTCBS) printf(" tcbs");
if(opts & HDBTEXCODEC) printf(" excodec");
printf("\n");
- printf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- printf("file size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ printf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ printf("file size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
if(!tchdbclose(hdb)){
if(!err) printerr(hdb);
err = true;
static int procput(const char *path, const char *kbuf, int ksiz, const char *vbuf, int vsiz,
int omode, int dmode){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbopen(hdb, path, HDBOWRITER | omode)){
printerr(hdb);
/* perform out command */
static int procout(const char *path, const char *kbuf, int ksiz, int omode){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbopen(hdb, path, HDBOWRITER | omode)){
printerr(hdb);
/* perform get command */
static int procget(const char *path, const char *kbuf, int ksiz, int omode, bool px, bool pz){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbopen(hdb, path, HDBOREADER | omode)){
printerr(hdb);
/* perform list command */
static int proclist(const char *path, int omode, int max, bool pv, bool px, const char *fmstr){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbopen(hdb, path, HDBOREADER | omode)){
printerr(hdb);
static int procoptimize(const char *path, int bnum, int apow, int fpow, int opts, int omode,
bool df){
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbopen(hdb, path, HDBOWRITER | omode)){
printerr(hdb);
return 1;
}
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetcodecfunc(hdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(hdb);
if(!tchdbopen(hdb, path, HDBOWRITER | HDBOCREAT | omode)){
printerr(hdb);
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
/* print members of hash database */
static void mprint(TCHDB *hdb){
if(hdb->cnt_writerec < 0) return;
- iprintf("bucket number: %lld\n", (long long)tchdbbnum(hdb));
- iprintf("used bucket number: %lld\n", (long long)tchdbbnumused(hdb));
- iprintf("cnt_writerec: %lld\n", (long long)hdb->cnt_writerec);
- iprintf("cnt_reuserec: %lld\n", (long long)hdb->cnt_reuserec);
- iprintf("cnt_moverec: %lld\n", (long long)hdb->cnt_moverec);
- iprintf("cnt_readrec: %lld\n", (long long)hdb->cnt_readrec);
- iprintf("cnt_searchfbp: %lld\n", (long long)hdb->cnt_searchfbp);
- iprintf("cnt_insertfbp: %lld\n", (long long)hdb->cnt_insertfbp);
- iprintf("cnt_splicefbp: %lld\n", (long long)hdb->cnt_splicefbp);
- iprintf("cnt_dividefbp: %lld\n", (long long)hdb->cnt_dividefbp);
- iprintf("cnt_mergefbp: %lld\n", (long long)hdb->cnt_mergefbp);
- iprintf("cnt_reducefbp: %lld\n", (long long)hdb->cnt_reducefbp);
- iprintf("cnt_appenddrp: %lld\n", (long long)hdb->cnt_appenddrp);
- iprintf("cnt_deferdrp: %lld\n", (long long)hdb->cnt_deferdrp);
- iprintf("cnt_flushdrp: %lld\n", (long long)hdb->cnt_flushdrp);
- iprintf("cnt_adjrecc: %lld\n", (long long)hdb->cnt_adjrecc);
- iprintf("cnt_defrag: %lld\n", (long long)hdb->cnt_defrag);
- iprintf("cnt_shiftrec: %lld\n", (long long)hdb->cnt_shiftrec);
- iprintf("cnt_trunc: %lld\n", (long long)hdb->cnt_trunc);
+ iprintf("bucket number: %" PRIdMAX "\n", (long long)tchdbbnum(hdb));
+ iprintf("used bucket number: %" PRIdMAX "\n", (long long)tchdbbnumused(hdb));
+ iprintf("cnt_writerec: %" PRIdMAX "\n", (long long)hdb->cnt_writerec);
+ iprintf("cnt_reuserec: %" PRIdMAX "\n", (long long)hdb->cnt_reuserec);
+ iprintf("cnt_moverec: %" PRIdMAX "\n", (long long)hdb->cnt_moverec);
+ iprintf("cnt_readrec: %" PRIdMAX "\n", (long long)hdb->cnt_readrec);
+ iprintf("cnt_searchfbp: %" PRIdMAX "\n", (long long)hdb->cnt_searchfbp);
+ iprintf("cnt_insertfbp: %" PRIdMAX "\n", (long long)hdb->cnt_insertfbp);
+ iprintf("cnt_splicefbp: %" PRIdMAX "\n", (long long)hdb->cnt_splicefbp);
+ iprintf("cnt_dividefbp: %" PRIdMAX "\n", (long long)hdb->cnt_dividefbp);
+ iprintf("cnt_mergefbp: %" PRIdMAX "\n", (long long)hdb->cnt_mergefbp);
+ iprintf("cnt_reducefbp: %" PRIdMAX "\n", (long long)hdb->cnt_reducefbp);
+ iprintf("cnt_appenddrp: %" PRIdMAX "\n", (long long)hdb->cnt_appenddrp);
+ iprintf("cnt_deferdrp: %" PRIdMAX "\n", (long long)hdb->cnt_deferdrp);
+ iprintf("cnt_flushdrp: %" PRIdMAX "\n", (long long)hdb->cnt_flushdrp);
+ iprintf("cnt_adjrecc: %" PRIdMAX "\n", (long long)hdb->cnt_adjrecc);
+ iprintf("cnt_defrag: %" PRIdMAX "\n", (long long)hdb->cnt_defrag);
+ iprintf("cnt_shiftrec: %" PRIdMAX "\n", (long long)hdb->cnt_shiftrec);
+ iprintf("cnt_trunc: %" PRIdMAX "\n", (long long)hdb->cnt_trunc);
}
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
if(rnum % 50 > 0) iprintf(" (%08d)\n", rnum);
}
tcmapdel(map);
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(!tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
/* main routine */
int main(int argc, char **argv){
+
g_progname = argv[0];
const char *ebuf = getenv("TCRNDSEED");
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
+ g_dbgfd = INVALID_HANDLE_VALUE;
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
/* print members of hash database */
static void mprint(TCHDB *hdb){
if(hdb->cnt_writerec < 0) return;
- iprintf("bucket number: %lld\n", (long long)tchdbbnum(hdb));
- iprintf("used bucket number: %lld\n", (long long)tchdbbnumused(hdb));
- iprintf("cnt_writerec: %lld\n", (long long)hdb->cnt_writerec);
- iprintf("cnt_reuserec: %lld\n", (long long)hdb->cnt_reuserec);
- iprintf("cnt_moverec: %lld\n", (long long)hdb->cnt_moverec);
- iprintf("cnt_readrec: %lld\n", (long long)hdb->cnt_readrec);
- iprintf("cnt_searchfbp: %lld\n", (long long)hdb->cnt_searchfbp);
- iprintf("cnt_insertfbp: %lld\n", (long long)hdb->cnt_insertfbp);
- iprintf("cnt_splicefbp: %lld\n", (long long)hdb->cnt_splicefbp);
- iprintf("cnt_dividefbp: %lld\n", (long long)hdb->cnt_dividefbp);
- iprintf("cnt_mergefbp: %lld\n", (long long)hdb->cnt_mergefbp);
- iprintf("cnt_reducefbp: %lld\n", (long long)hdb->cnt_reducefbp);
- iprintf("cnt_appenddrp: %lld\n", (long long)hdb->cnt_appenddrp);
- iprintf("cnt_deferdrp: %lld\n", (long long)hdb->cnt_deferdrp);
- iprintf("cnt_flushdrp: %lld\n", (long long)hdb->cnt_flushdrp);
- iprintf("cnt_adjrecc: %lld\n", (long long)hdb->cnt_adjrecc);
- iprintf("cnt_defrag: %lld\n", (long long)hdb->cnt_defrag);
- iprintf("cnt_shiftrec: %lld\n", (long long)hdb->cnt_shiftrec);
- iprintf("cnt_trunc: %lld\n", (long long)hdb->cnt_trunc);
+ iprintf("bucket number: %" PRIdMAX "\n", (long long)tchdbbnum(hdb));
+ iprintf("used bucket number: %" PRIdMAX "\n", (long long)tchdbbnumused(hdb));
+ iprintf("msiz: %" PRIdMAX "\n", hdb->msiz);
+ iprintf("xmsiz: %" PRIdMAX "\n", hdb->xmsiz);
+ iprintf("fbpnum: %" PRIdMAX "\n", hdb->fbpnum);
+ iprintf("fbpool: %p\n", hdb->fbpool);
+ iprintf("cnt_writerec: %" PRIdMAX "\n", (long long)hdb->cnt_writerec);
+ iprintf("cnt_reuserec: %" PRIdMAX "\n", (long long)hdb->cnt_reuserec);
+ iprintf("cnt_moverec: %" PRIdMAX "\n", (long long)hdb->cnt_moverec);
+ iprintf("cnt_readrec: %" PRIdMAX "\n", (long long)hdb->cnt_readrec);
+ iprintf("cnt_searchfbp: %" PRIdMAX "\n", (long long)hdb->cnt_searchfbp);
+ iprintf("cnt_insertfbp: %" PRIdMAX "\n", (long long)hdb->cnt_insertfbp);
+ iprintf("cnt_splicefbp: %" PRIdMAX "\n", (long long)hdb->cnt_splicefbp);
+ iprintf("cnt_dividefbp: %" PRIdMAX "\n", (long long)hdb->cnt_dividefbp);
+ iprintf("cnt_mergefbp: %" PRIdMAX "\n", (long long)hdb->cnt_mergefbp);
+ iprintf("cnt_reducefbp: %" PRIdMAX "\n", (long long)hdb->cnt_reducefbp);
+ iprintf("cnt_appenddrp: %" PRIdMAX "\n", (long long)hdb->cnt_appenddrp);
+ iprintf("cnt_deferdrp: %" PRIdMAX "\n", (long long)hdb->cnt_deferdrp);
+ iprintf("cnt_flushdrp: %" PRIdMAX "\n", (long long)hdb->cnt_flushdrp);
+ iprintf("cnt_adjrecc: %" PRIdMAX "\n", (long long)hdb->cnt_adjrecc);
+ iprintf("cnt_defrag: %" PRIdMAX "\n", (long long)hdb->cnt_defrag);
+ iprintf("cnt_shiftrec: %" PRIdMAX "\n", (long long)hdb->cnt_shiftrec);
+ iprintf("cnt_trunc: %" PRIdMAX "\n", (long long)hdb->cnt_trunc);
}
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(mt && !tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(mt && !tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(mt && !tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(mt && !tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(mt && !tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
eprint(hdb, __LINE__, "tchdbopen");
err = true;
}
- if(TCUSEPTHREAD){
+ if(1){
TCHDB *hdbdup = tchdbnew();
if(tchdbopen(hdbdup, path, HDBOREADER)){
eprint(hdb, __LINE__, "(validation)");
eprint(hdb, __LINE__, "tchdbtranabort");
err = true;
}
- iprintf("checking consistency:\n");
+ iprintf("checking consistency: %d %d\n", (int)tchdbrnum(hdb), (int) ornum);
if(tchdbrnum(hdb) != ornum || tchdbfsiz(hdb) != ofsiz || tchdbrnum(hdb) != tcmaprnum(map)){
eprint(hdb, __LINE__, "(validation)");
err = true;
eprint(hdb, __LINE__, "tchdbforeach");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
if(!tchdbclose(hdb)){
bool err = false;
double stime = tctime();
TCHDB *hdb = tchdbnew();
- if(g_dbgfd >= 0) tchdbsetdbgfd(hdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tchdbsetdbgfd(hdb, g_dbgfd);
if(mt && !tchdbsetmutex(hdb)){
eprint(hdb, __LINE__, "tchdbsetmutex");
err = true;
eprint(hdb, __LINE__, "(validation)");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tchdbrnum(hdb));
- iprintf("size: %llu\n", (unsigned long long)tchdbfsiz(hdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tchdbrnum(hdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tchdbfsiz(hdb));
mprint(hdb);
sysprint();
tcmapdel(map);
/* Set mutual exclusion control of a table database object for threading. */
bool tctdbsetmutex(TCTDB *tdb){
assert(tdb);
- if(!TCUSEPTHREAD) return true;
if(tdb->mmtx || tdb->open){
tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);
return false;
/* Begin the transaction of a table database object. */
bool tctdbtranbegin(TCTDB *tdb){
assert(tdb);
- for(double wsec = 1.0 / sysconf(_SC_CLK_TCK); true; wsec *= 2){
+ for(double wsec = 1.0 / sysconf_SC_CLK_TCK; true; wsec *= 2){
if(!TDBLOCKMETHOD(tdb, true)) return false;
if(!tdb->open || !tdb->wmode){
tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);
if(flags & TDBQPSTOP) break;
}
tclistdel(res);
- tcxstrprintf(qry->hint, "post treatment: get=%lld, put=%lld, out=%lld\n",
+ tcxstrprintf(qry->hint, "post treatment: get=%" PRIdMAX ", put=%" PRIdMAX ", out=%" PRIdMAX "\n",
(long long)getnum, (long long)putnum, (long long)outnum);
TDBUNLOCKMETHOD(tdb);
return !err;
/* Set the file descriptor for debugging output. */
-void tctdbsetdbgfd(TCTDB *tdb, int fd){
- assert(tdb && fd >= 0);
+void tctdbsetdbgfd(TCTDB *tdb, HANDLE fd){
+ assert(tdb);
tchdbsetdbgfd(tdb->hdb, fd);
}
/* Get the file descriptor for debugging output. */
-int tctdbdbgfd(TCTDB *tdb){
+HANDLE tctdbdbgfd(TCTDB *tdb){
assert(tdb);
return tchdbdbgfd(tdb->hdb);
}
}
-/* Get the pointer to the opaque field of a table database object. */
-char *tctdbopaque(TCTDB *tdb){
- assert(tdb);
- if(!tdb->open){
- tctdbsetecode(tdb, TCEINVALID, __FILE__, __LINE__, __func__);
- return NULL;
- }
- return tchdbopaque(tdb->hdb) + TDBOPAQUESIZ;
-}
-
-
/* Get the number of used elements of the bucket array of a table database object. */
uint64_t tctdbbnumused(TCTDB *tdb){
assert(tdb);
TDBUNLOCKMETHOD(tdb);
}
tclistdel(res);
- tcxstrprintf(qry->hint, "post treatment: get=%lld, put=%lld, out=%lld\n",
+ tcxstrprintf(qry->hint, "post treatment: get=%" PRIdMAX ", put=%" PRIdMAX ", out=%" PRIdMAX "\n",
(long long)getnum, (long long)putnum, (long long)outnum);
return !err;
}
If successful, the return value is true, else, it is false. */
static bool tctdbopenimpl(TCTDB *tdb, const char *path, int omode){
assert(tdb && path);
- int dbgfd = tchdbdbgfd(tdb->hdb);
+ HANDLE dbgfd = tchdbdbgfd(tdb->hdb);
TCCODEC enc, dec;
void *encop, *decop;
tchdbcodecfunc(tdb->hdb, &enc, &encop, &dec, &decop);
char *name = tcurldecode(stem, &nsiz);
if(!strcmp(ep, "lex") || !strcmp(ep, "dec") || !strcmp(ep, "tok") || !strcmp(ep, "qgr")){
TCBDB *bdb = tcbdbnew();
- if(dbgfd >= 0) tcbdbsetdbgfd(bdb, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(bdb, dbgfd);
if(tdb->mmtx) tcbdbsetmutex(bdb);
if(enc && dec) tcbdbsetcodecfunc(bdb, enc, encop, dec, decop);
tcbdbsetcache(bdb, tdb->lcnum, tdb->ncnum);
}
}
const char *path = tchdbpath(tdb->hdb);
- char *tpath = tcsprintf("%s%ctmp%c%llu", path, MYEXTCHR, MYEXTCHR, tchdbinode(tdb->hdb));
+ char *tpath = tcsprintf("%s%ctmp%c%" PRIuMAX "", path, MYEXTCHR, MYEXTCHR, tchdbinode(tdb->hdb));
TCHDB *thdb = tchdbnew();
tchdbsettype(thdb, TCDBTTABLE);
- int dbgfd = tchdbdbgfd(tdb->hdb);
- if(dbgfd >= 0) tchdbsetdbgfd(thdb, dbgfd);
+ HANDLE dbgfd = tchdbdbgfd(tdb->hdb);
+ if(!INVALIDHANDLE(dbgfd)) tchdbsetdbgfd(thdb, dbgfd);
TCCODEC enc, dec;
void *encop, *decop;
tchdbcodecfunc(hdb, &enc, &encop, &dec, &decop);
if(opts & TDBTTCBS) hopts |= HDBTTCBS;
if(opts & TDBTEXCODEC) hopts |= HDBTEXCODEC;
tchdbtune(thdb, bnum, apow, fpow, hopts);
- if(tchdbopen(thdb, tpath, HDBOWRITER | HDBOCREAT | HDBOTRUNC)){
- memcpy(tchdbopaque(thdb), tchdbopaque(hdb), TDBOPAQUESIZ + TDBLEFTOPQSIZ);
+ if(tchdbopen(thdb, tpath, HDBOWRITER | HDBOCREAT | HDBOTRUNC) && tchdbcopyopaque(thdb, hdb, 0, -1)) {
if(!tchdbiterinit(hdb)) err = true;
TCXSTR *kxstr = tcxstrnew();
TCXSTR *vxstr = tcxstrnew();
err = true;
}
if(!err){
- if(unlink(path) == -1){
+ char *npath = tcstrdup(path);
+ int omode = (tchdbomode(hdb) & ~HDBOCREAT) & ~HDBOTRUNC;
+ if(!tchdbclose(hdb)) err = true;
+ if(unlink(npath)){
tctdbsetecode(tdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
- if(rename(tpath, path) == -1){
+ if(rename(tpath, npath)){
tctdbsetecode(tdb, TCERENAME, __FILE__, __LINE__, __func__);
err = true;
}
- char *npath = tcstrdup(path);
- int omode = (tchdbomode(hdb) & ~HDBOCREAT) & ~HDBOTRUNC;
- if(!tchdbclose(hdb)) err = true;
if(!tchdbopen(hdb, npath, omode)) err = true;
TCFREE(npath);
}
int inum = tdb->inum;
for(int i = 0; i < inum; i++){
TDBIDX *idx = idxs + i;
- const char *path;
+ char *path;
if(!strcmp(idx->name, name)){
if(keep){
tctdbsetecode(tdb, TCEKEEP, __FILE__, __LINE__, __func__);
case TDBITDECIMAL:
case TDBITTOKEN:
case TDBITQGRAM:
- path = tcbdbpath(idx->db);
+ path = tcstrdup(tcbdbpath(idx->db));
+ tcbdbdel(idx->db);
if(path && unlink(path)){
tctdbsetecode(tdb, TCEUNLINK, __FILE__, __LINE__, __func__);
err = true;
}
- tcbdbdel(idx->db);
+ TCFREE(path);
break;
}
TCFREE(idx->name);
if(homode & HDBONOLCK) bomode |= BDBONOLCK;
if(homode & HDBOLCKNB) bomode |= BDBOLCKNB;
if(homode & HDBOTSYNC) bomode |= BDBOTSYNC;
- int dbgfd = tchdbdbgfd(tdb->hdb);
+ HANDLE dbgfd = tchdbdbgfd(tdb->hdb);
TCCODEC enc, dec;
void *encop, *decop;
tchdbcodecfunc(tdb->hdb, &enc, &encop, &dec, &decop);
idx->db = tcbdbnew();
idx->name = tcstrdup(name);
tcxstrprintf(pbuf, "%clex", MYEXTCHR);
- if(dbgfd >= 0) tcbdbsetdbgfd(idx->db, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(idx->db, dbgfd);
if(tdb->mmtx) tcbdbsetmutex(idx->db);
if(enc && dec) tcbdbsetcodecfunc(idx->db, enc, encop, dec, decop);
tcbdbtune(idx->db, TDBIDXLMEMB, TDBIDXNMEMB, bbnum, -1, -1, bopts);
idx->db = tcbdbnew();
idx->name = tcstrdup(name);
tcxstrprintf(pbuf, "%cdec", MYEXTCHR);
- if(dbgfd >= 0) tcbdbsetdbgfd(idx->db, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(idx->db, dbgfd);
if(tdb->mmtx) tcbdbsetmutex(idx->db);
tcbdbsetcmpfunc(idx->db, tccmpdecimal, NULL);
if(enc && dec) tcbdbsetcodecfunc(idx->db, enc, encop, dec, decop);
idx->cc = tcmapnew2(TDBIDXICCBNUM);
idx->name = tcstrdup(name);
tcxstrprintf(pbuf, "%ctok", MYEXTCHR);
- if(dbgfd >= 0) tcbdbsetdbgfd(idx->db, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(idx->db, dbgfd);
if(tdb->mmtx) tcbdbsetmutex(idx->db);
if(enc && dec) tcbdbsetcodecfunc(idx->db, enc, encop, dec, decop);
tcbdbtune(idx->db, TDBIDXLMEMB, TDBIDXNMEMB, bbnum, -1, -1, bopts);
idx->cc = tcmapnew2(TDBIDXICCBNUM);
idx->name = tcstrdup(name);
tcxstrprintf(pbuf, "%cqgr", MYEXTCHR);
- if(dbgfd >= 0) tcbdbsetdbgfd(idx->db, dbgfd);
+ if(!INVALIDHANDLE(dbgfd)) tcbdbsetdbgfd(idx->db, dbgfd);
if(tdb->mmtx) tcbdbsetmutex(idx->db);
if(enc && dec) tcbdbsetcodecfunc(idx->db, enc, encop, dec, decop);
tcbdbtune(idx->db, TDBIDXLMEMB, TDBIDXNMEMB, bbnum, -1, -1, bopts);
The return value is the new unique ID number or -1 on failure. */
static int64_t tctdbgenuidimpl(TCTDB *tdb, int64_t inc){
assert(tdb);
- void *opq = tchdbopaque(tdb->hdb);
uint64_t llnum, uid;
if(inc < 0){
uid = -inc - 1;
} else {
- memcpy(&llnum, opq, sizeof(llnum));
+ tchdbreadopaque(tdb->hdb, &llnum, 0, sizeof(llnum));
if(inc == 0) return TCITOHLL(llnum);
uid = TCITOHLL(llnum) + inc;
}
llnum = TCITOHLL(uid);
- memcpy(opq, &llnum, sizeof(llnum));
+ tchdbwriteopaque(tdb->hdb, &llnum, 0, sizeof(llnum));
return uid;
}
tcmapdel(nmap);
nmap = tctdbidxgetbyfts(tdb, idx, cond, hint);
}
- tcxstrprintf(hint, "auxiliary result set size: %lld\n", (long long)TCMAPRNUM(nmap));
+ tcxstrprintf(hint, "auxiliary result set size: %" PRIdMAX "\n", (long long)TCMAPRNUM(nmap));
return nmap;
}
return !err;
}
-
/* Add a column of a record into an index of a table database object.
`tdb' specifies the table database object.
`idx' specifies the index object.
int step;
TCREADVNUMBUF64(cbuf, tid, step);
char pkbuf[TCNUMBUFSIZ];
- int pksiz = sprintf(pkbuf, "%lld", (long long)tid);
+ int pksiz = sprintf(pkbuf, "%" PRIdMAX "", (long long)tid);
if(cnt < 1){
tcmapput(res, pkbuf, pksiz, "", 0);
} else if(wring){
int step;
TCREADVNUMBUF64(cbuf, tid, step);
char pkbuf[TCNUMBUFSIZ];
- int pksiz = sprintf(pkbuf, "%lld", (long long)tid);
+ int pksiz = sprintf(pkbuf, "%" PRIdMAX "", (long long)tid);
if(cnt < 1){
tcmapput(res, pkbuf, pksiz, "", 0);
} else if(wring){
if(off == ocr->off + rem){
onum++;
char pkbuf[TCNUMBUFSIZ];
- int pksiz = sprintf(pkbuf, "%lld", (long long)pkid);
+ int pksiz = sprintf(pkbuf, "%" PRIdMAX "", (long long)pkid);
if(ores){
int rsiz;
if(tcmapget(ores, pkbuf, pksiz, &rsiz)){
if(uniq) tcmapputkeep(uniq, pkbuf, pksiz, "", 0);
} else {
char numbuf[TCNUMBUFSIZ];
- int pksiz = sprintf(numbuf, "%lld", (long long)pkid);
+ int pksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)pkid);
if(ores){
int rsiz;
if(tcmapget(ores, numbuf, pksiz, &rsiz)){
if(uniq) tcmapputkeep(uniq, pkbuf, pksiz, "", 0);
} else {
char numbuf[TCNUMBUFSIZ];
- int pksiz = sprintf(numbuf, "%lld", (long long)pkid);
+ int pksiz = sprintf(numbuf, "%" PRIdMAX "", (long long)pkid);
if(ores){
int rsiz;
if(tcmapget(ores, numbuf, pksiz, &rsiz)){
`tdb' specifies the table database object. */
void tctdbprintmeta(TCTDB *tdb){
assert(tdb);
- int dbgfd = tchdbdbgfd(tdb->hdb);
- if(dbgfd < 0) return;
- if(dbgfd == UINT16_MAX) dbgfd = 1;
+ HANDLE dbgfd = tchdbdbgfd(tdb->hdb);
+ if(!INVALIDHANDLE(dbgfd)) {
+ dbgfd = GET_STDOUT_HANDLE();
+ }
char buf[TDBPAGEBUFSIZ];
char *wp = buf;
wp += sprintf(wp, "META:");
wp += sprintf(wp, " opts=%u", tdb->opts);
wp += sprintf(wp, " lcnum=%d", tdb->lcnum);
wp += sprintf(wp, " ncnum=%d", tdb->ncnum);
- wp += sprintf(wp, " iccmax=%lld", (long long)tdb->iccmax);
+ wp += sprintf(wp, " iccmax=%" PRIdMAX "", (long long)tdb->iccmax);
wp += sprintf(wp, " iccsync=%f", tdb->iccsync);
wp += sprintf(wp, " idxs=%p", (void *)tdb->idxs);
wp += sprintf(wp, " inum=%d", tdb->inum);
/* Get the message string corresponding to an error code.
`ecode' specifies the error code.
The return value is the message string of the error code. */
-const char *tctdberrmsg(int ecode);
+EJDB_EXPORT const char *tctdberrmsg(int ecode);
/* Create a table database object.
The return value is the new table database object. */
-TCTDB *tctdbnew(void);
+EJDB_EXPORT TCTDB *tctdbnew(void);
/* Delete a table database object.
`tdb' specifies the table database object.
If the database is not closed, it is closed implicitly. Note that the deleted object and its
derivatives can not be used anymore. */
-void tctdbdel(TCTDB *tdb);
+EJDB_EXPORT void tctdbdel(TCTDB *tdb);
/* Get the last happened error code of a table database object.
for unlink error, `TCERENAME' for rename error, `TCEMKDIR' for mkdir error, `TCERMDIR' for
rmdir error, `TCEKEEP' for existing record, `TCENOREC' for no record found, and `TCEMISC' for
miscellaneous error. */
-int tctdbecode(TCTDB *tdb);
+EJDB_EXPORT int tctdbecode(TCTDB *tdb);
/* Set mutual exclusion control of a table database object for threading.
If successful, the return value is true, else, it is false.
Note that the mutual exclusion control is needed if the object is shared by plural threads and
this function should be called before the database is opened. */
-bool tctdbsetmutex(TCTDB *tdb);
+EJDB_EXPORT bool tctdbsetmutex(TCTDB *tdb);
/* Set the tuning parameters of a table database object.
BZIP2 encoding, `TDBTTCBS' specifies that each record is compressed with TCBS encoding.
If successful, the return value is true, else, it is false.
Note that the tuning parameters should be set before the database is opened. */
-bool tctdbtune(TCTDB *tdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
+EJDB_EXPORT bool tctdbtune(TCTDB *tdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
/* Set the caching parameters of a table database object.
If successful, the return value is true, else, it is false.
Note that the caching parameters should be set before the database is opened. Leaf nodes and
non-leaf nodes are used in column indices. */
-bool tctdbsetcache(TCTDB *tdb, int32_t rcnum, int32_t lcnum, int32_t ncnum);
+EJDB_EXPORT bool tctdbsetcache(TCTDB *tdb, int32_t rcnum, int32_t lcnum, int32_t ncnum);
/* Set the size of the extra mapped memory of a table database object.
mapped memory is disabled. The default size is 67108864.
If successful, the return value is true, else, it is false.
Note that the mapping parameters should be set before the database is opened. */
-bool tctdbsetxmsiz(TCTDB *tdb, int64_t xmsiz);
+EJDB_EXPORT bool tctdbsetxmsiz(TCTDB *tdb, int64_t xmsiz);
/* Set the unit step number of auto defragmentation of a table database object.
is disabled. It is disabled by default.
If successful, the return value is true, else, it is false.
Note that the defragmentation parameters should be set before the database is opened. */
-bool tctdbsetdfunit(TCTDB *tdb, int32_t dfunit);
+EJDB_EXPORT bool tctdbsetdfunit(TCTDB *tdb, int32_t dfunit);
/* Open a database file and connect a table database object.
bitwise-or: `TDBONOLCK', which means it opens the database file without file locking, or
`TDBOLCKNB', which means locking is performed without blocking.
If successful, the return value is true, else, it is false. */
-bool tctdbopen(TCTDB *tdb, const char *path, int omode);
+EJDB_EXPORT bool tctdbopen(TCTDB *tdb, const char *path, int omode);
/* Close a table database object.
If successful, the return value is true, else, it is false.
Update of a database is assured to be written when the database is closed. If a writer opens
a database but does not close it appropriately, the database will be broken. */
-bool tctdbclose(TCTDB *tdb);
+EJDB_EXPORT bool tctdbclose(TCTDB *tdb);
/* Store a record into a table database object.
`cols' specifies a map object containing columns.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tctdbput(TCTDB *tdb, const void *pkbuf, int pksiz, TCMAP *cols);
+EJDB_EXPORT bool tctdbput(TCTDB *tdb, const void *pkbuf, int pksiz, TCMAP *cols);
/* Store a string record into a table database object with a zero separated column string.
`csiz' specifies the size of the region of the column string.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tctdbput2(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz);
+EJDB_EXPORT bool tctdbput2(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz);
/* Store a string record into a table database object with a tab separated column string.
value of each column are situated one after the other.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, it is overwritten. */
-bool tctdbput3(TCTDB *tdb, const char *pkstr, const char *cstr);
+EJDB_EXPORT bool tctdbput3(TCTDB *tdb, const char *pkstr, const char *cstr);
/* Store a new record into a table database object.
`cols' specifies a map object containing columns.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tctdbputkeep(TCTDB *tdb, const void *pkbuf, int pksiz, TCMAP *cols);
+EJDB_EXPORT bool tctdbputkeep(TCTDB *tdb, const void *pkbuf, int pksiz, TCMAP *cols);
/* Store a new string record into a table database object with a zero separated column string.
`csiz' specifies the size of the region of the column string.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tctdbputkeep2(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz);
+EJDB_EXPORT bool tctdbputkeep2(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz);
/* Store a new string record into a table database object with a tab separated column string.
value of each column are situated one after the other.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tctdbputkeep3(TCTDB *tdb, const char *pkstr, const char *cstr);
+EJDB_EXPORT bool tctdbputkeep3(TCTDB *tdb, const char *pkstr, const char *cstr);
/* Concatenate columns of the existing record in a table database object.
`cols' specifies a map object containing columns.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tctdbputcat(TCTDB *tdb, const void *pkbuf, int pksiz, TCMAP *cols);
+EJDB_EXPORT bool tctdbputcat(TCTDB *tdb, const void *pkbuf, int pksiz, TCMAP *cols);
/* Concatenate columns in a table database object with a zero separated column string.
`csiz' specifies the size of the region of the column string.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tctdbputcat2(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz);
+EJDB_EXPORT bool tctdbputcat2(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz);
/* Concatenate columns in a table database object with with a tab separated column string.
value of each column are situated one after the other.
If successful, the return value is true, else, it is false.
If there is no corresponding record, a new record is created. */
-bool tctdbputcat3(TCTDB *tdb, const char *pkstr, const char *cstr);
+EJDB_EXPORT bool tctdbputcat3(TCTDB *tdb, const char *pkstr, const char *cstr);
/* Remove a record of a table database object.
`pkbuf' specifies the pointer to the region of the primary key.
`pksiz' specifies the size of the region of the primary key.
If successful, the return value is true, else, it is false. */
-bool tctdbout(TCTDB *tdb, const void *pkbuf, int pksiz);
+EJDB_EXPORT bool tctdbout(TCTDB *tdb, const void *pkbuf, int pksiz);
/* Remove a string record of a table database object.
`tdb' specifies the table database object connected as a writer.
`pkstr' specifies the string of the primary key.
If successful, the return value is true, else, it is false. */
-bool tctdbout2(TCTDB *tdb, const char *pkstr);
+EJDB_EXPORT bool tctdbout2(TCTDB *tdb, const char *pkstr);
/* Retrieve a record in a table database object.
`NULL' is returned if no record corresponds.
Because the object of the return value is created with the function `tcmapnew', it should be
deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tctdbget(TCTDB *tdb, const void *pkbuf, int pksiz);
+EJDB_EXPORT TCMAP *tctdbget(TCTDB *tdb, const void *pkbuf, int pksiz);
/* Retrieve a record in a table database object as a zero separated column string.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-char *tctdbget2(TCTDB *tdb, const void *pkbuf, int pksiz, int *sp);
+EJDB_EXPORT char *tctdbget2(TCTDB *tdb, const void *pkbuf, int pksiz, int *sp);
/* Retrieve a string record in a table database object as a tab separated column string.
record. `NULL' is returned if no record corresponds.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tctdbget3(TCTDB *tdb, const char *pkstr);
+EJDB_EXPORT char *tctdbget3(TCTDB *tdb, const char *pkstr);
/* Get the size of the value of a record in a table database object.
`ksiz' specifies the size of the region of the primary key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tctdbvsiz(TCTDB *tdb, const void *pkbuf, int pksiz);
+EJDB_EXPORT int tctdbvsiz(TCTDB *tdb, const void *pkbuf, int pksiz);
/* Get the size of the value of a string record in a table database object.
`kstr' specifies the string of the primary key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tctdbvsiz2(TCTDB *tdb, const char *pkstr);
+EJDB_EXPORT int tctdbvsiz2(TCTDB *tdb, const char *pkstr);
/* Initialize the iterator of a table database object.
If successful, the return value is true, else, it is false.
The iterator is used in order to access the primary key of every record stored in a
database. */
-bool tctdbiterinit(TCTDB *tdb);
+EJDB_EXPORT bool tctdbiterinit(TCTDB *tdb);
/* Get the next primary key of the iterator of a table database object.
However, it is not assured if updating the database is occurred while the iteration. Besides,
the order of this traversal access method is arbitrary, so it is not assured that the order of
storing matches the one of the traversal access. */
-void *tctdbiternext(TCTDB *tdb, int *sp);
+EJDB_EXPORT void *tctdbiternext(TCTDB *tdb, int *sp);
/* Get the next primary key string of the iterator of a table database object.
database is occurred while the iteration. Besides, the order of this traversal access method
is arbitrary, so it is not assured that the order of storing matches the one of the traversal
access. */
-char *tctdbiternext2(TCTDB *tdb);
+EJDB_EXPORT char *tctdbiternext2(TCTDB *tdb);
/* Get the columns of the next record of the iterator of a table database object.
the database is occurred while the iteration. Besides, the order of this traversal access
method is arbitrary, so it is not assured that the order of storing matches the one of the
traversal access. */
-TCMAP *tctdbiternext3(TCTDB *tdb);
+EJDB_EXPORT TCMAP *tctdbiternext3(TCTDB *tdb);
/* Get forward matching primary keys in a table database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tctdbfwmkeys(TCTDB *tdb, const void *pbuf, int psiz, int max);
+EJDB_EXPORT TCLIST *tctdbfwmkeys(TCTDB *tdb, const void *pbuf, int psiz, int max);
/* Get forward matching string primary keys in a table database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tctdbfwmkeys2(TCTDB *tdb, const char *pstr, int max);
+EJDB_EXPORT TCLIST *tctdbfwmkeys2(TCTDB *tdb, const char *pstr, int max);
/* Add an integer to a column of a record in a table database object.
If successful, the return value is the summation value, else, it is `INT_MIN'.
The additional value is stored as a decimal string value of a column whose name is "_num".
If no record corresponds, a new record with the additional value is stored. */
-int tctdbaddint(TCTDB *tdb, const void *pkbuf, int pksiz, int num);
+EJDB_EXPORT int tctdbaddint(TCTDB *tdb, const void *pkbuf, int pksiz, int num);
/* Add a real number to a column of a record in a table database object.
If successful, the return value is the summation value, else, it is Not-a-Number.
The additional value is stored as a decimal string value of a column whose name is "_num".
If no record corresponds, a new record with the additional value is stored. */
-double tctdbadddouble(TCTDB *tdb, const void *pkbuf, int pksiz, double num);
+EJDB_EXPORT double tctdbadddouble(TCTDB *tdb, const void *pkbuf, int pksiz, double num);
/* Synchronize updated contents of a table database object with the file and the device.
`tdb' specifies the table database object connected as a writer.
If successful, the return value is true, else, it is false.
This function is useful when another process connects to the same database file. */
-bool tctdbsync(TCTDB *tdb);
+EJDB_EXPORT bool tctdbsync(TCTDB *tdb);
/* Optimize the file of a table database object.
If successful, the return value is true, else, it is false.
This function is useful to reduce the size of the database file with data fragmentation by
successive updating. */
-bool tctdboptimize(TCTDB *tdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
+EJDB_EXPORT bool tctdboptimize(TCTDB *tdb, int64_t bnum, int8_t apow, int8_t fpow, uint8_t opts);
/* Remove all records of a table database object.
`tdb' specifies the table database object connected as a writer.
If successful, the return value is true, else, it is false. */
-bool tctdbvanish(TCTDB *tdb);
+EJDB_EXPORT bool tctdbvanish(TCTDB *tdb);
/* Copy the database file of a table database object.
The database file is assured to be kept synchronized and not modified while the copying or
executing operation is in progress. So, this function is useful to create a backup file of
the database file. */
-bool tctdbcopy(TCTDB *tdb, const char *path);
+EJDB_EXPORT bool tctdbcopy(TCTDB *tdb, const char *path);
/* Begin the transaction of a table database object.
cached on memory while the transaction, the amount of referred records is limited by the
memory capacity. If the database is closed during transaction, the transaction is aborted
implicitly. */
-bool tctdbtranbegin(TCTDB *tdb);
+EJDB_EXPORT bool tctdbtranbegin(TCTDB *tdb);
/* Commit the transaction of a table database object.
`tdb' specifies the table database object connected as a writer.
If successful, the return value is true, else, it is false.
Update in the transaction is fixed when it is committed successfully. */
-bool tctdbtrancommit(TCTDB *tdb);
+EJDB_EXPORT bool tctdbtrancommit(TCTDB *tdb);
/* Abort the transaction of a table database object.
If successful, the return value is true, else, it is false.
Update in the transaction is discarded when it is aborted. The state of the database is
rollbacked to before transaction. */
-bool tctdbtranabort(TCTDB *tdb);
+EJDB_EXPORT bool tctdbtranabort(TCTDB *tdb);
/* Get the file path of a table database object.
`tdb' specifies the table database object.
The return value is the path of the database file or `NULL' if the object does not connect to
any database file. */
-const char *tctdbpath(TCTDB *tdb);
+EJDB_EXPORT const char *tctdbpath(TCTDB *tdb);
/* Get the number of records ccccof a table database object.
`tdb' specifies the table database object.
The return value is the number of records or 0 if the object does not connect to any database
file. */
-uint64_t tctdbrnum(TCTDB *tdb);
+EJDB_EXPORT uint64_t tctdbrnum(TCTDB *tdb);
/* Get the size of the database file of a table database object.
`tdb' specifies the table database object.
The return value is the size of the database file or 0 if the object does not connect to any
database file. */
-uint64_t tctdbfsiz(TCTDB *tdb);
+EJDB_EXPORT uint64_t tctdbfsiz(TCTDB *tdb);
/* Set a column index to a table database object.
`TDBITKEEP' is added by bitwise-or and the index exists, this function merely returns failure.
If successful, the return value is true, else, it is false.
Note that the setting indices should be set after the database is opened. */
-bool tctdbsetindex(TCTDB *tdb, const char *name, int type);
+EJDB_EXPORT bool tctdbsetindex(TCTDB *tdb, const char *name, int type);
-bool tctdbsetindexrldr(TCTDB *tdb, const char *name, int type, TDBRVALOADER rvldr, void* rvldrop);
+EJDB_EXPORT bool tctdbsetindexrldr(TCTDB *tdb, const char *name, int type, TDBRVALOADER rvldr, void* rvldrop);
/* Generate a unique ID number of a table database object.
`tdb' specifies the table database object connected as a writer.
The return value is the new unique ID number or -1 on failure. */
-int64_t tctdbgenuid(TCTDB *tdb);
+EJDB_EXPORT int64_t tctdbgenuid(TCTDB *tdb);
/* Create a query object.
`tdb' specifies the table database object.
The return value is the new query object. */
-TDBQRY *tctdbqrynew(TCTDB *tdb);
+EJDB_EXPORT TDBQRY *tctdbqrynew(TCTDB *tdb);
/* Delete a query object.
`qry' specifies the query object. */
-void tctdbqrydel(TDBQRY *qry);
+EJDB_EXPORT void tctdbqrydel(TDBQRY *qry);
/* Add a narrowing condition to a query object.
full-text search with the compound expression. All operations can be flagged by bitwise-or:
`TDBQCNEGATE' for negation, `TDBQCNOIDX' for using no index.
`expr' specifies an operand exression. */
-void tctdbqryaddcond(TDBQRY *qry, const char *name, int op, const char *expr);
+EJDB_EXPORT void tctdbqryaddcond(TDBQRY *qry, const char *name, int op, const char *expr);
/* Set the order of a query object.
`name' specifies the name of a column. An empty string means the primary key.
`type' specifies the order type: `TDBQOSTRASC' for string ascending, `TDBQOSTRDESC' for
string descending, `TDBQONUMASC' for number ascending, `TDBQONUMDESC' for number descending. */
-void tctdbqrysetorder(TDBQRY *qry, const char *name, int type);
+EJDB_EXPORT void tctdbqrysetorder(TDBQRY *qry, const char *name, int type);
/* Set the limit number of records of the result of a query object.
specified.
`skip' specifies the number of skipped records of the result. If it is not more than 0, no
record is skipped. */
-void tctdbqrysetlimit(TDBQRY *qry, int max, int skip);
+EJDB_EXPORT void tctdbqrysetlimit(TDBQRY *qry, int max, int skip);
/* Execute the search of a query object.
function does never fail. It returns an empty list even if no record corresponds.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tctdbqrysearch(TDBQRY *qry);
+EJDB_EXPORT TCLIST *tctdbqrysearch(TDBQRY *qry);
/* Remove each record corresponding to a query object.
`qry' specifies the query object of the database connected as a writer.
If successful, the return value is true, else, it is false. */
-bool tctdbqrysearchout(TDBQRY *qry);
+EJDB_EXPORT bool tctdbqrysearchout(TDBQRY *qry);
/* Process each record corresponding to a query object.
`op' specifies an arbitrary pointer to be given as a parameter of the iterator function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tctdbqryproc(TDBQRY *qry, TDBQRYPROC proc, void *op);
+EJDB_EXPORT bool tctdbqryproc(TDBQRY *qry, TDBQRYPROC proc, void *op);
/* Get the hint string of a query object.
The return value is the hint string.
This function should be called after the query execution by `tctdbqrysearch' and so on. The
region of the return value is overwritten when this function is called again. */
-const char *tctdbqryhint(TDBQRY *qry);
+EJDB_EXPORT const char *tctdbqryhint(TDBQRY *qry);
/* Retrieve records with multiple query objects and get the set of the result.
If the first query object has the order setting, the result array is sorted by the order.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tctdbmetasearch(TDBQRY **qrys, int num, int type);
+EJDB_EXPORT TCLIST *tctdbmetasearch(TDBQRY **qrys, int num, int type);
`file' specifies the file name of the code.
`line' specifies the line number of the code.
`func' specifies the function name of the code. */
-void tctdbsetecode(TCTDB *tdb, int ecode, const char *filename, int line, const char *func);
+EJDB_EXPORT void tctdbsetecode(TCTDB *tdb, int ecode, const char *filename, int line, const char *func);
/* Set the file descriptor for debugging output.
`tdb' specifies the table database object.
`fd' specifies the file descriptor for debugging output. */
-void tctdbsetdbgfd(TCTDB *tdb, int fd);
+EJDB_EXPORT void tctdbsetdbgfd(TCTDB *tdb, HANDLE fd);
/* Get the file descriptor for debugging output.
`tdb' specifies the table database object.
The return value is the file descriptor for debugging output. */
-int tctdbdbgfd(TCTDB *tdb);
+EJDB_EXPORT HANDLE tctdbdbgfd(TCTDB *tdb);
/* Check whether mutual exclusion control is set to a table database object.
`tdb' specifies the table database object.
If mutual exclusion control is set, it is true, else it is false. */
-bool tctdbhasmutex(TCTDB *tdb);
+EJDB_EXPORT bool tctdbhasmutex(TCTDB *tdb);
/* Synchronize updating contents on memory of a table database object.
`tdb' specifies the table database object.
The return value is the number of elements of the bucket array or 0 if the object does not
connect to any database file. */
-uint64_t tctdbbnum(TCTDB *tdb);
+EJDB_EXPORT uint64_t tctdbbnum(TCTDB *tdb);
/* Get the record alignment of a table database object.
`tdb' specifies the table database object.
The return value is the record alignment or 0 if the object does not connect to any database
file. */
-uint32_t tctdbalign(TCTDB *tdb);
+EJDB_EXPORT uint32_t tctdbalign(TCTDB *tdb);
/* Get the maximum number of the free block pool of a table database object.
`tdb' specifies the table database object.
The return value is the maximum number of the free block pool or 0 if the object does not
connect to any database file. */
-uint32_t tctdbfbpmax(TCTDB *tdb);
+EJDB_EXPORT uint32_t tctdbfbpmax(TCTDB *tdb);
/* Get the inode number of the database file of a table database object.
`tdb' specifies the table database object.
The return value is the inode number of the database file or 0 if the object does not connect
to any database file. */
-uint64_t tctdbinode(TCTDB *tdb);
+EJDB_EXPORT uint64_t tctdbinode(TCTDB *tdb);
/* Get the modification time of the database file of a table database object.
`tdb' specifies the table database object.
The return value is the inode number of the database file or 0 if the object does not connect
to any database file. */
-time_t tctdbmtime(TCTDB *tdb);
+EJDB_EXPORT time_t tctdbmtime(TCTDB *tdb);
/* Get the additional flags of a table database object.
`tdb' specifies the table database object.
The return value is the additional flags. */
-uint8_t tctdbflags(TCTDB *tdb);
+EJDB_EXPORT uint8_t tctdbflags(TCTDB *tdb);
/* Get the options of a table database object.
`tdb' specifies the table database object.
The return value is the options. */
-uint8_t tctdbopts(TCTDB *tdb);
-
-
-/* Get the pointer to the opaque field of a table database object.
- `tdb' specifies the table database object.
- The return value is the pointer to the opaque field whose size is 128 bytes. */
-char *tctdbopaque(TCTDB *tdb);
+EJDB_EXPORT uint8_t tctdbopts(TCTDB *tdb);
/* Get the number of used elements of the bucket array of a table database object.
`tdb' specifies the table database object.
The return value is the number of used elements of the bucket array or 0 if the object does not
connect to any database file. */
-uint64_t tctdbbnumused(TCTDB *tdb);
+EJDB_EXPORT uint64_t tctdbbnumused(TCTDB *tdb);
/* Get the number of column indices of a table database object.
`tdb' specifies the table database object.
The return value is the number of column indices or 0 if the object does not connect to any
database file. */
-int tctdbinum(TCTDB *tdb);
+EJDB_EXPORT int tctdbinum(TCTDB *tdb);
/* Get the seed of unique ID unumbers of a table database object.
`tdb' specifies the table database object.
The return value is the seed of unique ID numbers or -1 on failure. */
-int64_t tctdbuidseed(TCTDB *tdb);
+EJDB_EXPORT int64_t tctdbuidseed(TCTDB *tdb);
/* Set the seed of unique ID unumbers of a table database object.
`tdb' specifies the table database object connected as a writer.
If successful, the return value is true, else, it is false. */
-bool tctdbsetuidseed(TCTDB *tdb, int64_t seed);
+EJDB_EXPORT bool tctdbsetuidseed(TCTDB *tdb, int64_t seed);
/* Set the parameters of the inverted cache of a table database object.
specified. The default value is 0.01.
If successful, the return value is true, else, it is false.
Note that the caching parameters should be set before the database is opened. */
-bool tctdbsetinvcache(TCTDB *tdb, int64_t iccmax, double iccsync);
+EJDB_EXPORT bool tctdbsetinvcache(TCTDB *tdb, int64_t iccmax, double iccsync);
/* Set the custom codec functions of a table database object.
If successful, the return value is true, else, it is false.
Note that the custom codec functions should be set before the database is opened and should be
set every time the database is being opened. */
-bool tctdbsetcodecfunc(TCTDB *tdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop);
+EJDB_EXPORT bool tctdbsetcodecfunc(TCTDB *tdb, TCCODEC enc, void *encop, TCCODEC dec, void *decop);
/* Get the unit step number of auto defragmentation of a table database object.
`tdb' specifies the table database object.
The return value is the unit step number of auto defragmentation. */
-uint32_t tctdbdfunit(TCTDB *tdb);
+EJDB_EXPORT uint32_t tctdbdfunit(TCTDB *tdb);
/* Perform dynamic defragmentation of a table database object.
`step' specifie the number of steps. If it is not more than 0, the whole file is defragmented
gradually without keeping a continuous lock.
If successful, the return value is true, else, it is false. */
-bool tctdbdefrag(TCTDB *tdb, int64_t step);
+EJDB_EXPORT bool tctdbdefrag(TCTDB *tdb, int64_t step);
/* Clear the cache of a table tree database object.
`tdb' specifies the table tree database object.
If successful, the return value is true, else, it is false. */
-bool tctdbcacheclear(TCTDB *tdb);
+EJDB_EXPORT bool tctdbcacheclear(TCTDB *tdb);
/* Store a record into a table database object with a duplication handler.
If successful, the return value is true, else, it is false.
Note that the callback function can not perform any database operation because the function
is called in the critical section guarded by the same locks of database operations. */
-bool tctdbputproc(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz,
+EJDB_EXPORT bool tctdbputproc(TCTDB *tdb, const void *pkbuf, int pksiz, const void *cbuf, int csiz,
TCPDPROC proc, void *op);
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-char *tctdbget4(TCTDB *tdb, const void *pkbuf, int pksiz, const void *nbuf, int nsiz, int *sp);
+EJDB_EXPORT char *tctdbget4(TCTDB *tdb, const void *pkbuf, int pksiz, const void *nbuf, int nsiz, int *sp);
/* Move the iterator to the record corresponding a key of a table database object.
`pksiz' specifies the size of the region of the primary key.
If successful, the return value is true, else, it is false. False is returned if there is
no record corresponding the condition. */
-bool tctdbiterinit2(TCTDB *tdb, const void *pkbuf, int pksiz);
+EJDB_EXPORT bool tctdbiterinit2(TCTDB *tdb, const void *pkbuf, int pksiz);
/* Move the iterator to the record corresponding a key string of a table database object.
`kstr' specifies the string of the primary key.
If successful, the return value is true, else, it is false. False is returned if there is
no record corresponding the condition. */
-bool tctdbiterinit3(TCTDB *tdb, const char *kstr);
+EJDB_EXPORT bool tctdbiterinit3(TCTDB *tdb, const char *kstr);
/* Process each record atomically of a table database object.
If successful, the return value is true, else, it is false.
Note that the callback function can not perform any database operation because the function
is called in the critical section guarded by the same locks of database operations. */
-bool tctdbforeach(TCTDB *tdb, TCITER iter, void *op);
+EJDB_EXPORT bool tctdbforeach(TCTDB *tdb, TCITER iter, void *op);
/* Process each record corresponding to a query object with non-atomic fashion.
`op' specifies an arbitrary pointer to be given as a parameter of the iterator function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tctdbqryproc2(TDBQRY *qry, TDBQRYPROC proc, void *op);
+EJDB_EXPORT bool tctdbqryproc2(TDBQRY *qry, TDBQRYPROC proc, void *op);
/* Remove each record corresponding to a query object with non-atomic fashion.
`qry' specifies the query object of the database connected as a writer.
If successful, the return value is true, else, it is false. */
-bool tctdbqrysearchout2(TDBQRY *qry);
+EJDB_EXPORT bool tctdbqrysearchout2(TDBQRY *qry);
/* Convert a string into the index type number.
`str' specifies a string.
The return value is the index type number or -1 on failure. */
-int tctdbstrtoindextype(const char *str);
+EJDB_EXPORT int tctdbstrtoindextype(const char *str);
/* Convert a string into the meta search type number.
`str' specifies a string.
The return value is the meta search type number or -1 on failure. */
-int tctdbstrtometasearcytype(const char *str);
+EJDB_EXPORT int tctdbstrtometasearcytype(const char *str);
/* Get the count of corresponding records of a query object.
`qry' specifies the query object.
The return value is the count of corresponding records. */
-int tctdbqrycount(TDBQRY *qry);
+EJDB_EXPORT int tctdbqrycount(TDBQRY *qry);
/* Generate keyword-in-context strings from a query object.
The return value is the list object whose elements are strings around keywords.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tctdbqrykwic(TDBQRY *qry, TCMAP *cols, const char *name, int width, int opts);
+EJDB_EXPORT TCLIST *tctdbqrykwic(TDBQRY *qry, TCMAP *cols, const char *name, int width, int opts);
/* Convert a string into the query operation number.
`str' specifies a string.
The return value is the query operation number or -1 on failure. */
-int tctdbqrystrtocondop(const char *str);
+EJDB_EXPORT int tctdbqrystrtocondop(const char *str);
/* Convert a string into the query order type number.
`str' specifies a string.
The return value is the query order type or -1 on failure. */
-int tctdbqrystrtoordertype(const char *str);
+EJDB_EXPORT int tctdbqrystrtoordertype(const char *str);
/* Convert a string into the set operation type number.
`str' specifies a string.
The return value is the set operation type or -1 on failure. */
-int tctdbmetastrtosettype(const char *str);
+EJDB_EXPORT int tctdbmetastrtosettype(const char *str);
/* Add a record into indices of a table database object.
TCMAP *tctdbidxgetbytokens(TCTDB *tdb, const TDBIDX *idx, const TCLIST *tokens, int op, TCXSTR *hint);
bool tctdbtranbeginimpl(TCTDB *tdb);
+
bool tctdbtrancommitimpl(TCTDB *tdb);
+
bool tctdbtranabortimpl(TCTDB *tdb);
#define TDBDEFBNUM 131071 // default bucket number
/* global variables */
const char *g_progname; // program name
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
/* main routine */
int main(int argc, char **argv){
g_progname = argv[0];
- g_dbgfd = -1;
+ g_dbgfd = INVALID_HANDLE_VALUE;
const char *ebuf = getenv("TCDBGFD");
- if(ebuf) g_dbgfd = tcatoix(ebuf);
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "create")){
/* perform create command */
static int proccreate(const char *path, int bnum, int apow, int fpow, int opts){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
if(!tctdbtune(tdb, bnum, apow, fpow, opts)){
printerr(tdb);
/* perform inform command */
static int procinform(const char *path, int omode){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL);
if(!tctdbopen(tdb, path, TDBOREADER | omode)){
printerr(tdb);
if(flags & TDBFOPEN) printf(" open");
if(flags & TDBFFATAL) printf(" fatal");
printf("\n");
- printf("bucket number: %llu\n", (unsigned long long)tctdbbnum(tdb));
+ printf("bucket number: %" PRIuMAX "\n", (unsigned long long)tctdbbnum(tdb));
if(tdb->hdb->cnt_writerec >= 0)
- printf("used bucket number: %lld\n", (long long)tctdbbnumused(tdb));
+ printf("used bucket number: %" PRIdMAX "\n", (long long)tctdbbnumused(tdb));
printf("alignment: %u\n", tctdbalign(tdb));
printf("free block pool: %u\n", tctdbfbpmax(tdb));
printf("index number: %d\n", tctdbinum(tdb));
TDBIDX *idxp = idxs + i;
switch(idxp->type){
case TDBITLEXICAL:
- printf(" name=%s, type=lexical, rnum=%lld, fsiz=%lld\n",
+ printf(" name=%s, type=lexical, rnum=%" PRIdMAX ", fsiz=%" PRIdMAX "\n",
idxp->name, (long long)tcbdbrnum(idxp->db), (long long)tcbdbfsiz(idxp->db));
break;
case TDBITDECIMAL:
- printf(" name=%s, type=decimal, rnum=%lld, fsiz=%lld\n",
+ printf(" name=%s, type=decimal, rnum=%" PRIdMAX ", fsiz=%" PRIdMAX "\n",
idxp->name, (long long)tcbdbrnum(idxp->db), (long long)tcbdbfsiz(idxp->db));
break;
case TDBITTOKEN:
- printf(" name=%s, type=token, rnum=%lld, fsiz=%lld\n",
+ printf(" name=%s, type=token, rnum=%" PRIdMAX ", fsiz=%" PRIdMAX "\n",
idxp->name, (long long)tcbdbrnum(idxp->db), (long long)tcbdbfsiz(idxp->db));
break;
case TDBITQGRAM:
- printf(" name=%s, type=qgram, rnum=%lld, fsiz=%lld\n",
+ printf(" name=%s, type=qgram, rnum=%" PRIdMAX ", fsiz=%" PRIdMAX "\n",
idxp->name, (long long)tcbdbrnum(idxp->db), (long long)tcbdbfsiz(idxp->db));
break;
}
}
- printf("unique ID seed: %lld\n", (long long)tctdbuidseed(tdb));
- printf("inode number: %lld\n", (long long)tctdbinode(tdb));
+ printf("unique ID seed: %" PRIdMAX "\n", (long long)tctdbuidseed(tdb));
+ printf("inode number: %" PRIdMAX "\n", (long long)tctdbinode(tdb));
char date[48];
tcdatestrwww(tctdbmtime(tdb), INT_MAX, date);
printf("modified time: %s\n", date);
if(opts & TDBTTCBS) printf(" tcbs");
if(opts & TDBTEXCODEC) printf(" excodec");
printf("\n");
- printf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- printf("file size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ printf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ printf("file size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
if(!tctdbclose(tdb)){
if(!err) printerr(tdb);
err = true;
static int procput(const char *path, const char *pkbuf, int pksiz, TCMAP *cols,
int omode, int dmode){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
if(!tctdbopen(tdb, path, TDBOWRITER | omode)){
printerr(tdb);
bool err = false;
char pknumbuf[TCNUMBUFSIZ];
if(pksiz < 1){
- pksiz = sprintf(pknumbuf, "%lld", (long long)tctdbgenuid(tdb));
+ pksiz = sprintf(pknumbuf, "%" PRIdMAX "", (long long)tctdbgenuid(tdb));
pkbuf = pknumbuf;
}
const char *vbuf;
/* perform out command */
static int procout(const char *path, const char *pkbuf, int pksiz, int omode){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
if(!tctdbopen(tdb, path, TDBOWRITER | omode)){
printerr(tdb);
/* perform get command */
static int procget(const char *path, const char *pkbuf, int pksiz, int omode, bool px, bool pz){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
if(!tctdbopen(tdb, path, TDBOREADER | omode)){
printerr(tdb);
/* perform list command */
static int proclist(const char *path, int omode, int max, bool pv, bool px, const char *fmstr){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
if(!tctdbopen(tdb, path, TDBOREADER | omode)){
printerr(tdb);
int omode, int max, int skip, bool pv, bool px, bool kw, bool ph, int bt,
bool rm, const char *mtype){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
if(!tctdbopen(tdb, path, (rm ? TDBOWRITER : TDBOREADER) | omode)){
printerr(tdb);
static int procoptimize(const char *path, int bnum, int apow, int fpow, int opts, int omode,
bool df){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
int64_t msiz = 0;
TCMAP *info = tcsysinfo();
/* perform setindex command */
static int procsetindex(const char *path, const char *name, int omode, int type){
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
int64_t msiz = 0;
TCMAP *info = tcsysinfo();
return 1;
}
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetcodecfunc(tdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(tdb);
int64_t msiz = 0;
TCMAP *info = tcsysinfo();
if(sc) tcstrutfnorm(line, TCUNSPACE | TCUNLOWER | TCUNNOACC | TCUNWIDTH);
const char *pkey;
if(*line == '\0'){
- sprintf(numbuf, "%lld", (long long)tctdbgenuid(tdb));
+ sprintf(numbuf, "%" PRIdMAX "", (long long)tctdbgenuid(tdb));
pkey = numbuf;
} else {
pkey = line;
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(!tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
}
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
/* global variables */
const char *g_progname; // program name
unsigned int g_randseed; // random seed
-int g_dbgfd; // debugging output
+HANDLE g_dbgfd; // debugging output
/* function prototypes */
g_randseed = ebuf ? tcatoix(ebuf) : tctime() * 1000;
srand(g_randseed);
ebuf = getenv("TCDBGFD");
- g_dbgfd = ebuf ? tcatoix(ebuf) : UINT16_MAX;
+ if (ebuf) {
+ int debugfd = tcatoix(ebuf);
+#ifdef _WIN32
+ g_dbgfd = (HANDLE) _get_osfhandle(debugfd);
+#else
+ g_dbgfd = debugfd;
+#endif
+ }
if(argc < 2) usage();
int rv = 0;
if(!strcmp(argv[1], "write")){
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(mt && !tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(mt && !tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(mt && !tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(mt && !tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
if(i == rnum || i % (rnum / 10) == 0) iprintf(" (%08d)\n", i);
}
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(mt && !tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
eprint(tdb, __LINE__, "tctdbsetindex");
err = true;
}
- if(TCUSEPTHREAD){
+ if(1){
TCTDB *tdbdup = tctdbnew();
if(tctdbopen(tdbdup, path, TDBOREADER)){
eprint(tdb, __LINE__, "(validation)");
eprint(tdb, __LINE__, "tctdbforeach");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
bool err = false;
double stime = tctime();
TCTDB *tdb = tctdbnew();
- if(g_dbgfd >= 0) tctdbsetdbgfd(tdb, g_dbgfd);
+ if(!INVALIDHANDLE(g_dbgfd)) tctdbsetdbgfd(tdb, g_dbgfd);
if(mt && !tctdbsetmutex(tdb)){
eprint(tdb, __LINE__, "tctdbsetmutex");
err = true;
eprint(tdb, __LINE__, "tctdbsync");
err = true;
}
- iprintf("record number: %llu\n", (unsigned long long)tctdbrnum(tdb));
- iprintf("size: %llu\n", (unsigned long long)tctdbfsiz(tdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctdbrnum(tdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctdbfsiz(tdb));
sysprint();
if(!tctdbclose(tdb)){
eprint(tdb, __LINE__, "tctdbclose");
tcdatestrhttp(t, jl, buf);
printf("%s\n", buf);
} else {
- printf("%lld\n", (long long int)t);
+ printf("%" PRIdMAX "\n", (long long int)t);
}
return 0;
}
printf("myconf(bigend): %d\n", TCBIGEND);
printf("myconf(usezlib): %d\n", TCUSEZLIB);
printf("myconf(usebzip): %d\n", TCUSEBZIP);
- printf("type(bool): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(bool): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(bool), (int)_alignof(bool), TCALIGNOF(bool),
(unsigned long long)true);
- printf("type(char): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(char): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(char), (int)_alignof(char), TCALIGNOF(char),
(unsigned long long)CHAR_MAX);
- printf("type(short): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(short): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(short), (int)_alignof(short), TCALIGNOF(short),
(unsigned long long)SHRT_MAX);
- printf("type(int): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(int): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(int), (int)_alignof(int), TCALIGNOF(int),
(unsigned long long)INT_MAX);
- printf("type(long): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(long): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(long), (int)_alignof(long), TCALIGNOF(long),
(unsigned long long)LONG_MAX);
- printf("type(long long): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(long long): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(long long), (int)_alignof(long long), TCALIGNOF(long long),
(unsigned long long)LLONG_MAX);
printf("type(float): size=%d align=%d offset=%d max=%g\n",
(long double)LDBL_MAX);
printf("type(void *): size=%d align=%d offset=%d\n",
(int)sizeof(void *), (int)_alignof(void *), TCALIGNOF(void *));
- printf("type(intptr_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(intptr_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(intptr_t), (int)_alignof(intptr_t), TCALIGNOF(intptr_t),
(unsigned long long)INTPTR_MAX);
- printf("type(size_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(size_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(size_t), (int)_alignof(size_t), TCALIGNOF(size_t),
(unsigned long long)SIZE_MAX);
- printf("type(ptrdiff_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(ptrdiff_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(ptrdiff_t), (int)_alignof(ptrdiff_t), TCALIGNOF(ptrdiff_t),
(unsigned long long)PTRDIFF_MAX);
- printf("type(wchar_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(wchar_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(wchar_t), (int)_alignof(wchar_t), TCALIGNOF(wchar_t),
(unsigned long long)WCHAR_MAX);
- printf("type(sig_atomic_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(sig_atomic_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(sig_atomic_t), (int)_alignof(sig_atomic_t), TCALIGNOF(sig_atomic_t),
(unsigned long long)SIG_ATOMIC_MAX);
- printf("type(time_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(time_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(time_t), (int)_alignof(time_t), TCALIGNOF(time_t),
(unsigned long long)_maxof(time_t));
- printf("type(off_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(off_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(off_t), (int)_alignof(off_t), TCALIGNOF(off_t),
(unsigned long long)_maxof(off_t));
- printf("type(ino_t): size=%d align=%d offset=%d max=%llu\n",
+ printf("type(ino_t): size=%d align=%d offset=%d max=%" PRIuMAX "\n",
(int)sizeof(ino_t), (int)_alignof(ino_t), TCALIGNOF(ino_t),
(unsigned long long)_maxof(ino_t));
printf("type(tcgeneric_t): size=%d align=%d offset=%d\n",
(int)sizeof(tcgeneric_t), (int)_alignof(tcgeneric_t), TCALIGNOF(tcgeneric_t));
- printf("macro(RAND_MAX): %llu\n", (unsigned long long)RAND_MAX);
- printf("macro(PATH_MAX): %llu\n", (unsigned long long)PATH_MAX);
- printf("macro(NAME_MAX): %llu\n", (unsigned long long)NAME_MAX);
+ printf("macro(RAND_MAX): %" PRIuMAX "\n", (unsigned long long)RAND_MAX);
+ printf("macro(PATH_MAX): %" PRIuMAX "\n", (unsigned long long)PATH_MAX);
+ printf("macro(NAME_MAX): %" PRIuMAX "\n", (unsigned long long)NAME_MAX);
+#ifndef _WIN32
printf("macro(P_tmpdir): %s\n", P_tmpdir);
- printf("sysconf(_SC_CLK_TCK): %ld\n", sysconf(_SC_CLK_TCK));
printf("sysconf(_SC_OPEN_MAX): %ld\n", sysconf(_SC_OPEN_MAX));
- printf("sysconf(_SC_PAGESIZE): %ld\n", sysconf(_SC_PAGESIZE));
+#endif
+ printf("sysconf(_SC_CLK_TCK): %ld\n", sysconf_SC_CLK_TCK);
+ printf("sysconf(_SC_PAGESIZE): %ld\n", tcpagsize());
TCMAP *info = tcsysinfo();
if(info){
tcmapiterinit(info);
if(stat(MYCDIRSTR, &sbuf) == 0){
printf("stat(st_uid): %d\n", (int)sbuf.st_uid);
printf("stat(st_gid): %d\n", (int)sbuf.st_gid);
+#ifndef _WIN32
printf("stat(st_blksize): %d\n", (int)sbuf.st_blksize);
+#endif
}
}
return 0;
}
}
if(tr){
- iprintf("record number: %llu\n", (unsigned long long)tcndbrnum(ndb));
- iprintf("size: %llu\n", (unsigned long long)tcndbmsiz(ndb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcndbrnum(ndb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcndbmsiz(ndb));
} else {
- iprintf("record number: %llu\n", (unsigned long long)tcmdbrnum(mdb));
- iprintf("size: %llu\n", (unsigned long long)tcmdbmsiz(mdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcmdbrnum(mdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcmdbmsiz(mdb));
}
tcndbdel(ndb);
tcmdbdel(mdb);
}
}
if(tr){
- iprintf("record number: %llu\n", (unsigned long long)tcndbrnum(ndb));
- iprintf("size: %llu\n", (unsigned long long)tcndbmsiz(ndb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcndbrnum(ndb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcndbmsiz(ndb));
} else {
- iprintf("record number: %llu\n", (unsigned long long)tcmdbrnum(mdb));
- iprintf("size: %llu\n", (unsigned long long)tcmdbmsiz(mdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcmdbrnum(mdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcmdbmsiz(mdb));
}
tcndbdel(ndb);
tcmdbdel(mdb);
}
if(rnd && rnum > 250) iprintf(" (%08d)\n", inum);
}
- iprintf("record number: %llu\n", (unsigned long long)tcmaprnum(map));
- iprintf("size: %llu\n", (unsigned long long)tcmapmsiz(map));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcmaprnum(map));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcmapmsiz(map));
sysprint();
tcmapdel(map);
iprintf("time: %.3f\n", tctime() - stime);
}
if(rnd && rnum > 250) iprintf(" (%08d)\n", inum);
}
- iprintf("record number: %llu\n", (unsigned long long)tctreernum(tree));
- iprintf("size: %llu\n", (unsigned long long)tctreemsiz(tree));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tctreernum(tree));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tctreemsiz(tree));
sysprint();
tctreedel(tree);
iprintf("time: %.3f\n", tctime() - stime);
}
if(rnd && rnum > 250) iprintf(" (%08d)\n", inum);
}
- iprintf("record number: %llu\n", (unsigned long long)tcmdbrnum(mdb));
- iprintf("size: %llu\n", (unsigned long long)tcmdbmsiz(mdb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcmdbrnum(mdb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcmdbmsiz(mdb));
sysprint();
tcmdbdel(mdb);
iprintf("time: %.3f\n", tctime() - stime);
}
if(rnd && rnum > 250) iprintf(" (%08d)\n", inum);
}
- iprintf("record number: %llu\n", (unsigned long long)tcndbrnum(ndb));
- iprintf("size: %llu\n", (unsigned long long)tcndbmsiz(ndb));
+ iprintf("record number: %" PRIuMAX "\n", (unsigned long long)tcndbrnum(ndb));
+ iprintf("size: %" PRIuMAX "\n", (unsigned long long)tcndbmsiz(ndb));
sysprint();
tcndbdel(ndb);
iprintf("time: %.3f\n", tctime() - stime);
buf = tczeromap(myrand(1024*256) + 1);
tczerounmap(buf);
}
- buf = tcmalloc(48);
+ buf = tcmalloc(64);
date = myrand(INT_MAX - 1000000);
jl = 3600 * (myrand(23) - 11);
tcdatestrwww(date, jl, buf);
#include "myconf.h"
#include "md5.h"
+#ifdef _WIN32
+#include <wincrypt.h>
+#endif
/*************************************************************************************************
int cblen = 1;
int lnum = 0;
format++;
- while(strchr("0123456789 .+-hlLz", *format) && *format != '\0' &&
+ while(strchr("0123456789 .+-hlLzI", *format) && *format != '\0' &&
cblen < TCNUMBUFSIZ - 1){
- if(*format == 'l' || *format == 'L') lnum++;
+ if(*format == 'l' || *format == 'L') {
+ lnum++;
+ } else if (*format == 'I' && *(format + 1) == '6' && *(format + 2) == '4') {
+ lnum += 2;
+ }
cbuf[cblen++] = *(format++);
}
cbuf[cblen++] = *format;
return -1;
}
-
/* Perform formatted output into a map object. */
void tcmapprintf(TCMAP *map, const char *kstr, const char *format, ...){
assert(map && kstr && format);
/* Clear an on-memory tree database object. */
void tcndbvanish(TCNDB *ndb){
assert(ndb);
- if(pthread_mutex_lock((pthread_mutex_t *)ndb->mmtx) != 0);
+ if (pthread_mutex_lock((pthread_mutex_t *)ndb->mmtx) != 0) return;
tctreeclear(ndb->tree);
pthread_mutex_unlock((pthread_mutex_t *)ndb->mmtx);
}
/* Remove fringe records of an on-memory tree database object. */
void tcndbcutfringe(TCNDB *ndb, int num){
assert(ndb && num >= 0);
- if(pthread_mutex_lock((pthread_mutex_t *)ndb->mmtx) != 0);
+ if (pthread_mutex_lock((pthread_mutex_t *)ndb->mmtx) != 0) return;
tctreecutfringe(ndb->tree, num);
pthread_mutex_unlock((pthread_mutex_t *)ndb->mmtx);
}
*************************************************************************************************/
-#define TCRANDDEV "/dev/urandom" // path of the random device file
+
#define TCDISTMAXLEN 4096 // maximum size of a string for distance checking
#define TCDISTBUFSIZ 16384 // size of a distance buffer
#define TCLDBLCOLMAX 16 // maximum number of columns of the long double
-
-/* File descriptor of random number generator. */
-int tcrandomdevfd = -1;
-
-
/* private function prototypes */
static void tcrandomfdclose(void);
static time_t tcmkgmtime(struct tm *tm);
return (a < b) ? a : b;
}
-
+#ifndef _WIN32
+#define TCRANDDEV "/dev/urandom" // path of the random device file
+/* File descriptor of random number generator. */
+int tcrandomdevfd = -1;
/* Get a random number as long integer based on uniform distribution. */
unsigned long tclrand(void){
static uint32_t cnt = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
if((cnt & 0xff) == 0 && pthread_mutex_lock(&mutex) == 0){
if(cnt == 0) seed += time(NULL);
- if(tcrandomdevfd == -1 && (tcrandomdevfd = open(TCRANDDEV, O_RDONLY, 00644)) != -1)
+ if(tcrandomdevfd == -1 && (tcrandomdevfd = open(TCRANDDEV, O_RDONLY, 00644)) != -1) {
atexit(tcrandomfdclose);
+ }
if(tcrandomdevfd == -1 || read(tcrandomdevfd, &mask, sizeof(mask)) != sizeof(mask)){
double t = tctime();
uint64_t tmask;
return TCSWAB64(num);
}
+/* Close the random number generator. */
+static void tcrandomfdclose(void){
+ close(tcrandomdevfd);
+}
+#else
+static HCRYPTPROV hcprov = 0;
+unsigned long tclrand(void) {
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ static bool acquired = false;
+ static uint32_t cnt = 0;
+ static uint64_t seed = 0;
+ static uint64_t mask = 0;
+ uint64_t num = 0;
+ if ((cnt & 0xff) == 0 && pthread_mutex_lock(&mutex) == 0) {
+ if(cnt == 0) seed += time(NULL);
+ if (!hcprov) {
+ if (!CryptAcquireContext(&hcprov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
+ hcprov = 0;
+ }
+ if (!acquired) {
+ acquired = true;
+ atexit(tcrandomfdclose);
+ }
+ if (!hcprov || !CryptGenRandom(hcprov, sizeof (mask), (PBYTE) &mask)) {
+ double t = tctime();
+ uint64_t tmask;
+ memcpy(&tmask, &t, tclmin(sizeof (t), sizeof (tmask)));
+ mask = (mask << 8) ^ tmask;
+ }
+ }
+ pthread_mutex_unlock(&mutex);
+ }
+ seed = seed * 123456789012301LL + 211;
+ num = (mask ^ cnt++) ^ seed;
+ return TCSWAB64(num);
+}
+static void tcrandomfdclose(void){
+ if (hcprov) {
+ CryptReleaseContext(hcprov, 0);
+ hcprov = 0;
+ }
+}
+#endif
+
/* Get a random number as double decimal based on uniform distribution. */
double tcdrand(void){
/* Get the time of day in seconds. */
double tctime(void){
struct timeval tv;
- if(gettimeofday(&tv, NULL) == -1) return 0.0;
+ if(gettimeofday(&tv, NULL)) return 0.0;
return (double)tv.tv_sec + (double)tv.tv_usec / 1000000.0;
}
/* Get time in milleconds since Epoch. */
unsigned long tcmstime(void) {
struct timeval tv;
- if(gettimeofday(&tv, NULL) == -1) return 0;
+ if(gettimeofday(&tv, NULL)) return 0;
return (unsigned long long) (tv.tv_sec) * 1000 + (unsigned long long) (tv.tv_usec) / 1000;
}
-
/* Get the Gregorian calendar of a time. */
void tccalendar(int64_t t, int jl, int *yearp, int *monp, int *dayp,
int *hourp, int *minp, int *secp){
}
-/* Close the random number generator. */
-static void tcrandomfdclose(void){
- close(tcrandomdevfd);
-}
-
/* Make the GMT from a time structure.
`tm' specifies the pointer to the time structure.
return isnum && (*str == '\0' || len == 0);
}
-
/* Convert a hexadecimal string to an integer. */
int64_t tcatoih(const char *str){
assert(str);
TCMALLOC(tbuf, ti * 5 + 1);
int wi = 0;
wi += tcstrutfkwicputtext(oary, nary, 0, ti, nanum, tbuf + wi, uwords, opts);
- if(!(opts & TCKWNOOVER) && opts & TCKWMUTAB){
+ if(!(opts & TCKWNOOVER) && (opts & TCKWMUTAB)){
tbuf[wi++] = '\t';
tbuf[wi++] = '\t';
}
/* Suspend execution of the current thread. */
bool tcsleep(double sec){
if(!isnormal(sec) || sec <= 0.0) return false;
- if(sec <= 1.0 / sysconf(_SC_CLK_TCK)) return sched_yield() == 0;
+#ifdef _WIN32
+ Sleep(sec * 1000);
+#else
+ if(sec <= 1.0 / sysconf_SC_CLK_TCK) return sched_yield() == 0;
double integ, fract;
fract = modf(sec, &integ);
struct timespec req, rem;
if(errno != EINTR) return false;
req = rem;
}
+#endif
return true;
}
}
if(tcstrifwm(line, "VmSize:")){
int64_t size = tcatoix(rp);
- if(size > 0) tcmapprintf(info, "size", "%lld", (long long)size);
+ if(size > 0) tcmapprintf(info, "size", "%" PRIdMAX "", (long long)size);
} else if(tcstrifwm(line, "VmRSS:")){
int64_t size = tcatoix(rp);
- if(size > 0) tcmapprintf(info, "rss", "%lld", (long long)size);
+ if(size > 0) tcmapprintf(info, "rss", "%" PRIdMAX "", (long long)size);
}
}
tclistdel(lines);
}
if(tcstrifwm(line, "MemTotal:")){
int64_t size = tcatoix(rp);
- if(size > 0) tcmapprintf(info, "total", "%lld", (long long)size);
+ if(size > 0) tcmapprintf(info, "total", "%" PRIdMAX "", (long long)size);
} else if(tcstrifwm(line, "MemFree:")){
int64_t size = tcatoix(rp);
- if(size > 0) tcmapprintf(info, "free", "%lld", (long long)size);
+ if(size > 0) tcmapprintf(info, "free", "%" PRIdMAX "", (long long)size);
} else if(tcstrifwm(line, "Cached:")){
int64_t size = tcatoix(rp);
- if(size > 0) tcmapprintf(info, "cached", "%lld", (long long)size);
+ if(size > 0) tcmapprintf(info, "cached", "%" PRIdMAX "", (long long)size);
}
}
tclistdel(lines);
const char *line = TCLISTVALPTR(lines, i);
if(tcstrifwm(line, "processor")) cnum++;
}
- if(cnum > 0) tcmapprintf(info, "corenum", "%lld", (long long)cnum);
+ if(cnum > 0) tcmapprintf(info, "corenum", "%" PRIdMAX "", (long long)cnum);
tclistdel(lines);
}
return info;
rbuf.ru_utime.tv_sec + rbuf.ru_utime.tv_usec / 1000000.0);
tcmapprintf(info, "stime", "%0.6f",
rbuf.ru_stime.tv_sec + rbuf.ru_stime.tv_usec / 1000000.0);
- long tck = sysconf(_SC_CLK_TCK);
+ long tck = sysconf_SC_CLK_TCK;
int64_t size = (((double)rbuf.ru_ixrss + rbuf.ru_idrss + rbuf.ru_isrss) / tck) * 1024.0;
- if(size > 0) tcmapprintf(info, "rss", "%lld", (long long)size);
+ if(size > 0) tcmapprintf(info, "rss", "%" PRIdMAX "", (long long)size);
+ }
+ return info;
+#elif defined(_WIN32)
+ TCMAP *info = tcmapnew2(TCMAPTINYBNUM);
+ FILETIME creat, exit, kernel, user;
+ ULARGE_INTEGER largetime;
+ if (GetProcessTimes(GetCurrentProcess(), &creat, &exit, &kernel, &user)){
+ largetime.LowPart = user.dwLowDateTime;
+ largetime.HighPart = user.dwHighDateTime;
+ tcmapprintf(info, "utime", "%0.6f", largetime.QuadPart / 10000000.0);
+ largetime.LowPart = kernel.dwLowDateTime;
+ largetime.HighPart = kernel.dwHighDateTime;
+ tcmapprintf(info, "stime", "%0.6f", largetime.QuadPart / 10000000.0);
}
return info;
#else
#define TCFILEMODE 00644 // permission of a creating file
+#ifdef _WIN32
+#define TCIOBUFSIZ 65536 // size of an I/O buffer
+#else
#define TCIOBUFSIZ 16384 // size of an I/O buffer
+#endif
+
/* Get the canonicalized absolute path of a file. */
+#ifndef _WIN32
char *tcrealpath(const char *path){
assert(path);
char buf[PATH_MAX+1];
}
return NULL;
}
+#else
+char *tcrealpath(const char *path) {
+ char *ret = _fullpath(NULL, path, _MAX_PATH);
+ if (!ret) {
+ SetLastError(ERROR_INVALID_ACCESS);
+ return NULL;
+ }
+ return ret;
+}
+#endif
/* Get the status information of a file. */
/* Read whole data of a file. */
-void *tcreadfile(const char *path, int limit, int *sp){
- int fd = path ? open(path, O_RDONLY, TCFILEMODE) : 0;
- if(fd == -1) return NULL;
- if(fd == 0){
- TCXSTR *xstr = tcxstrnew();
- char buf[TCIOBUFSIZ];
- limit = limit > 0 ? limit : INT_MAX;
+void *tcreadfile(const char *path, int limit, int *sp) {
+ HANDLE fd;
+ if (path) {
+#ifndef _WIN32
+ fd = open(path, O_RDONLY, TCFILEMODE);
+#else
+ fd = CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ } else {
+ fd = GET_STDIN_HANDLE();
+ }
+ if (INVALIDHANDLE(fd)) {
+ return NULL;
+ }
+ if (path == NULL) { //stdin
+ TCXSTR *xstr = tcxstrnew();
+ char buf[TCIOBUFSIZ];
+ limit = limit > 0 ? limit : INT_MAX;
+ int rsiz;
+
+ while (1) {
+#ifndef _WIN32
+ rsiz = read(fd, buf, tclmin(TCIOBUFSIZ, limit));
+#else
+ DWORD red;
+ if (!ReadFile(fd, buf, tclmin(TCIOBUFSIZ, limit), &red, NULL)) {
+ rsiz = -1;
+ } else {
+ rsiz = red;
+ }
+#endif
+ if (rsiz <= 0) {
+ break;
+ }
+ TCXSTRCAT(xstr, buf, rsiz);
+ limit -= rsiz;
+ }
+ if (sp) *sp = TCXSTRSIZE(xstr);
+ return tcxstrtomalloc(xstr);
+ }
+ struct stat sbuf;
+ if (fstat(fd, &sbuf) || !S_ISREG(sbuf.st_mode)) {
+ CLOSEFH(fd);
+ return NULL;
+ }
+ limit = (limit > 0) ? tclmin((int) sbuf.st_size, limit) : sbuf.st_size;
+ char *buf;
+ TCMALLOC(buf, limit + 1);
+ char *wp = buf;
int rsiz;
- while((rsiz = read(fd, buf, tclmin(TCIOBUFSIZ, limit))) > 0){
- TCXSTRCAT(xstr, buf, rsiz);
- limit -= rsiz;
+ while (1) {
+#ifndef _WIN32
+ rsiz = read(fd, wp, limit - (wp - buf)));
+#else
+ DWORD red;
+ if (!ReadFile(fd, wp, limit - (wp - buf), &red, NULL)) {
+ rsiz = -1;
+ } else {
+ rsiz = red;
+ }
+#endif
+ if (rsiz <= 0) {
+ break;
+ }
+ wp += rsiz;
}
- if(sp) *sp = TCXSTRSIZE(xstr);
- return tcxstrtomalloc(xstr);
- }
- struct stat sbuf;
- if(fstat(fd, &sbuf) == -1 || !S_ISREG(sbuf.st_mode)){
- close(fd);
- return NULL;
- }
- limit = limit > 0 ? tclmin((int)sbuf.st_size, limit) : sbuf.st_size;
- char *buf;
- TCMALLOC(buf, sbuf.st_size + 1);
- char *wp = buf;
- int rsiz;
- while((rsiz = read(fd, wp, limit - (wp - buf))) > 0){
- wp += rsiz;
- }
- *wp = '\0';
- close(fd);
- if(sp) *sp = wp - buf;
- return buf;
+ *wp = '\0';
+ CLOSEFH(fd);
+ if (sp) *sp = wp - buf;
+ return buf;
}
/* Write data into a file. */
bool tcwritefile(const char *path, const void *ptr, int size){
assert(ptr && size >= 0);
- int fd = 1;
- if(path && (fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, TCFILEMODE)) == -1) return false;
+ HANDLE fd;
+ if (path) {
+#ifdef _WIN32
+ fd = CreateFile(path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+#else
+ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, TCFILEMODE);
+#endif
+ } else {
+ fd = GET_STDOUT_HANDLE();
+ }
+ if (INVALIDHANDLE(fd)) {
+ return false;
+ }
bool err = false;
if(!tcwrite(fd, ptr, size)) err = true;
- if(close(fd) == -1) err = true;
+ if(path && !CLOSEFH(fd)) err = true;
return !err;
}
/* Copy a file. */
bool tccopyfile(const char *src, const char *dest){
- int ifd = open(src, O_RDONLY, TCFILEMODE);
- if(ifd == -1) return false;
- int ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, TCFILEMODE);
- if(ofd == -1){
- close(ifd);
+ HANDLE ifd, ofd;
+#ifndef _WIN32
+ ifd = open(src, O_RDONLY, TCFILEMODE);
+#else
+ ifd = CreateFile(src, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ if (INVALIDHANDLE(ifd)) return false;
+
+#ifndef _WIN32
+ ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, TCFILEMODE);
+#else
+ ofd = CreateFile(dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+#endif
+ if(INVALIDHANDLE(ofd)){
+ CLOSEFH(ifd);
return false;
}
bool err = false;
- while(true){
+ struct stat stat;
+ if (fstat(ifd, &stat)) {
+ CLOSEFH(ifd);
+ CLOSEFH(ofd);
+ return false;
+ }
+ off_t togo = stat.st_size;
+#ifdef _WIN32
+ HANDLE map = CreateFileMapping(ifd, NULL, PAGE_READONLY, 0, 0, NULL);
+ void *mmaped;
+ if (INVALIDHANDLE(map)) {
+ CLOSEFH(ifd);
+ CLOSEFH(ofd);
+ return false;
+ }
+#endif
+ while(togo > 0){
char buf[TCIOBUFSIZ];
+#ifndef _WIN32
int size = read(ifd, buf, TCIOBUFSIZ);
+#else
+ size_t toread = min(togo, TCIOBUFSIZ);
+ int size;
+ LARGE_INTEGER offset;
+ offset.QuadPart = stat.st_size - togo;
+ mmaped = MapViewOfFileEx(map, FILE_MAP_READ, offset.HighPart, offset.LowPart, toread, NULL);
+ if (mmaped == NULL){
+ size = -1;
+ errno = ESPIPE;
+ } else{
+ size = toread;
+ memcpy(buf, mmaped, toread);
+ UnmapViewOfFile(mmaped);
+ }
+#endif
if(size > 0){
+ togo -= size;
if(!tcwrite(ofd, buf, size)){
err = true;
break;
break;
}
}
- if(close(ofd) == -1) err = true;
- if(close(ifd) == -1) err = true;
+#ifdef _WIN32
+ if(!CLOSEFH(map)) err = true;
+#endif
+ if(!CLOSEFH(ofd)) err = true;
+ if(!CLOSEFH(ifd)) err = true;
return !err;
}
bool tcremovelink(const char *path){
assert(path);
struct stat sbuf;
- if(lstat(path, &sbuf) == -1) return false;
+ if(lstat(path, &sbuf)) return false;
if(unlink(path) == 0) return true;
TCLIST *list;
if(!S_ISDIR(sbuf.st_mode) || !(list = tcreaddir(path))) return false;
return rmdir(path) == 0 ? true : false;
}
+bool tcfseek(HANDLE fd, off_t off, int whence) {
+#ifdef _WIN32
+LARGE_INTEGER loff;
+loff.QuadPart = off;
+int w = FILE_BEGIN;
+if (whence == TCFCUR) {
+ w = FILE_CURRENT;
+} else if (whence == TCFEND) {
+ w = FILE_END;
+}
+return SetFilePointerEx(fd, loff, NULL, w);
+#else
+int w = SEEK_SET;
+if (whence == TCFCUR) {
+ w = SEEK_CUR;
+} else if (whence == TCFEND) {
+ w = SEEK_END;
+}
+return (lseek(fd, off, w) != -1)
+#endif
+}
+
+bool tcftruncate(HANDLE fd, off_t length) {
+#ifdef _WIN32
+ LARGE_INTEGER size;
+ size.QuadPart = length;
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ bool err = false;
+ pthread_mutex_lock(&mutex);
+ if (!SetFilePointerEx(fd, size, NULL, FILE_BEGIN)) err = true;
+ if (err == false && !SetEndOfFile(fd)) err = true;
+ pthread_mutex_unlock(&mutex);
+ return !err;
+#else
+ return (ftruncate(fd, length) != -1);
+#endif
+}
/* Write data into a file. */
-bool tcwrite(int fd, const void *buf, size_t size){
- assert(fd >= 0 && buf && size >= 0);
+bool tcwrite(HANDLE fd, const void *buf, size_t size){
+ assert(!INVALIDHANDLE(fd) && buf && size >= 0);
const char *rp = buf;
do {
+#ifndef _WIN32
int wb = write(fd, rp, size);
+#else
+ DWORD written;
+ int wb;
+ if (!WriteFile(fd, rp, size, &written, NULL))
+ wb = -1;
+ else
+ wb = written;
+#endif
switch(wb){
case -1: if(errno != EINTR) return false;
case 0: break;
/* Read data from a file. */
-bool tcread(int fd, void *buf, size_t size){
- assert(fd >= 0 && buf && size >= 0);
+bool tcread(HANDLE fd, void *buf, size_t size){
+ assert(!INVALIDHANDLE(fd) && buf && size >= 0);
char *wp = buf;
do {
+#ifndef _WIN32
int rb = read(fd, wp, size);
+#else
+ int rb;
+ DWORD r;
+ if(!ReadFile(fd, wp, size, &r, NULL))
+ rb = -1;
+ else
+ rb = r;
+#endif
switch(rb){
case -1: if(errno != EINTR) return false;
case 0: return size < 1;
/* Lock a file. */
-bool tclock(int fd, bool ex, bool nb){
- assert(fd >= 0);
+bool tclock(HANDLE fd, bool ex, bool nb){
+ assert(!INVALIDHANDLE(fd));
+#ifndef _WIN32
struct flock lock;
memset(&lock, 0, sizeof(struct flock));
lock.l_type = ex ? F_WRLCK : F_RDLCK;
if(errno != EINTR) return false;
}
return true;
+#else
+ DWORD type = 0; /* shared lock with waiting */
+ OVERLAPPED offset;
+ memset(&offset, 0, sizeof(OVERLAPPED));
+ if (ex) type = LOCKFILE_EXCLUSIVE_LOCK;
+ if (nb) type |= LOCKFILE_FAIL_IMMEDIATELY;
+ if (LockFileEx(fd, type, 0, ULONG_MAX, ULONG_MAX, &offset)) {
+ return true;
+ } else {
+ return false;
+ }
+#endif
}
/* Unlock a file. */
-bool tcunlock(int fd){
- assert(fd >= 0);
+bool tcunlock(HANDLE fd){
+ assert(!INVALIDHANDLE(fd));
+#ifndef _WIN32
struct flock lock;
memset(&lock, 0, sizeof(struct flock));
lock.l_type = F_UNLCK;
if(errno != EINTR) return false;
}
return true;
+#else
+ OVERLAPPED offset;
+ memset(&offset, 0, sizeof(OVERLAPPED));
+ if (UnlockFileEx(fd, 0, ULONG_MAX, ULONG_MAX, &offset)) {
+ return true;
+ } else {
+ return false;
+ }
+#endif
}
static int tcgammaencode(const char *ptr, int size, char *obuf);
static int tcgammadecode(const char *ptr, int size, char *obuf);
+int tcfilerrno2tcerr(int tcerrdef) {
+#ifdef _WIN32
+ switch (GetLastError()) {
+ case ERROR_PATH_NOT_FOUND:
+ case ERROR_FILE_NOT_FOUND:
+ return TCENOFILE;
+ case ERROR_ACCESS_DENIED:
+ case ERROR_WRITE_PROTECT:
+ case ERROR_SHARING_VIOLATION:
+ return TCENOPERM;
+ break;
+ case ERROR_SEEK:
+ return TCESEEK;
+ break;
+ case ERROR_READ_FAULT:
+ return TCEREAD;
+ break;
+ case ERROR_WRITE_FAULT:
+ return TCEWRITE;
+ break;
+ case ERROR_LOCK_VIOLATION:
+ return TCELOCK;
+ break;
+ case ERROR_FILE_EXISTS:
+ case ERROR_ALREADY_EXISTS:
+ return TCEOPEN;
+ break;
+ }
+#endif
+ switch (errno) {
+ case EACCES:
+ case EROFS:
+ return TCENOPERM;
+ break;
+ case ENOENT:
+ case ENOTDIR:
+ return TCENOFILE;
+ break;
+ }
+ return tcerrdef;
+}
+
/* Get the message string corresponding to an error code. */
const char *tcerrmsg(int ecode){
case TCERMDIR: return "rmdir error";
case TCEKEEP: return "existing record";
case TCENOREC: return "no record found";
+ case TCETR: return "illegal transaction state";
case TCEMISC: return "miscellaneous error";
}
return "unknown error";
return log(num) / log(2);
}
+off_t tcpagsize(void) {
+#ifdef _WIN32
+ static off_t g_pagesize = 0;
+ if (!g_pagesize) {
+ SYSTEM_INFO system_info;
+ GetSystemInfo(&system_info);
+ g_pagesize = system_info.dwPageSize;
+ }
+ return g_pagesize;
+#else
+ return sysconf(_SC_PAGESIZE);
+#endif
+}
/* Get the aligned offset of a file offset. */
uint64_t tcpagealign(uint64_t off){
- int ps = sysconf(_SC_PAGESIZE);
+ off_t ps = tcpagsize();
int diff = off & (ps - 1);
- return (diff > 0) ? off + ps - diff : off;
+ return (diff > 0) ? (off + ps - diff) : off;
}
/* Initialize the global mutex object */
static void tcglobalinit(void){
- if(!TCUSEPTHREAD){
- memset(&tcglobalmutex, 0, sizeof(tcglobalmutex));
- memset(&tcpathmutex, 0, sizeof(tcpathmutex));
- }
if(pthread_rwlock_init(&tcglobalmutex, NULL) != 0) tcmyfatal("rwlock error");
if(pthread_mutex_init(&tcpathmutex, NULL) != 0) tcmyfatal("mutex error");
tcpathmap = tcmapnew2(TCMAPTINYBNUM);
#endif
__TCUTIL_CLINKAGEBEGIN
+#include "basedefs.h"
#include <stdlib.h>
#if ! defined(__cplusplus)
#include <time.h>
#include <limits.h>
#include <math.h>
+#include <sys/types.h>
/* String containing the version information. */
-extern const char *tcversion;
+extern EJDB_EXPORT const char *tcversion;
/* Pointer to the call back function for handling a fatal error.
The argument specifies the error message.
The initial value of this variable is `NULL'. If the value is `NULL', the default function is
called when a fatal error occurs. A fatal error occurs when memory allocation is failed. */
-extern void (*tcfatalfunc)(const char *);
+extern EJDB_EXPORT void (*tcfatalfunc)(const char *);
/* Allocate a region on memory.
This function handles failure of memory allocation implicitly. Because the region of the
return value is allocated with the `malloc' call, it should be released with the `free' call
when it is no longer in use. */
-void *tcmalloc(size_t size);
+ EJDB_EXPORT void *tcmalloc(size_t size);
/* Allocate a nullified region on memory.
This function handles failure of memory allocation implicitly. Because the region of the
return value is allocated with the `calloc' call, it should be released with the `free' call
when it is no longer in use. */
-void *tccalloc(size_t nmemb, size_t size);
+EJDB_EXPORT void *tccalloc(size_t nmemb, size_t size);
/* Re-allocate a region on memory.
This function handles failure of memory allocation implicitly. Because the region of the
return value is allocated with the `realloc' call, it should be released with the `free' call
when it is no longer in use. */
-void *tcrealloc(void *ptr, size_t size);
+EJDB_EXPORT void *tcrealloc(void *ptr, size_t size);
/* Duplicate a region on memory.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tcmemdup(const void *ptr, size_t size);
+EJDB_EXPORT void *tcmemdup(const void *ptr, size_t size);
/* Duplicate a string on memory.
The return value is the allocated string equivalent to the specified string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcstrdup(const void *str);
+EJDB_EXPORT char *tcstrdup(const void *str);
/* Free a region on memory.
`ptr' specifies the pointer to the region. If it is `NULL', this function has no effect.
Although this function is just a wrapper of `free' call, this is useful in applications using
another package of the `malloc' series. */
-void tcfree(void *ptr);
+EJDB_EXPORT void tcfree(void *ptr);
/* Create an extensible string object.
The return value is the new extensible string object. */
-TCXSTR *tcxstrnew(void);
+EJDB_EXPORT TCXSTR *tcxstrnew(void);
/* Create an extensible string object from a character string.
`str' specifies the string of the initial content.
The return value is the new extensible string object containing the specified string. */
-TCXSTR *tcxstrnew2(const char *str);
+EJDB_EXPORT TCXSTR *tcxstrnew2(const char *str);
/* Create an extensible string object with the initial allocation size.
`asiz' specifies the initial allocation size.
The return value is the new extensible string object. */
-TCXSTR *tcxstrnew3(int asiz);
+EJDB_EXPORT TCXSTR *tcxstrnew3(int asiz);
/* Copy an extensible string object.
`xstr' specifies the extensible string object.
The return value is the new extensible string object equivalent to the specified object. */
-TCXSTR *tcxstrdup(const TCXSTR *xstr);
+EJDB_EXPORT TCXSTR *tcxstrdup(const TCXSTR *xstr);
/* Delete an extensible string object.
`xstr' specifies the extensible string object.
Note that the deleted object and its derivatives can not be used anymore. */
-void tcxstrdel(TCXSTR *xstr);
+EJDB_EXPORT void tcxstrdel(TCXSTR *xstr);
/* Concatenate a region to the end of an extensible string object.
`xstr' specifies the extensible string object.
`ptr' specifies the pointer to the region to be appended.
`size' specifies the size of the region. */
-void tcxstrcat(TCXSTR *xstr, const void *ptr, int size);
+EJDB_EXPORT void tcxstrcat(TCXSTR *xstr, const void *ptr, int size);
/* Concatenate a character string to the end of an extensible string object.
`xstr' specifies the extensible string object.
`str' specifies the string to be appended. */
-void tcxstrcat2(TCXSTR *xstr, const char *str);
+EJDB_EXPORT void tcxstrcat2(TCXSTR *xstr, const char *str);
/* Get the pointer of the region of an extensible string object.
The return value is the pointer of the region of the object.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-const void *tcxstrptr(const TCXSTR *xstr);
+EJDB_EXPORT const void *tcxstrptr(const TCXSTR *xstr);
/* Get the size of the region of an extensible string object.
`xstr' specifies the extensible string object.
The return value is the size of the region of the object. */
-int tcxstrsize(const TCXSTR *xstr);
+EJDB_EXPORT int tcxstrsize(const TCXSTR *xstr);
/* Clear an extensible string object.
`xstr' specifies the extensible string object.
The internal buffer of the object is cleared and the size is set zero. */
-void tcxstrclear(TCXSTR *xstr);
+EJDB_EXPORT void tcxstrclear(TCXSTR *xstr);
/* Perform formatted output into an extensible string object.
with `s' but escapes meta characters of URL. `b' converts an integer to the string as binary
numbers. The other conversion character work as with each original.
The other arguments are used according to the format string. */
-void tcxstrprintf(TCXSTR *xstr, const char *format, ...);
+EJDB_EXPORT void tcxstrprintf(TCXSTR *xstr, const char *format, ...);
/* Allocate a formatted string on memory.
The return value is the pointer to the region of the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcsprintf(const char *format, ...);
+EJDB_EXPORT char *tcsprintf(const char *format, ...);
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. Because the region of the original object is deleted, it should not be
deleted again. */
-void *tcxstrtomalloc(TCXSTR *xstr);
+EJDB_EXPORT void *tcxstrtomalloc(TCXSTR *xstr);
/* Create an extensible string object from an allocated region.
`size' specifies the size of the region.
The return value is the new extensible string object wrapping the specified region.
Note that the specified region is released when the object is deleted. */
-TCXSTR *tcxstrfrommalloc(void *ptr, int size);
+EJDB_EXPORT TCXSTR *tcxstrfrommalloc(void *ptr, int size);
/* Create a list object.
The return value is the new list object. */
-TCLIST *tclistnew(void);
+EJDB_EXPORT TCLIST *tclistnew(void);
/* Create a list object with expecting the number of elements.
`anum' specifies the number of elements expected to be stored in the list.
The return value is the new list object. */
-TCLIST *tclistnew2(int anum);
+EJDB_EXPORT TCLIST *tclistnew2(int anum);
/* Create a list object with initial string elements.
`str' specifies the string of the first element.
The other arguments are other elements. They should be trailed by a `NULL' argument.
The return value is the new list object. */
-TCLIST *tclistnew3(const char *str, ...);
+EJDB_EXPORT TCLIST *tclistnew3(const char *str, ...);
/* Copy a list object.
`list' specifies the list object.
The return value is the new list object equivalent to the specified object. */
-TCLIST *tclistdup(const TCLIST *list);
+EJDB_EXPORT TCLIST *tclistdup(const TCLIST *list);
/* Delete a list object.
`list' specifies the list object.
Note that the deleted object and its derivatives can not be used anymore. */
-void tclistdel(TCLIST *list);
+EJDB_EXPORT void tclistdel(TCLIST *list);
/* Get the number of elements of a list object.
`list' specifies the list object.
The return value is the number of elements of the list. */
-int tclistnum(const TCLIST *list);
+EJDB_EXPORT int tclistnum(const TCLIST *list);
/* Get the pointer to the region of an element of a list object.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. If `index' is equal to or more than
the number of elements, the return value is `NULL'. */
-const void *tclistval(const TCLIST *list, int index, int *sp);
+EJDB_EXPORT const void *tclistval(const TCLIST *list, int index, int *sp);
/* Get the string of an element of a list object.
`index' specifies the index of the element.
The return value is the string of the value.
If `index' is equal to or more than the number of elements, the return value is `NULL'. */
-const char *tclistval2(const TCLIST *list, int index);
+EJDB_EXPORT const char *tclistval2(const TCLIST *list, int index);
/* Add an element at the end of a list object.
`list' specifies the list object.
`ptr' specifies the pointer to the region of the new element.
`size' specifies the size of the region. */
-void tclistpush(TCLIST *list, const void *ptr, int size);
+EJDB_EXPORT void tclistpush(TCLIST *list, const void *ptr, int size);
/* Add a string element at the end of a list object.
`list' specifies the list object.
`str' specifies the string of the new element. */
-void tclistpush2(TCLIST *list, const char *str);
+EJDB_EXPORT void tclistpush2(TCLIST *list, const char *str);
/* Remove an element of the end of a list object.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. If the list is empty, the return value is `NULL'. */
-void *tclistpop(TCLIST *list, int *sp);
+EJDB_EXPORT void *tclistpop(TCLIST *list, int *sp);
/* Remove a string element of the end of a list object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. If the list is empty, the return
value is `NULL'. */
-char *tclistpop2(TCLIST *list);
+EJDB_EXPORT char *tclistpop2(TCLIST *list);
/* Add an element at the top of a list object.
`list' specifies the list object.
`ptr' specifies the pointer to the region of the new element.
`size' specifies the size of the region. */
-void tclistunshift(TCLIST *list, const void *ptr, int size);
+EJDB_EXPORT void tclistunshift(TCLIST *list, const void *ptr, int size);
/* Add a string element at the top of a list object.
`list' specifies the list object.
`str' specifies the string of the new element. */
-void tclistunshift2(TCLIST *list, const char *str);
+EJDB_EXPORT void tclistunshift2(TCLIST *list, const char *str);
/* Remove an element of the top of a list object.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. If the list is empty, the return value is `NULL'. */
-void *tclistshift(TCLIST *list, int *sp);
+EJDB_EXPORT void *tclistshift(TCLIST *list, int *sp);
/* Remove a string element of the top of a list object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. If the list is empty, the return
value is `NULL'. */
-char *tclistshift2(TCLIST *list);
+EJDB_EXPORT char *tclistshift2(TCLIST *list);
/* Add an element at the specified location of a list object.
`ptr' specifies the pointer to the region of the new element.
`size' specifies the size of the region.
If `index' is equal to or more than the number of elements, this function has no effect. */
-void tclistinsert(TCLIST *list, int index, const void *ptr, int size);
+EJDB_EXPORT void tclistinsert(TCLIST *list, int index, const void *ptr, int size);
/* Add a string element at the specified location of a list object.
`index' specifies the index of the new element.
`str' specifies the string of the new element.
If `index' is equal to or more than the number of elements, this function has no effect. */
-void tclistinsert2(TCLIST *list, int index, const char *str);
+EJDB_EXPORT void tclistinsert2(TCLIST *list, int index, const char *str);
/* Remove an element at the specified location of a list object.
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. If `index' is equal to or more than the number of elements, no element
is removed and the return value is `NULL'. */
-void *tclistremove(TCLIST *list, int index, int *sp);
+EJDB_EXPORT void *tclistremove(TCLIST *list, int index, int *sp);
/* Remove a string element at the specified location of a list object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. If `index' is equal to or more
than the number of elements, no element is removed and the return value is `NULL'. */
-char *tclistremove2(TCLIST *list, int index);
+EJDB_EXPORT char *tclistremove2(TCLIST *list, int index);
/* Overwrite an element at the specified location of a list object.
`ptr' specifies the pointer to the region of the new content.
`size' specifies the size of the new content.
If `index' is equal to or more than the number of elements, this function has no effect. */
-void tclistover(TCLIST *list, int index, const void *ptr, int size);
+EJDB_EXPORT void tclistover(TCLIST *list, int index, const void *ptr, int size);
/* Overwrite a string element at the specified location of a list object.
`index' specifies the index of the element to be overwritten.
`str' specifies the string of the new content.
If `index' is equal to or more than the number of elements, this function has no effect. */
-void tclistover2(TCLIST *list, int index, const char *str);
+EJDB_EXPORT void tclistover2(TCLIST *list, int index, const char *str);
/* Sort elements of a list object in lexical order.
`list' specifies the list object. */
-void tclistsort(TCLIST *list);
+EJDB_EXPORT void tclistsort(TCLIST *list);
/* Search a list object for an element using liner search.
The return value is the index of a corresponding element or -1 if there is no corresponding
element.
If two or more elements correspond, the former returns. */
-int tclistlsearch(const TCLIST *list, const void *ptr, int size);
+EJDB_EXPORT int tclistlsearch(const TCLIST *list, const void *ptr, int size);
/* Search a list object for an element using binary search.
The return value is the index of a corresponding element or -1 if there is no corresponding
element.
If two or more elements correspond, which returns is not defined. */
-int tclistbsearch(const TCLIST *list, const void *ptr, int size);
+EJDB_EXPORT int tclistbsearch(const TCLIST *list, const void *ptr, int size);
/* Clear a list object.
`list' specifies the list object.
All elements are removed. */
-void tclistclear(TCLIST *list);
+EJDB_EXPORT void tclistclear(TCLIST *list);
/* Serialize a list object into a byte array.
The return value is the pointer to the region of the result serial region.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-void *tclistdump(const TCLIST *list, int *sp);
+EJDB_EXPORT void *tclistdump(const TCLIST *list, int *sp);
/* Create a list object from a serialized byte array.
The return value is a new list object.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tclistload(const void *ptr, int size);
+EJDB_EXPORT TCLIST *tclistload(const void *ptr, int size);
`ptr' specifies the pointer to the region allocated with `malloc' call.
`size' specifies the size of the region.
Note that the specified region is released when the object is deleted. */
-void tclistpushmalloc(TCLIST *list, void *ptr, int size);
+EJDB_EXPORT void tclistpushmalloc(TCLIST *list, void *ptr, int size);
/* Sort elements of a list object in case-insensitive lexical order.
`list' specifies the list object. */
-void tclistsortci(TCLIST *list);
+EJDB_EXPORT void tclistsortci(TCLIST *list);
/* Sort elements of a list object by an arbitrary comparison function.
`cmp' specifies the pointer to the comparison function. The structure TCLISTDATUM has the
member "ptr" which is the pointer to the region of the element, and the member "size" which is
the size of the region. */
-void tclistsortex(TCLIST *list, int (*cmp)(const TCLISTDATUM *, const TCLISTDATUM *));
+EJDB_EXPORT void tclistsortex(TCLIST *list, int (*cmp)(const TCLISTDATUM *, const TCLISTDATUM *));
/* Invert elements of a list object.
`list' specifies the list object. */
-void tclistinvert(TCLIST *list);
+EJDB_EXPORT void tclistinvert(TCLIST *list);
/* Perform formatted output into a list object.
with `s' but escapes meta characters of URL. `b' converts an integer to the string as binary
numbers. The other conversion character work as with each original.
The other arguments are used according to the format string. */
-void tclistprintf(TCLIST *list, const char *format, ...);
+EJDB_EXPORT void tclistprintf(TCLIST *list, const char *format, ...);
/* Create a map object.
The return value is the new map object. */
-TCMAP *tcmapnew(void);
+EJDB_EXPORT TCMAP *tcmapnew(void);
/* Create a map object with specifying the number of the buckets.
`bnum' specifies the number of the buckets.
The return value is the new map object. */
-TCMAP *tcmapnew2(uint32_t bnum);
+EJDB_EXPORT TCMAP *tcmapnew2(uint32_t bnum);
/* Create a map object with initial string elements.
The other arguments are other elements. They should be trailed by a `NULL' argument.
The return value is the new map object.
The key and the value of each record are situated one after the other. */
-TCMAP *tcmapnew3(const char *str, ...);
+EJDB_EXPORT TCMAP *tcmapnew3(const char *str, ...);
/* Copy a map object.
`map' specifies the map object.
The return value is the new map object equivalent to the specified object. */
-TCMAP *tcmapdup(const TCMAP *map);
+EJDB_EXPORT TCMAP *tcmapdup(const TCMAP *map);
/* Delete a map object.
`map' specifies the map object.
Note that the deleted object and its derivatives can not be used anymore. */
-void tcmapdel(TCMAP *map);
+EJDB_EXPORT void tcmapdel(TCMAP *map);
/* Store a record into a map object.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the map, it is overwritten. */
-void tcmapput(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcmapput(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into a map object.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If a record with the same key exists in the map, it is overwritten. */
-void tcmapput2(TCMAP *map, const char *kstr, const char *vstr);
+EJDB_EXPORT void tcmapput2(TCMAP *map, const char *kstr, const char *vstr);
/* Store a new record into a map object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the map, this function has no effect. */
-bool tcmapputkeep(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcmapputkeep(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into a map object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the map, this function has no effect. */
-bool tcmapputkeep2(TCMAP *map, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcmapputkeep2(TCMAP *map, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the value of the existing record in a map object.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. */
-void tcmapputcat(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcmapputcat(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string value at the end of the value of the existing record in a map object.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If there is no corresponding record, a new record is created. */
-void tcmapputcat2(TCMAP *map, const char *kstr, const char *vstr);
+EJDB_EXPORT void tcmapputcat2(TCMAP *map, const char *kstr, const char *vstr);
/* Remove a record of a map object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcmapout(TCMAP *map, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcmapout(TCMAP *map, const void *kbuf, int ksiz);
/* Remove a string record of a map object.
`kstr' specifies the string of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcmapout2(TCMAP *map, const char *kstr);
+EJDB_EXPORT bool tcmapout2(TCMAP *map, const char *kstr);
/* Retrieve a record in a map object.
corresponding record. `NULL' is returned when no record corresponds.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-const void *tcmapget(const TCMAP *map, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT const void *tcmapget(const TCMAP *map, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in a map object.
`kstr' specifies the string of the key.
If successful, the return value is the string of the value of the corresponding record.
`NULL' is returned when no record corresponds. */
-const char *tcmapget2(const TCMAP *map, const char *kstr);
+EJDB_EXPORT const char *tcmapget2(const TCMAP *map, const char *kstr);
/* Move a record to the edge of a map object.
`head' specifies the destination which is the head if it is true or the tail if else.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcmapmove(TCMAP *map, const void *kbuf, int ksiz, bool head);
+EJDB_EXPORT bool tcmapmove(TCMAP *map, const void *kbuf, int ksiz, bool head);
/* Move a string record to the edge of a map object.
`head' specifies the destination which is the head if it is true or the tail if else.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcmapmove2(TCMAP *map, const char *kstr, bool head);
+EJDB_EXPORT bool tcmapmove2(TCMAP *map, const char *kstr, bool head);
/* Initialize the iterator of a map object.
`map' specifies the map object.
The iterator is used in order to access the key of every record stored in the map object. */
-void tcmapiterinit(TCMAP *map);
+EJDB_EXPORT void tcmapiterinit(TCMAP *map);
/* Get the next key of the iterator of a map object.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string.
The order of iteration is assured to be the same as the stored order. */
-const void *tcmapiternext(TCMAP *map, int *sp);
+EJDB_EXPORT const void *tcmapiternext(TCMAP *map, int *sp);
/* Get the next key string of the iterator of a map object.
If successful, the return value is the pointer to the region of the next key, else, it is
`NULL'. `NULL' is returned when no record can be fetched from the iterator.
The order of iteration is assured to be the same as the stored order. */
-const char *tcmapiternext2(TCMAP *map);
+EJDB_EXPORT const char *tcmapiternext2(TCMAP *map);
/* Get the number of records stored in a map object.
`map' specifies the map object.
The return value is the number of the records stored in the map object. */
-uint64_t tcmaprnum(const TCMAP *map);
+EJDB_EXPORT uint64_t tcmaprnum(const TCMAP *map);
/* Get the total size of memory used in a map object.
`map' specifies the map object.
The return value is the total size of memory used in a map object. */
-uint64_t tcmapmsiz(const TCMAP *map);
+EJDB_EXPORT uint64_t tcmapmsiz(const TCMAP *map);
/* Create a list object containing all keys in a map object.
The return value is the new list object containing all keys in the map object.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcmapkeys(const TCMAP *map);
+EJDB_EXPORT TCLIST *tcmapkeys(const TCMAP *map);
/* Create a list object containing all values in a map object.
The return value is the new list object containing all values in the map object.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcmapvals(const TCMAP *map);
+EJDB_EXPORT TCLIST *tcmapvals(const TCMAP *map);
/* Add an integer to a record in a map object.
The return value is the summation value.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tcmapaddint(TCMAP *map, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tcmapaddint(TCMAP *map, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in a map object.
The return value is the summation value.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tcmapadddouble(TCMAP *map, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tcmapadddouble(TCMAP *map, const void *kbuf, int ksiz, double num);
/* Clear a map object.
`map' specifies the map object.
All records are removed. */
-void tcmapclear(TCMAP *map);
+EJDB_EXPORT void tcmapclear(TCMAP *map);
/* Remove front records of a map object.
`map' specifies the map object.
`num' specifies the number of records to be removed. */
-void tcmapcutfront(TCMAP *map, int num);
+EJDB_EXPORT void tcmapcutfront(TCMAP *map, int num);
/* Serialize a map object into a byte array.
The return value is the pointer to the region of the result serial region.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-void *tcmapdump(const TCMAP *map, int *sp);
+EJDB_EXPORT void *tcmapdump(const TCMAP *map, int *sp);
/* Create a map object from a serialized byte array.
The return value is a new map object.
Because the object of the return value is created with the function `tcmapnew', it should be
deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tcmapload(const void *ptr, int size);
+EJDB_EXPORT TCMAP *tcmapload(const void *ptr, int size);
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the map, it is overwritten. The record is moved to
the tail. */
-void tcmapput3(TCMAP *map, const void *kbuf, int ksiz, const char *vbuf, int vsiz);
+EJDB_EXPORT void tcmapput3(TCMAP *map, const void *kbuf, int ksiz, const char *vbuf, int vsiz);
/* Store a record of the value of two regions into a map object.
`lvbuf' specifies the pointer to the latter region of the value.
`lvsiz' specifies the size of the latter region of the value.
If a record with the same key exists in the map, it is overwritten. */
-void tcmapput4(TCMAP *map, const void *kbuf, int ksiz,
+EJDB_EXPORT void tcmapput4(TCMAP *map, const void *kbuf, int ksiz,
const void *fvbuf, int fvsiz, const void *lvbuf, int lvsiz);
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. */
-void tcmapputcat3(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcmapputcat3(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a record into a map object with a duplication handler.
`op' specifies an arbitrary pointer to be given as a parameter of the callback function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tcmapputproc(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tcmapputproc(TCMAP *map, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
the return value can be treated as a character string. The internal region of the returned
record is moved to the tail so that the record will survive for a time under LRU cache
algorithm removing records from the head. */
-const void *tcmapget3(TCMAP *map, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT const void *tcmapget3(TCMAP *map, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in a map object with specifying the default value string.
`dstr' specifies the string of the default value.
The return value is the string of the value of the corresponding record or the default value
string. */
-const char *tcmapget4(TCMAP *map, const char *kstr, const char *dstr);
+EJDB_EXPORT const char *tcmapget4(TCMAP *map, const char *kstr, const char *dstr);
/* Initialize the iterator of a map object at the record corresponding a key.
`kbuf' specifies the pointer to the region of the key.
`ksiz' specifies the size of the region of the key.
If there is no record corresponding the condition, the iterator is not modified. */
-void tcmapiterinit2(TCMAP *map, const void *kbuf, int ksiz);
+EJDB_EXPORT void tcmapiterinit2(TCMAP *map, const void *kbuf, int ksiz);
/* Initialize the iterator of a map object at the record corresponding a key string.
`map' specifies the map object.
`kstr' specifies the string of the key.
If there is no record corresponding the condition, the iterator is not modified. */
-void tcmapiterinit3(TCMAP *map, const char *kstr);
+EJDB_EXPORT void tcmapiterinit3(TCMAP *map, const char *kstr);
/* Get the value bound to the key fetched from the iterator of a map object.
The return value is the pointer to the region of the value of the corresponding record.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-const void *tcmapiterval(const void *kbuf, int *sp);
+EJDB_EXPORT const void *tcmapiterval(const void *kbuf, int *sp);
/* Get the value string bound to the key fetched from the iterator of a map object.
`kstr' specifies the string of the iteration key.
The return value is the pointer to the region of the value of the corresponding record. */
-const char *tcmapiterval2(const char *kstr);
+EJDB_EXPORT const char *tcmapiterval2(const char *kstr);
/* Create an array of strings of all keys in a map object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. Note that elements of the array
point to the inner objects, whose life duration is synchronous with the map object. */
-const char **tcmapkeys2(const TCMAP *map, int *np);
+EJDB_EXPORT const char **tcmapkeys2(const TCMAP *map, int *np);
/* Create an array of strings of all values in a map object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. Note that elements of the array
point to the inner objects, whose life duration is synchronous with the map object. */
-const char **tcmapvals2(const TCMAP *map, int *np);
+EJDB_EXPORT const char **tcmapvals2(const TCMAP *map, int *np);
/* Extract a map record from a serialized byte array.
corresponding record. `NULL' is returned when no record corresponds.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-void *tcmaploadone(const void *ptr, int size, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcmaploadone(const void *ptr, int size, const void *kbuf, int ksiz, int *sp);
/* Extract a map record from a serialized byte array into extensible string object.
`xstr' specifies extensible string object data will be placed into.
If successful, the return value is >= 0
corresponding record. 0 is returned when no record corresponds.*/
-int tcmaploadoneintoxstr(const void *ptr, int size, const void *kbuf, int ksiz, TCXSTR *xstr);
+EJDB_EXPORT int tcmaploadoneintoxstr(const void *ptr, int size, const void *kbuf, int ksiz, TCXSTR *xstr);
/* Perform formatted output into a map object.
with `s' but escapes meta characters of URL. `b' converts an integer to the string as binary
numbers. The other conversion character work as with each original.
The other arguments are used according to the format string. */
-void tcmapprintf(TCMAP *map, const char *kstr, const char *format, ...);
+EJDB_EXPORT void tcmapprintf(TCMAP *map, const char *kstr, const char *format, ...);
/* Create a tree object.
The return value is the new tree object. */
-TCTREE *tctreenew(void);
+EJDB_EXPORT TCTREE *tctreenew(void);
/* Create a tree object with specifying the custom comparison function.
The return value is the new tree object.
The default comparison function compares keys of two records by lexical order. The functions
`tccmplexical' (dafault), `tccmpdecimal', `tccmpint32', and `tccmpint64' are built-in. */
-TCTREE *tctreenew2(TCCMP cmp, void *cmpop);
+EJDB_EXPORT TCTREE *tctreenew2(TCCMP cmp, void *cmpop);
/* Copy a tree object.
`tree' specifies the tree object.
The return value is the new tree object equivalent to the specified object. */
-TCTREE *tctreedup(const TCTREE *tree);
+EJDB_EXPORT TCTREE *tctreedup(const TCTREE *tree);
/* Delete a tree object.
`tree' specifies the tree object.
Note that the deleted object and its derivatives can not be used anymore. */
-void tctreedel(TCTREE *tree);
+EJDB_EXPORT void tctreedel(TCTREE *tree);
/* Store a record into a tree object.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the tree, it is overwritten. */
-void tctreeput(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tctreeput(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into a tree object.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If a record with the same key exists in the tree, it is overwritten. */
-void tctreeput2(TCTREE *tree, const char *kstr, const char *vstr);
+EJDB_EXPORT void tctreeput2(TCTREE *tree, const char *kstr, const char *vstr);
/* Store a new record into a tree object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the tree, this function has no effect. */
-bool tctreeputkeep(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tctreeputkeep(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into a tree object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the tree, this function has no effect. */
-bool tctreeputkeep2(TCTREE *tree, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tctreeputkeep2(TCTREE *tree, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the value of the existing record in a tree object.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. */
-void tctreeputcat(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tctreeputcat(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string value at the end of the value of the existing record in a tree object.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If there is no corresponding record, a new record is created. */
-void tctreeputcat2(TCTREE *tree, const char *kstr, const char *vstr);
+EJDB_EXPORT void tctreeputcat2(TCTREE *tree, const char *kstr, const char *vstr);
/* Store a record into a tree object with a duplication handler.
`op' specifies an arbitrary pointer to be given as a parameter of the callback function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tctreeputproc(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tctreeputproc(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
`ksiz' specifies the size of the region of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tctreeout(TCTREE *tree, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tctreeout(TCTREE *tree, const void *kbuf, int ksiz);
/* Remove a string record of a tree object.
`kstr' specifies the string of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tctreeout2(TCTREE *tree, const char *kstr);
+EJDB_EXPORT bool tctreeout2(TCTREE *tree, const char *kstr);
/* Retrieve a record in a tree object.
corresponding record. `NULL' is returned when no record corresponds.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-const void *tctreeget(TCTREE *tree, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT const void *tctreeget(TCTREE *tree, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in a tree object.
`kstr' specifies the string of the key.
If successful, the return value is the string of the value of the corresponding record.
`NULL' is returned when no record corresponds. */
-const char *tctreeget2(TCTREE *tree, const char *kstr);
+EJDB_EXPORT const char *tctreeget2(TCTREE *tree, const char *kstr);
/* Initialize the iterator of a tree object.
`tree' specifies the tree object.
The iterator is used in order to access the key of every record stored in the tree object. */
-void tctreeiterinit(TCTREE *tree);
+EJDB_EXPORT void tctreeiterinit(TCTREE *tree);
/* Get the next key of the iterator of a tree object.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string.
The order of iteration is assured to be ascending of the keys. */
-const void *tctreeiternext(TCTREE *tree, int *sp);
+EJDB_EXPORT const void *tctreeiternext(TCTREE *tree, int *sp);
/* Get the next key string of the iterator of a tree object.
If successful, the return value is the pointer to the region of the next key, else, it is
`NULL'. `NULL' is returned when no record can be fetched from the iterator.
The order of iteration is assured to be ascending of the keys. */
-const char *tctreeiternext2(TCTREE *tree);
+EJDB_EXPORT const char *tctreeiternext2(TCTREE *tree);
/* Get the number of records stored in a tree object.
`tree' specifies the tree object.
The return value is the number of the records stored in the tree object. */
-uint64_t tctreernum(const TCTREE *tree);
+EJDB_EXPORT uint64_t tctreernum(const TCTREE *tree);
/* Get the total size of memory used in a tree object.
`tree' specifies the tree object.
The return value is the total size of memory used in a tree object. */
-uint64_t tctreemsiz(const TCTREE *tree);
+EJDB_EXPORT uint64_t tctreemsiz(const TCTREE *tree);
/* Create a list object containing all keys in a tree object.
The return value is the new list object containing all keys in the tree object.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tctreekeys(const TCTREE *tree);
+EJDB_EXPORT TCLIST *tctreekeys(const TCTREE *tree);
/* Create a list object containing all values in a tree object.
The return value is the new list object containing all values in the tree object.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tctreevals(const TCTREE *tree);
+EJDB_EXPORT TCLIST *tctreevals(const TCTREE *tree);
/* Add an integer to a record in a tree object.
The return value is the summation value.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tctreeaddint(TCTREE *tree, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tctreeaddint(TCTREE *tree, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in a tree object.
The return value is the summation value.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tctreeadddouble(TCTREE *tree, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tctreeadddouble(TCTREE *tree, const void *kbuf, int ksiz, double num);
/* Clear a tree object.
`tree' specifies the tree object.
All records are removed. */
-void tctreeclear(TCTREE *tree);
+EJDB_EXPORT void tctreeclear(TCTREE *tree);
/* Remove fringe records of a tree object.
`tree' specifies the tree object.
`num' specifies the number of records to be removed. */
-void tctreecutfringe(TCTREE *tree, int num);
+EJDB_EXPORT void tctreecutfringe(TCTREE *tree, int num);
/* Serialize a tree object into a byte array.
The return value is the pointer to the region of the result serial region.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-void *tctreedump(const TCTREE *tree, int *sp);
+EJDB_EXPORT void *tctreedump(const TCTREE *tree, int *sp);
/* Create a tree object from a serialized byte array.
The return value is a new tree object.
Because the object of the return value is created with the function `tctreenew', it should be
deleted with the function `tctreedel' when it is no longer in use. */
-TCTREE *tctreeload(const void *ptr, int size, TCCMP cmp, void *cmpop);
+EJDB_EXPORT TCTREE *tctreeload(const void *ptr, int size, TCCMP cmp, void *cmpop);
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the tree, it is overwritten. The structure of the
tree is not modifed by this function. */
-void tctreeput3(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tctreeput3(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new record into a tree object without balancing nodes.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the tree, this function has no effect. The structure
of the tree is not modifed by this function. */
-bool tctreeputkeep3(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tctreeputkeep3(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a value at the existing record in a tree object without balancing nodes.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. The structure of the tree is
not modifed by this function. */
-void tctreeputcat3(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tctreeputcat3(TCTREE *tree, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Retrieve a record in a tree object without balancing nodes.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. The structure of the tree is not
modifed by this function. */
-const void *tctreeget3(const TCTREE *tree, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT const void *tctreeget3(const TCTREE *tree, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in a tree object with specifying the default value string.
`dstr' specifies the string of the default value.
The return value is the string of the value of the corresponding record or the default value
string. */
-const char *tctreeget4(TCTREE *tree, const char *kstr, const char *dstr);
+EJDB_EXPORT const char *tctreeget4(TCTREE *tree, const char *kstr, const char *dstr);
/* Initialize the iterator of a tree object in front of records corresponding a key.
`ksiz' specifies the size of the region of the key.
The iterator is set to the first record corresponding the key or the next substitute if
completely matching record does not exist. */
-void tctreeiterinit2(TCTREE *tree, const void *kbuf, int ksiz);
+EJDB_EXPORT void tctreeiterinit2(TCTREE *tree, const void *kbuf, int ksiz);
/* Initialize the iterator of a tree object in front of records corresponding a key string.
`kstr' specifies the string of the key.
The iterator is set to the first record corresponding the key or the next substitute if
completely matching record does not exist. */
-void tctreeiterinit3(TCTREE *tree, const char *kstr);
+EJDB_EXPORT void tctreeiterinit3(TCTREE *tree, const char *kstr);
/* Get the value bound to the key fetched from the iterator of a tree object.
The return value is the pointer to the region of the value of the corresponding record.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-const void *tctreeiterval(const void *kbuf, int *sp);
+EJDB_EXPORT const void *tctreeiterval(const void *kbuf, int *sp);
/* Get the value string bound to the key fetched from the iterator of a tree object.
`kstr' specifies the string of the iteration key.
The return value is the pointer to the region of the value of the corresponding record. */
-const char *tctreeiterval2(const char *kstr);
+EJDB_EXPORT const char *tctreeiterval2(const char *kstr);
/* Create an array of strings of all keys in a tree object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. Note that elements of the array
point to the inner objects, whose life duration is synchronous with the tree object. */
-const char **tctreekeys2(const TCTREE *tree, int *np);
+EJDB_EXPORT const char **tctreekeys2(const TCTREE *tree, int *np);
/* Create an array of strings of all values in a tree object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. Note that elements of the array
point to the inner objects, whose life duration is synchronous with the tree object. */
-const char **tctreevals2(const TCTREE *tree, int *np);
+EJDB_EXPORT const char **tctreevals2(const TCTREE *tree, int *np);
/* Extract a tree record from a serialized byte array.
corresponding record. `NULL' is returned when no record corresponds.
Because an additional zero code is appended at the end of the region of the return value,
the return value can be treated as a character string. */
-void *tctreeloadone(const void *ptr, int size, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tctreeloadone(const void *ptr, int size, const void *kbuf, int ksiz, int *sp);
/* Perform formatted output into a tree object.
with `s' but escapes meta characters of URL. `b' converts an integer to the string as binary
numbers. The other conversion character work as with each original.
The other arguments are used according to the format string. */
-void tctreeprintf(TCTREE *tree, const char *kstr, const char *format, ...);
+EJDB_EXPORT void tctreeprintf(TCTREE *tree, const char *kstr, const char *format, ...);
/* Create an on-memory hash database object.
The return value is the new on-memory hash database object.
The object can be shared by plural threads because of the internal mutex. */
-TCMDB *tcmdbnew(void);
+EJDB_EXPORT TCMDB *tcmdbnew(void);
/* Create an on-memory hash database object with specifying the number of the buckets.
`bnum' specifies the number of the buckets.
The return value is the new on-memory hash database object.
The object can be shared by plural threads because of the internal mutex. */
-TCMDB *tcmdbnew2(uint32_t bnum);
+EJDB_EXPORT TCMDB *tcmdbnew2(uint32_t bnum);
/* Delete an on-memory hash database object.
`mdb' specifies the on-memory hash database object. */
-void tcmdbdel(TCMDB *mdb);
+EJDB_EXPORT void tcmdbdel(TCMDB *mdb);
/* Store a record into an on-memory hash database object.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the database, it is overwritten. */
-void tcmdbput(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcmdbput(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into an on-memory hash database object.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If a record with the same key exists in the database, it is overwritten. */
-void tcmdbput2(TCMDB *mdb, const char *kstr, const char *vstr);
+EJDB_EXPORT void tcmdbput2(TCMDB *mdb, const char *kstr, const char *vstr);
/* Store a new record into an on-memory hash database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcmdbputkeep(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcmdbputkeep(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into an on-memory hash database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcmdbputkeep2(TCMDB *mdb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcmdbputkeep2(TCMDB *mdb, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the existing record in an on-memory hash database.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. */
-void tcmdbputcat(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcmdbputcat(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string at the end of the existing record in an on-memory hash database.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If there is no corresponding record, a new record is created. */
-void tcmdbputcat2(TCMDB *mdb, const char *kstr, const char *vstr);
+EJDB_EXPORT void tcmdbputcat2(TCMDB *mdb, const char *kstr, const char *vstr);
/* Remove a record of an on-memory hash database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcmdbout(TCMDB *mdb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcmdbout(TCMDB *mdb, const void *kbuf, int ksiz);
/* Remove a string record of an on-memory hash database object.
`kstr' specifies the string of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcmdbout2(TCMDB *mdb, const char *kstr);
+EJDB_EXPORT bool tcmdbout2(TCMDB *mdb, const char *kstr);
/* Retrieve a record in an on-memory hash database object.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tcmdbget(TCMDB *mdb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcmdbget(TCMDB *mdb, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in an on-memory hash database object.
`NULL' is returned when no record corresponds.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcmdbget2(TCMDB *mdb, const char *kstr);
+EJDB_EXPORT char *tcmdbget2(TCMDB *mdb, const char *kstr);
/* Get the size of the value of a record in an on-memory hash database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tcmdbvsiz(TCMDB *mdb, const void *kbuf, int ksiz);
+EJDB_EXPORT int tcmdbvsiz(TCMDB *mdb, const void *kbuf, int ksiz);
/* Get the size of the value of a string record in an on-memory hash database object.
`kstr' specifies the string of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tcmdbvsiz2(TCMDB *mdb, const char *kstr);
+EJDB_EXPORT int tcmdbvsiz2(TCMDB *mdb, const char *kstr);
/* Initialize the iterator of an on-memory hash database object.
`mdb' specifies the on-memory hash database object.
The iterator is used in order to access the key of every record stored in the on-memory
database. */
-void tcmdbiterinit(TCMDB *mdb);
+EJDB_EXPORT void tcmdbiterinit(TCMDB *mdb);
/* Get the next key of the iterator of an on-memory hash database object.
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. The order of iteration is assured to be the same as the stored
order. */
-void *tcmdbiternext(TCMDB *mdb, int *sp);
+EJDB_EXPORT void *tcmdbiternext(TCMDB *mdb, int *sp);
/* Get the next key string of the iterator of an on-memory hash database object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. The order of iteration is assured
to be the same as the stored order. */
-char *tcmdbiternext2(TCMDB *mdb);
+EJDB_EXPORT char *tcmdbiternext2(TCMDB *mdb);
/* Get forward matching keys in an on-memory hash database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tcmdbfwmkeys(TCMDB *mdb, const void *pbuf, int psiz, int max);
+EJDB_EXPORT TCLIST *tcmdbfwmkeys(TCMDB *mdb, const void *pbuf, int psiz, int max);
/* Get forward matching string keys in an on-memory hash database object.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. Note that this function
may be very slow because every key in the database is scanned. */
-TCLIST *tcmdbfwmkeys2(TCMDB *mdb, const char *pstr, int max);
+EJDB_EXPORT TCLIST *tcmdbfwmkeys2(TCMDB *mdb, const char *pstr, int max);
/* Get the number of records stored in an on-memory hash database object.
`mdb' specifies the on-memory hash database object.
The return value is the number of the records stored in the database. */
-uint64_t tcmdbrnum(TCMDB *mdb);
+EJDB_EXPORT uint64_t tcmdbrnum(TCMDB *mdb);
/* Get the total size of memory used in an on-memory hash database object.
`mdb' specifies the on-memory hash database object.
The return value is the total size of memory used in the database. */
-uint64_t tcmdbmsiz(TCMDB *mdb);
+EJDB_EXPORT uint64_t tcmdbmsiz(TCMDB *mdb);
/* Add an integer to a record in an on-memory hash database object.
The return value is the summation value.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tcmdbaddint(TCMDB *mdb, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tcmdbaddint(TCMDB *mdb, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in an on-memory hash database object.
The return value is the summation value.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tcmdbadddouble(TCMDB *mdb, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tcmdbadddouble(TCMDB *mdb, const void *kbuf, int ksiz, double num);
/* Clear an on-memory hash database object.
`mdb' specifies the on-memory hash database object.
All records are removed. */
-void tcmdbvanish(TCMDB *mdb);
+EJDB_EXPORT void tcmdbvanish(TCMDB *mdb);
/* Remove front records of an on-memory hash database object.
`mdb' specifies the on-memory hash database object.
`num' specifies the number of records to be removed. */
-void tcmdbcutfront(TCMDB *mdb, int num);
+EJDB_EXPORT void tcmdbcutfront(TCMDB *mdb, int num);
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the map, it is overwritten. The record is moved to
the tail. */
-void tcmdbput3(TCMDB *mdb, const void *kbuf, int ksiz, const char *vbuf, int vsiz);
+EJDB_EXPORT void tcmdbput3(TCMDB *mdb, const void *kbuf, int ksiz, const char *vbuf, int vsiz);
/* Store a record of the value of two regions into an on-memory hash database object.
`lvbuf' specifies the pointer to the latter region of the value.
`lvsiz' specifies the size of the latter region of the value.
If a record with the same key exists in the database, it is overwritten. */
-void tcmdbput4(TCMDB *mdb, const void *kbuf, int ksiz,
+EJDB_EXPORT void tcmdbput4(TCMDB *mdb, const void *kbuf, int ksiz,
const void *fvbuf, int fvsiz, const void *lvbuf, int lvsiz);
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. */
-void tcmdbputcat3(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcmdbputcat3(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a record into a on-memory hash database object with a duplication handler.
`op' specifies an arbitrary pointer to be given as a parameter of the callback function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tcmdbputproc(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tcmdbputproc(TCMDB *mdb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
is allocated with the `malloc' call, it should be released with the `free' call when it is no
longer in use. The internal region of the returned record is moved to the tail so that the
record will survive for a time under LRU cache algorithm removing records from the head. */
-void *tcmdbget3(TCMDB *mdb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcmdbget3(TCMDB *mdb, const void *kbuf, int ksiz, int *sp);
/* Initialize the iterator of an on-memory map database object in front of a key.
`kbuf' specifies the pointer to the region of the key.
`ksiz' specifies the size of the region of the key.
If there is no record corresponding the condition, the iterator is not modified. */
-void tcmdbiterinit2(TCMDB *mdb, const void *kbuf, int ksiz);
+EJDB_EXPORT void tcmdbiterinit2(TCMDB *mdb, const void *kbuf, int ksiz);
/* Initialize the iterator of an on-memory map database object in front of a key string.
`mdb' specifies the on-memory map database object.
`kstr' specifies the string of the key.
If there is no record corresponding the condition, the iterator is not modified. */
-void tcmdbiterinit3(TCMDB *mdb, const char *kstr);
+EJDB_EXPORT void tcmdbiterinit3(TCMDB *mdb, const char *kstr);
/* Process each record atomically of an on-memory hash database object.
or false to stop iteration.
`op' specifies an arbitrary pointer to be given as a parameter of the iterator function. If
it is not needed, `NULL' can be specified. */
-void tcmdbforeach(TCMDB *mdb, TCITER iter, void *op);
+EJDB_EXPORT void tcmdbforeach(TCMDB *mdb, TCITER iter, void *op);
/* Create an on-memory tree database object.
The return value is the new on-memory tree database object.
The object can be shared by plural threads because of the internal mutex. */
-TCNDB *tcndbnew(void);
+EJDB_EXPORT TCNDB *tcndbnew(void);
/* Create an on-memory tree database object with specifying the custom comparison function.
The default comparison function compares keys of two records by lexical order. The functions
`tccmplexical' (dafault), `tccmpdecimal', `tccmpint32', and `tccmpint64' are built-in. The
object can be shared by plural threads because of the internal mutex. */
-TCNDB *tcndbnew2(TCCMP cmp, void *cmpop);
+EJDB_EXPORT TCNDB *tcndbnew2(TCCMP cmp, void *cmpop);
/* Delete an on-memory tree database object.
`ndb' specifies the on-memory tree database object. */
-void tcndbdel(TCNDB *ndb);
+EJDB_EXPORT void tcndbdel(TCNDB *ndb);
/* Store a record into an on-memory tree database object.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the database, it is overwritten. */
-void tcndbput(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcndbput(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a string record into an on-memory tree database object.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If a record with the same key exists in the database, it is overwritten. */
-void tcndbput2(TCNDB *ndb, const char *kstr, const char *vstr);
+EJDB_EXPORT void tcndbput2(TCNDB *ndb, const char *kstr, const char *vstr);
/* Store a new record into an on-memory tree database object.
`vsiz' specifies the size of the region of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcndbputkeep(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcndbputkeep(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new string record into an on-memory tree database object.
`vstr' specifies the string of the value.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. */
-bool tcndbputkeep2(TCNDB *ndb, const char *kstr, const char *vstr);
+EJDB_EXPORT bool tcndbputkeep2(TCNDB *ndb, const char *kstr, const char *vstr);
/* Concatenate a value at the end of the existing record in an on-memory tree database.
`vbuf' specifies the pointer to the region of the value.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. */
-void tcndbputcat(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcndbputcat(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a string at the end of the existing record in an on-memory tree database.
`kstr' specifies the string of the key.
`vstr' specifies the string of the value.
If there is no corresponding record, a new record is created. */
-void tcndbputcat2(TCNDB *ndb, const char *kstr, const char *vstr);
+EJDB_EXPORT void tcndbputcat2(TCNDB *ndb, const char *kstr, const char *vstr);
/* Remove a record of an on-memory tree database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcndbout(TCNDB *ndb, const void *kbuf, int ksiz);
+EJDB_EXPORT bool tcndbout(TCNDB *ndb, const void *kbuf, int ksiz);
/* Remove a string record of an on-memory tree database object.
`kstr' specifies the string of the key.
If successful, the return value is true. False is returned when no record corresponds to
the specified key. */
-bool tcndbout2(TCNDB *ndb, const char *kstr);
+EJDB_EXPORT bool tcndbout2(TCNDB *ndb, const char *kstr);
/* Retrieve a record in an on-memory tree database object.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-void *tcndbget(TCNDB *ndb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcndbget(TCNDB *ndb, const void *kbuf, int ksiz, int *sp);
/* Retrieve a string record in an on-memory tree database object.
`NULL' is returned when no record corresponds.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcndbget2(TCNDB *ndb, const char *kstr);
+EJDB_EXPORT char *tcndbget2(TCNDB *ndb, const char *kstr);
/* Get the size of the value of a record in an on-memory tree database object.
`ksiz' specifies the size of the region of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tcndbvsiz(TCNDB *ndb, const void *kbuf, int ksiz);
+EJDB_EXPORT int tcndbvsiz(TCNDB *ndb, const void *kbuf, int ksiz);
/* Get the size of the value of a string record in an on-memory tree database object.
`kstr' specifies the string of the key.
If successful, the return value is the size of the value of the corresponding record, else,
it is -1. */
-int tcndbvsiz2(TCNDB *ndb, const char *kstr);
+EJDB_EXPORT int tcndbvsiz2(TCNDB *ndb, const char *kstr);
/* Initialize the iterator of an on-memory tree database object.
`ndb' specifies the on-memory tree database object.
The iterator is used in order to access the key of every record stored in the on-memory
database. */
-void tcndbiterinit(TCNDB *ndb);
+EJDB_EXPORT void tcndbiterinit(TCNDB *ndb);
/* Get the next key of the iterator of an on-memory tree database object.
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. The order of iteration is assured to be the same as the stored
order. */
-void *tcndbiternext(TCNDB *ndb, int *sp);
+EJDB_EXPORT void *tcndbiternext(TCNDB *ndb, int *sp);
/* Get the next key string of the iterator of an on-memory tree database object.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. The order of iteration is assured
to be the same as the stored order. */
-char *tcndbiternext2(TCNDB *ndb);
+EJDB_EXPORT char *tcndbiternext2(TCNDB *ndb);
/* Get forward matching keys in an on-memory tree database object.
It returns an empty list even if no key corresponds.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcndbfwmkeys(TCNDB *ndb, const void *pbuf, int psiz, int max);
+EJDB_EXPORT TCLIST *tcndbfwmkeys(TCNDB *ndb, const void *pbuf, int psiz, int max);
/* Get forward matching string keys in an on-memory tree database object.
It returns an empty list even if no key corresponds.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcndbfwmkeys2(TCNDB *ndb, const char *pstr, int max);
+EJDB_EXPORT TCLIST *tcndbfwmkeys2(TCNDB *ndb, const char *pstr, int max);
/* Get the number of records stored in an on-memory tree database object.
`ndb' specifies the on-memory tree database object.
The return value is the number of the records stored in the database. */
-uint64_t tcndbrnum(TCNDB *ndb);
+EJDB_EXPORT uint64_t tcndbrnum(TCNDB *ndb);
/* Get the total size of memory used in an on-memory tree database object.
`ndb' specifies the on-memory tree database object.
The return value is the total size of memory used in the database. */
-uint64_t tcndbmsiz(TCNDB *ndb);
+EJDB_EXPORT uint64_t tcndbmsiz(TCNDB *ndb);
/* Add an integer to a record in an on-memory tree database object.
The return value is the summation value.
If the corresponding record exists, the value is treated as an integer and is added to. If no
record corresponds, a new record of the additional value is stored. */
-int tcndbaddint(TCNDB *ndb, const void *kbuf, int ksiz, int num);
+EJDB_EXPORT int tcndbaddint(TCNDB *ndb, const void *kbuf, int ksiz, int num);
/* Add a real number to a record in an on-memory tree database object.
The return value is the summation value.
If the corresponding record exists, the value is treated as a real number and is added to. If
no record corresponds, a new record of the additional value is stored. */
-double tcndbadddouble(TCNDB *ndb, const void *kbuf, int ksiz, double num);
+EJDB_EXPORT double tcndbadddouble(TCNDB *ndb, const void *kbuf, int ksiz, double num);
/* Clear an on-memory tree database object.
`ndb' specifies the on-memory tree database object.
All records are removed. */
-void tcndbvanish(TCNDB *ndb);
+EJDB_EXPORT void tcndbvanish(TCNDB *ndb);
/* Remove fringe records of an on-memory tree database object.
`ndb' specifies the on-memory tree database object.
`num' specifies the number of records to be removed. */
-void tcndbcutfringe(TCNDB *ndb, int num);
+EJDB_EXPORT void tcndbcutfringe(TCNDB *ndb, int num);
`vsiz' specifies the size of the region of the value.
If a record with the same key exists in the database, it is overwritten. The structure of the
tree is not modifed by this function. */
-void tcndbput3(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcndbput3(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a new record into a on-memory tree database object without balancing nodes.
If successful, the return value is true, else, it is false.
If a record with the same key exists in the database, this function has no effect. The
structure of the tree is not modifed by this function. */
-bool tcndbputkeep3(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT bool tcndbputkeep3(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Concatenate a value in a on-memory tree database without balancing nodes.
`vsiz' specifies the size of the region of the value.
If there is no corresponding record, a new record is created. The structure of the tree is
not modifed by this function. */
-void tcndbputcat3(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
+EJDB_EXPORT void tcndbputcat3(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz);
/* Store a record into a on-memory tree database object with a duplication handler.
`op' specifies an arbitrary pointer to be given as a parameter of the callback function. If
it is not needed, `NULL' can be specified.
If successful, the return value is true, else, it is false. */
-bool tcndbputproc(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
+EJDB_EXPORT bool tcndbputproc(TCNDB *ndb, const void *kbuf, int ksiz, const void *vbuf, int vsiz,
TCPDPROC proc, void *op);
the return value can be treated as a character string. Because the region of the return value
is allocated with the `malloc' call, it should be released with the `free' call when it is no
longer in use. The structure of the tree is not modifed by this function. */
-void *tcndbget3(TCNDB *ndb, const void *kbuf, int ksiz, int *sp);
+EJDB_EXPORT void *tcndbget3(TCNDB *ndb, const void *kbuf, int ksiz, int *sp);
/* Initialize the iterator of an on-memory tree database object in front of a key.
`ksiz' specifies the size of the region of the key.
The iterator is set to the first record corresponding the key or the next substitute if
completely matching record does not exist. */
-void tcndbiterinit2(TCNDB *ndb, const void *kbuf, int ksiz);
+EJDB_EXPORT void tcndbiterinit2(TCNDB *ndb, const void *kbuf, int ksiz);
/* Initialize the iterator of an on-memory tree database object in front of a key string.
`kstr' specifies the string of the key.
The iterator is set to the first record corresponding the key or the next substitute if
completely matching record does not exist. */
-void tcndbiterinit3(TCNDB *ndb, const char *kstr);
+EJDB_EXPORT void tcndbiterinit3(TCNDB *ndb, const char *kstr);
/* Process each record atomically of an on-memory tree database object.
or false to stop iteration.
`op' specifies an arbitrary pointer to be given as a parameter of the iterator function. If
it is not needed, `NULL' can be specified. */
-void tcndbforeach(TCNDB *ndb, TCITER iter, void *op);
+EJDB_EXPORT void tcndbforeach(TCNDB *ndb, TCITER iter, void *op);
/* Create a memory pool object.
The return value is the new memory pool object. */
-TCMPOOL *tcmpoolnew(void);
+EJDB_EXPORT TCMPOOL *tcmpoolnew(void);
/* Delete a memory pool object.
`mpool' specifies the memory pool object.
Note that the deleted object and its derivatives can not be used anymore. */
-void tcmpooldel(TCMPOOL *mpool);
+EJDB_EXPORT void tcmpooldel(TCMPOOL *mpool);
/* Relegate an arbitrary object to a memory pool object.
The return value is the pointer to the given object.
This function assures that the specified object is deleted when the memory pool object is
deleted. */
-void *tcmpoolpush(TCMPOOL *mpool, void *ptr, void (*del)(void *));
+EJDB_EXPORT void *tcmpoolpush(TCMPOOL *mpool, void *ptr, void (*del)(void *));
/* Relegate an allocated region to a memory pool object.
The return value is the pointer to the given object.
This function assures that the specified region is released when the memory pool object is
deleted. */
-void *tcmpoolpushptr(TCMPOOL *mpool, void *ptr);
+EJDB_EXPORT void *tcmpoolpushptr(TCMPOOL *mpool, void *ptr);
/* Relegate an extensible string object to a memory pool object.
The return value is the pointer to the given object.
This function assures that the specified object is deleted when the memory pool object is
deleted. */
-TCXSTR *tcmpoolpushxstr(TCMPOOL *mpool, TCXSTR *xstr);
+EJDB_EXPORT TCXSTR *tcmpoolpushxstr(TCMPOOL *mpool, TCXSTR *xstr);
/* Relegate a list object to a memory pool object.
The return value is the pointer to the given object.
This function assures that the specified object is deleted when the memory pool object is
deleted. */
-TCLIST *tcmpoolpushlist(TCMPOOL *mpool, TCLIST *list);
+EJDB_EXPORT TCLIST *tcmpoolpushlist(TCMPOOL *mpool, TCLIST *list);
/* Relegate a map object to a memory pool object.
The return value is the pointer to the given object.
This function assures that the specified object is deleted when the memory pool object is
deleted. */
-TCMAP *tcmpoolpushmap(TCMPOOL *mpool, TCMAP *map);
+EJDB_EXPORT TCMAP *tcmpoolpushmap(TCMPOOL *mpool, TCMAP *map);
/* Relegate a tree object to a memory pool object.
The return value is the pointer to the given object.
This function assures that the specified object is deleted when the memory pool object is
deleted. */
-TCTREE *tcmpoolpushtree(TCMPOOL *mpool, TCTREE *tree);
+EJDB_EXPORT TCTREE *tcmpoolpushtree(TCMPOOL *mpool, TCTREE *tree);
/* Allocate a region relegated to a memory pool object.
`mpool' specifies the memory pool object.
The return value is the pointer to the allocated region under the memory pool. */
-void *tcmpoolmalloc(TCMPOOL *mpool, size_t size);
+EJDB_EXPORT void *tcmpoolmalloc(TCMPOOL *mpool, size_t size);
/* Create an extensible string object relegated to a memory pool object.
The return value is the new extensible string object under the memory pool. */
-TCXSTR *tcmpoolxstrnew(TCMPOOL *mpool);
+EJDB_EXPORT TCXSTR *tcmpoolxstrnew(TCMPOOL *mpool);
/* Create a list object relegated to a memory pool object.
The return value is the new list object under the memory pool. */
-TCLIST *tcmpoollistnew(TCMPOOL *mpool);
+EJDB_EXPORT TCLIST *tcmpoollistnew(TCMPOOL *mpool);
/* Create a map object relegated to a memory pool object.
The return value is the new map object under the memory pool. */
-TCMAP *tcmpoolmapnew(TCMPOOL *mpool);
+EJDB_EXPORT TCMAP *tcmpoolmapnew(TCMPOOL *mpool);
/* Create a tree object relegated to a memory pool object.
The return value is the new tree object under the memory pool. */
-TCTREE *tcmpooltreenew(TCMPOOL *mpool);
+EJDB_EXPORT TCTREE *tcmpooltreenew(TCMPOOL *mpool);
/* Remove the most recently installed cleanup handler of a memory pool object.
`mpool' specifies the memory pool object.
`exe' specifies whether to execute the destructor of the removed handler. */
-void tcmpoolpop(TCMPOOL *mpool, bool exe);
+EJDB_EXPORT void tcmpoolpop(TCMPOOL *mpool, bool exe);
/* Remove all cleanup handler of a memory pool object.
`mpool' specifies the memory pool object.
`exe' specifies whether to execute the destructors of the removed handlers. */
-void tcmpoolclear(TCMPOOL *mpool, bool exe);
+EJDB_EXPORT void tcmpoolclear(TCMPOOL *mpool, bool exe);
/* Get the global memory pool object.
The return value is the global memory pool object.
The global memory pool object is a singleton and assured to be deleted when the porcess is
terminating normally. */
-TCMPOOL *tcmpoolglobal(void);
+EJDB_EXPORT TCMPOOL *tcmpoolglobal(void);
`a' specifies an integer.
`b' specifies the other integer.
The return value is the larger value of the two. */
-long tclmax(long a, long b);
+EJDB_EXPORT long tclmax(long a, long b);
/* Get the lesser value of two integers.
`a' specifies an integer.
`b' specifies the other integer.
The return value is the lesser value of the two. */
-long tclmin(long a, long b);
+EJDB_EXPORT long tclmin(long a, long b);
/* Get a random number as long integer based on uniform distribution.
The return value is the random number between 0 and `ULONG_MAX'.
This function uses the random number source device and generates a real random number if
possible. */
-unsigned long tclrand(void);
+EJDB_EXPORT unsigned long tclrand(void);
/* Get a random number as double decimal based on uniform distribution.
The return value is the random number equal to or greater than 0, and less than 1.0.
This function uses the random number source device and generates a real random number if
possible. */
-double tcdrand(void);
+EJDB_EXPORT double tcdrand(void);
/* Get a random number as double decimal based on normal distribution.
The return value is the random number.
This function uses the random number source device and generates a real random number if
possible. */
-double tcdrandnd(double avg, double sd);
+EJDB_EXPORT double tcdrandnd(double avg, double sd);
/* Compare two strings with case insensitive evaluation.
`bstr' specifies of the other string.
The return value is positive if the former is big, negative if the latter is big, 0 if both
are equivalent. */
-int tcstricmp(const char *astr, const char *bstr);
+EJDB_EXPORT int tcstricmp(const char *astr, const char *bstr);
/* Check whether a string begins with a key.
`str' specifies the target string.
`key' specifies the forward matching key string.
The return value is true if the target string begins with the key, else, it is false. */
-bool tcstrfwm(const char *str, const char *key);
+EJDB_EXPORT bool tcstrfwm(const char *str, const char *key);
/* Check whether a string begins with a key with case insensitive evaluation.
`str' specifies the target string.
`key' specifies the forward matching key string.
The return value is true if the target string begins with the key, else, it is false. */
-bool tcstrifwm(const char *str, const char *key);
+EJDB_EXPORT bool tcstrifwm(const char *str, const char *key);
/* Check whether a string ends with a key.
`str' specifies the target string.
`key' specifies the backward matching key string.
The return value is true if the target string ends with the key, else, it is false. */
-bool tcstrbwm(const char *str, const char *key);
+EJDB_EXPORT bool tcstrbwm(const char *str, const char *key);
/* Check whether a string ends with a key with case insensitive evaluation.
`str' specifies the target string.
`key' specifies the backward matching key string.
The return value is true if the target string ends with the key, else, it is false. */
-bool tcstribwm(const char *str, const char *key);
+EJDB_EXPORT bool tcstribwm(const char *str, const char *key);
/* Calculate the edit distance of two strings.
`bstr' specifies of the other string.
The return value is the edit distance which is known as the Levenshtein distance. The cost is
calculated by byte. */
-int tcstrdist(const char *astr, const char *bstr);
+EJDB_EXPORT int tcstrdist(const char *astr, const char *bstr);
/* Calculate the edit distance of two UTF-8 strings.
`bstr' specifies of the other string.
The return value is the edit distance which is known as the Levenshtein distance. The cost is
calculated by Unicode character. */
-int tcstrdistutf(const char *astr, const char *bstr);
+EJDB_EXPORT int tcstrdistutf(const char *astr, const char *bstr);
/* Convert the letters of a string into upper case.
`str' specifies the string to be converted.
The return value is the string itself. */
-char *tcstrtoupper(char *str);
+EJDB_EXPORT char *tcstrtoupper(char *str);
/* Convert the letters of a string into lower case.
`str' specifies the string to be converted.
The return value is the string itself. */
-char *tcstrtolower(char *str);
+EJDB_EXPORT char *tcstrtolower(char *str);
/* Cut space characters at head or tail of a string.
`str' specifies the string to be converted.
The return value is the string itself. */
-char *tcstrtrim(char *str);
+EJDB_EXPORT char *tcstrtrim(char *str);
/* Squeeze space characters in a string and trim it.
`str' specifies the string to be converted.
The return value is the string itself. */
-char *tcstrsqzspc(char *str);
+EJDB_EXPORT char *tcstrsqzspc(char *str);
/* Substitute characters in a string.
`sstr' specifies the string containing characters to be substituted.
If the substitute string is shorter then the replacement string, corresponding characters are
removed. */
-char *tcstrsubchr(char *str, const char *rstr, const char *sstr);
+EJDB_EXPORT char *tcstrsubchr(char *str, const char *rstr, const char *sstr);
/* Count the number of characters in a string of UTF-8.
`str' specifies the string of UTF-8.
The return value is the number of characters in the string. */
-int tcstrcntutf(const char *str);
+EJDB_EXPORT int tcstrcntutf(const char *str);
/* Cut a string of UTF-8 at the specified number of characters.
`str' specifies the string of UTF-8.
`num' specifies the number of characters to be kept.
The return value is the string itself. */
-char *tcstrcututf(char *str, int num);
+EJDB_EXPORT char *tcstrcututf(char *str, int num);
/* Convert a UTF-8 string into a UCS-2 array.
size of the buffer should be sufficient.
`np' specifies the pointer to a variable into which the number of elements of the result array
is assigned. */
-void tcstrutftoucs(const char *str, uint16_t *ary, int *np);
+EJDB_EXPORT void tcstrutftoucs(const char *str, uint16_t *ary, int *np);
/* Convert a UCS-2 array into a UTF-8 string.
`str' specifies the pointer to the region into which the result UTF-8 string is written. The
size of the buffer should be sufficient.
The return value is the length of the result string. */
-int tcstrucstoutf(const uint16_t *ary, int num, char *str);
+EJDB_EXPORT int tcstrucstoutf(const uint16_t *ary, int num, char *str);
/* Create a list object by splitting a string.
If two delimiters are successive, it is assumed that an empty element is between the two.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcstrsplit(const char *str, const char *delims);
+EJDB_EXPORT TCLIST *tcstrsplit(const char *str, const char *delims);
/* Create a string by joining all elements of a list object.
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcstrjoin(const TCLIST *list, char delim);
+EJDB_EXPORT char *tcstrjoin(const TCLIST *list, char delim);
/* Convert a string to an integer.
The return value is the integer. If the string does not contain numeric expression, 0 is
returned.
This function is equivalent to `atoll' except that it does not depend on the locale. */
-int64_t tcatoi(const char *str);
+EJDB_EXPORT int64_t tcatoi(const char *str);
/* Convert a string with a metric prefix to an integer.
The return value is the integer. If the string does not contain numeric expression, 0 is
returned. If the integer overflows the domain, `INT64_MAX' or `INT64_MIN' is returned
according to the sign. */
-int64_t tcatoix(const char *str);
+EJDB_EXPORT int64_t tcatoix(const char *str);
/* Convert a string to a real number.
The return value is the real number. If the string does not contain numeric expression, 0.0
is returned.
This function is equivalent to `atof' except that it does not depend on the locale. */
-double tcatof(const char *str);
+EJDB_EXPORT double tcatof(const char *str);
/**
* @param precision Number of signs after dot.
* @return
*/
-int tcftoa(long double f, char *buf, int max, int precision);
+EJDB_EXPORT int tcftoa(long double f, char *buf, int max, int precision);
/* Check whether a string matches a regular expression.
`regex' specifies the regular expression string. If it begins with `*', the trailing
substring is used as a case-insensitive regular expression.
The return value is true if matching is success, else, it is false. */
-bool tcregexmatch(const char *str, const char *regex);
+EJDB_EXPORT bool tcregexmatch(const char *str, const char *regex);
/* Replace each substring matching a regular expression string.
of the original string is returned.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcregexreplace(const char *str, const char *regex, const char *alt);
+EJDB_EXPORT char *tcregexreplace(const char *str, const char *regex, const char *alt);
/* Get the MD5 hash value of a serial object.
`size' specifies the size of the region.
`buf' specifies the pointer to the region into which the result string is written. The size
of the buffer should be equal to or more than 48 bytes. */
-void tcmd5hash(const void *ptr, int size, char *buf);
+EJDB_EXPORT void tcmd5hash(const void *ptr, int size, char *buf);
/* Cipher or decipher a serial object with the Arcfour stream cipher.
`ksiz' specifies the size of the region of the cipher key.
`obuf' specifies the pointer to the region into which the result data is written. The size
of the buffer should be equal to or more than the input region. */
-void tcarccipher(const void *ptr, int size, const void *kbuf, int ksiz, void *obuf);
+EJDB_EXPORT void tcarccipher(const void *ptr, int size, const void *kbuf, int ksiz, void *obuf);
/* Get the time of day in seconds.
The return value is the time of day in seconds. The accuracy is in microseconds. */
-double tctime(void);
+EJDB_EXPORT double tctime(void);
/* Get time in milleconds since Epoch. */
-unsigned long tcmstime(void);
+EJDB_EXPORT unsigned long tcmstime(void);
/* Get the Gregorian calendar of a time.
it is not used.
`secp' specifies the pointer to a variable to which the seconds is assigned. If it is `NULL',
it is not used. */
-void tccalendar(int64_t t, int jl, int *yearp, int *monp, int *dayp,
+EJDB_EXPORT void tccalendar(int64_t t, int jl, int *yearp, int *monp, int *dayp,
int *hourp, int *minp, int *secp);
`buf' specifies the pointer to the region into which the result string is written. The size
of the buffer should be equal to or more than 48 bytes.
W3CDTF represents a date as "YYYY-MM-DDThh:mm:ddTZD". */
-void tcdatestrwww(int64_t t, int jl, char *buf);
+EJDB_EXPORT void tcdatestrwww(int64_t t, int jl, char *buf);
/* Format a date as a string in RFC 1123 format.
`buf' specifies the pointer to the region into which the result string is written. The size
of the buffer should be equal to or more than 48 bytes.
RFC 1123 format represents a date as "Wdy, DD-Mon-YYYY hh:mm:dd TZD". */
-void tcdatestrhttp(int64_t t, int jl, char *buf);
+EJDB_EXPORT void tcdatestrhttp(int64_t t, int jl, char *buf);
/* Get the time value of a date string.
can be trailed by "s" for in seconds, "m" for in minutes, "h" for in hours, and "d" for in
days.
The return value is the time value of the date or `INT64_MIN' if the format is invalid. */
-int64_t tcstrmktime(const char *str);
+EJDB_EXPORT int64_t tcstrmktime(const char *str);
/* Get the jet lag of the local time.
The return value is the jet lag of the local time in seconds. */
-int tcjetlag(void);
+EJDB_EXPORT int tcjetlag(void);
/* Get the day of week of a date.
`mon' specifies the month of the date.
`day' specifies the day of the date.
The return value is the day of week of the date. 0 means Sunday and 6 means Saturday. */
-int tcdayofweek(int year, int mon, int day);
+EJDB_EXPORT int tcdayofweek(int year, int mon, int day);
/* Check whether a string is numeric completely or not.
`str' specifies the string to be checked.
The return value is true if the string is numeric, else, it is false. */
-bool tcstrisnum(const char *str);
-bool tcstrisintnum(const char *str, int len);
+EJDB_EXPORT bool tcstrisnum(const char *str);
+EJDB_EXPORT bool tcstrisintnum(const char *str, int len);
/* Convert a hexadecimal string to an integer.
`str' specifies the string.
The return value is the integer. If the string does not contain numeric expression, 0 is
returned. */
-int64_t tcatoih(const char *str);
+EJDB_EXPORT int64_t tcatoih(const char *str);
/* Skip space characters at head of a string.
`str' specifies the string.
The return value is the pointer to the first non-space character. */
-const char *tcstrskipspc(const char *str);
+EJDB_EXPORT const char *tcstrskipspc(const char *str);
/* Normalize a UTF-8 string.
alphabetical characters with accent marks are normalized without accent marks, `TCUNWIDTH'
specifies that full-width characters are normalized into half-width characters.
The return value is the string itself. */
-char *tcstrutfnorm(char *str, int opts);
+EJDB_EXPORT char *tcstrutfnorm(char *str, int opts);
/* Normalize a UCS-2 array.
alphabetical characters with accent marks are normalized without accent marks, `TCUNWIDTH'
specifies that full-width characters are normalized into half-width characters.
The return value is the number of elements of the result array. */
-int tcstrucsnorm(uint16_t *ary, int num, int opts);
+EJDB_EXPORT int tcstrucsnorm(uint16_t *ary, int num, int opts);
/* Generate a keyword-in-context string from a text and keywords.
The return value is the list object whose elements are strings around keywords.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcstrkwic(const char *str, const TCLIST *words, int width, int opts);
+EJDB_EXPORT TCLIST *tcstrkwic(const char *str, const TCLIST *words, int width, int opts);
/* Tokenize a text separating by white space characters.
The return value is the list object whose elements are extracted tokens.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcstrtokenize(const char *str);
+EJDB_EXPORT TCLIST *tcstrtokenize(const char *str);
/* Create a list object by splitting a region by zero code.
If two delimiters are successive, it is assumed that an empty element is between the two.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcstrsplit2(const void *ptr, int size);
+EJDB_EXPORT TCLIST *tcstrsplit2(const void *ptr, int size);
/* Create a map object by splitting a string.
The return value is a map object of the split records.
Because the object of the return value is created with the function `tcmapnew', it should be
deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tcstrsplit3(const char *str, const char *delims);
+EJDB_EXPORT TCMAP *tcstrsplit3(const char *str, const char *delims);
/* Create a map object by splitting a region by zero code.
The return value is a map object of the split records.
Because the object of the return value is created with the function `tcmapnew', it should be
deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tcstrsplit4(const void *ptr, int size);
+EJDB_EXPORT TCMAP *tcstrsplit4(const void *ptr, int size);
/* Create a region separated by zero code by joining all elements of a list object.
value is assigned.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-void *tcstrjoin2(const TCLIST *list, int *sp);
+EJDB_EXPORT void *tcstrjoin2(const TCLIST *list, int *sp);
/* Create a string by joining all records of a map object.
one after the other.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcstrjoin3(const TCMAP *map, char delim);
+EJDB_EXPORT char *tcstrjoin3(const TCMAP *map, char delim);
/* Create a region separated by zero code by joining all records of a map object.
value is assigned.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-void *tcstrjoin4(const TCMAP *map, int *sp);
+EJDB_EXPORT void *tcstrjoin4(const TCMAP *map, int *sp);
/* Sort top records of an array.
`compar' specifies the pointer to comparing function. The two arguments specify the pointers
of elements. The comparing function should returns positive if the former is big, negative
if the latter is big, 0 if both are equal. */
-void tctopsort(void *base, size_t nmemb, size_t size, size_t top,
+EJDB_EXPORT void tctopsort(void *base, size_t nmemb, size_t size, size_t top,
int(*compar)(const void *, const void *));
/* Suspend execution of the current thread.
`sec' specifies the interval of the suspension in seconds.
If successful, the return value is true, else, it is false. */
-bool tcsleep(double sec);
+EJDB_EXPORT bool tcsleep(double sec);
/* Get the current system information.
memory.
Because the object of the return value is created with the function `tcmapnew', it should be
deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tcsysinfo(void);
+EJDB_EXPORT TCMAP *tcsysinfo(void);
/* Create a consistent hashing object.
The return value is the new consistent hashing object.
Consistent hashing is useful because the addition or removal of one node does not
significantly change the mapping of keys to nodes. */
-TCCHIDX *tcchidxnew(int range);
+EJDB_EXPORT TCCHIDX *tcchidxnew(int range);
/* Delete a consistent hashing object.
`chidx' specifies the consistent hashing object. */
-void tcchidxdel(TCCHIDX *chidx);
+EJDB_EXPORT void tcchidxdel(TCCHIDX *chidx);
/* Get the consistent hashing value of a record.
`ptr' specifies the pointer to the region of the record.
`size' specifies the size of the region.
The return value is the hash value of the record. */
-int tcchidxhash(TCCHIDX *chidx, const void *ptr, int size);
+EJDB_EXPORT int tcchidxhash(TCCHIDX *chidx, const void *ptr, int size);
invalid.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcrealpath(const char *path);
+EJDB_EXPORT char *tcrealpath(const char *path);
/* Get the status information of a file.
`ntimep' specifies the pointer to a variable into which the size of the file is assigned. If
it is `NULL', it is ignored.
If successful, the return value is true, else, it is false. */
-bool tcstatfile(const char *path, bool *isdirp, int64_t *sizep, int64_t *mtimep);
+EJDB_EXPORT bool tcstatfile(const char *path, bool *isdirp, int64_t *sizep, int64_t *mtimep);
/* Read whole data of a file.
return value can be treated as a character string. Because the region of the return value is
allocated with the `malloc' call, it should be released with the `free' call when when is no
longer in use. */
-void *tcreadfile(const char *path, int limit, int *sp);
+EJDB_EXPORT void *tcreadfile(const char *path, int limit, int *sp);
/* Read every line of a file.
Line separators are cut out. Because the object of the return value is created with the
function `tclistnew', it should be deleted with the function `tclistdel' when it is no longer
in use. */
-TCLIST *tcreadfilelines(const char *path);
+EJDB_EXPORT TCLIST *tcreadfilelines(const char *path);
/* Write data into a file.
`ptr' specifies the pointer to the data region.
`size' specifies the size of the region.
If successful, the return value is true, else, it is false. */
-bool tcwritefile(const char *path, const void *ptr, int size);
+EJDB_EXPORT bool tcwritefile(const char *path, const void *ptr, int size);
/* Copy a file.
`dest' specifies the path of the destination file.
The return value is true if successful, else, it is false.
If the destination file exists, it is overwritten. */
-bool tccopyfile(const char *src, const char *dest);
+EJDB_EXPORT bool tccopyfile(const char *src, const char *dest);
/* Read names of files in a directory.
Links to the directory itself and to the parent directory are ignored.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcreaddir(const char *path);
+EJDB_EXPORT TCLIST *tcreaddir(const char *path);
/* Expand a pattern into a list of matched paths.
returned.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcglobpat(const char *pattern);
+EJDB_EXPORT TCLIST *tcglobpat(const char *pattern);
/* Remove a file or a directory and its sub ones recursively.
`path' specifies the path of the link.
If successful, the return value is true, else, it is false. False is returned when the link
does not exist or the permission is denied. */
-bool tcremovelink(const char *path);
+EJDB_EXPORT bool tcremovelink(const char *path);
+enum {
+ TCFSTART = 0, /* file start */
+ TCFCUR = 1, /* file current pos */
+ TCFEND = 2 /* file end */
+};
+
+/* File seek implementation */
+EJDB_EXPORT bool tcfseek(HANDLE fd, off_t off, int whence);
+
+
+EJDB_EXPORT bool tcftruncate(HANDLE fd, off_t length);
+
/* Write data into a file.
`fd' specifies the file descriptor.
`buf' specifies the buffer to be written.
`size' specifies the size of the buffer.
The return value is true if successful, else, it is false. */
-bool tcwrite(int fd, const void *buf, size_t size);
+EJDB_EXPORT bool tcwrite(HANDLE fd, const void *buf, size_t size);
/* Read data from a file.
`buf' specifies the buffer to store into.
`size' specifies the size of the buffer.
The return value is true if successful, else, it is false. */
-bool tcread(int fd, void *buf, size_t size);
+EJDB_EXPORT bool tcread(HANDLE fd, void *buf, size_t size);
/* Lock a file.
`ex' specifies whether an exclusive lock or a shared lock is performed.
`nb' specifies whether to request with non-blocking.
The return value is true if successful, else, it is false. */
-bool tclock(int fd, bool ex, bool nb);
+EJDB_EXPORT bool tclock(HANDLE fd, bool ex, bool nb);
/* Unlock a file.
`fd' specifies the file descriptor.
The return value is true if successful, else, it is false. */
-bool tcunlock(int fd);
+EJDB_EXPORT bool tcunlock(HANDLE fd);
/* Execute a shell command.
`anum' specifies the number of elements of the array.
The return value is the exit code of the command or `INT_MAX' on failure.
The command name and the arguments are quoted and meta characters are escaped. */
-int tcsystem(const char **args, int anum);
+EJDB_EXPORT int tcsystem(const char **args, int anum);
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tcurlencode(const char *ptr, int size);
+EJDB_EXPORT char *tcurlencode(const char *ptr, int size);
/* Decode a string encoded with URL encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-char *tcurldecode(const char *str, int *sp);
+EJDB_EXPORT char *tcurldecode(const char *str, int *sp);
/* Break up a URL into elements.
Supported schema are HTTP, HTTPS, FTP, and FILE. Absolute URL and relative URL are supported.
Because the object of the return value is created with the function `tcmapnew', it should be
deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tcurlbreak(const char *str);
+EJDB_EXPORT TCMAP *tcurlbreak(const char *str);
/* Resolve a relative URL with an absolute URL.
location from the base location is returned. Else, a copy of the target URL is returned.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcurlresolve(const char *base, const char *target);
+EJDB_EXPORT char *tcurlresolve(const char *base, const char *target);
/* Encode a serial object with Base64 encoding.
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tcbaseencode(const char *ptr, int size);
+EJDB_EXPORT char *tcbaseencode(const char *ptr, int size);
/* Decode a string encoded with Base64 encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-char *tcbasedecode(const char *str, int *sp);
+EJDB_EXPORT char *tcbasedecode(const char *str, int *sp);
/* Encode a serial object with Quoted-printable encoding.
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tcquoteencode(const char *ptr, int size);
+EJDB_EXPORT char *tcquoteencode(const char *ptr, int size);
/* Decode a string encoded with Quoted-printable encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-char *tcquotedecode(const char *str, int *sp);
+EJDB_EXPORT char *tcquotedecode(const char *str, int *sp);
/* Encode a string with MIME encoding.
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcmimeencode(const char *str, const char *encname, bool base);
+EJDB_EXPORT char *tcmimeencode(const char *str, const char *encname, bool base);
/* Decode a string encoded with MIME encoding.
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcmimedecode(const char *str, char *enp);
+EJDB_EXPORT char *tcmimedecode(const char *str, char *enp);
/* Split a string of MIME into headers and the body.
defined, the key "FILENAME" indicates the name. If the attribute name is defined, the key
"NAME" indicates the name. Because the region of the return value is allocated with the
`malloc' call, it should be released with the `free' call when it is no longer in use. */
-char *tcmimebreak(const char *ptr, int size, TCMAP *headers, int *sp);
+EJDB_EXPORT char *tcmimebreak(const char *ptr, int size, TCMAP *headers, int *sp);
/* Split multipart data of MIME into its parts.
The return value is a list object. Each element of the list is the data of a part.
Because the object of the return value is created with the function `tclistnew', it should be
deleted with the function `tclistdel' when it is no longer in use. */
-TCLIST *tcmimeparts(const char *ptr, int size, const char *boundary);
+EJDB_EXPORT TCLIST *tcmimeparts(const char *ptr, int size, const char *boundary);
/* Encode a serial object with hexadecimal encoding.
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tchexencode(const char *ptr, int size);
+EJDB_EXPORT char *tchexencode(const char *ptr, int size);
/* Decode a string encoded with hexadecimal encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when
it is no longer in use. */
-char *tchexdecode(const char *str, int *sp);
+EJDB_EXPORT char *tchexdecode(const char *str, int *sp);
/* Compress a serial object with Packbits encoding.
If successful, the return value is the pointer to the result object, else, it is `NULL'.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcpackencode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcpackencode(const char *ptr, int size, int *sp);
/* Decompress a serial object compressed with Packbits encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcpackdecode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcpackdecode(const char *ptr, int size, int *sp);
/* Compress a serial object with TCBS encoding.
If successful, the return value is the pointer to the result object, else, it is `NULL'.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcbsencode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcbsencode(const char *ptr, int size, int *sp);
/* Decompress a serial object compressed with TCBS encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcbsdecode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcbsdecode(const char *ptr, int size, int *sp);
/* Compress a serial object with Deflate encoding.
If successful, the return value is the pointer to the result object, else, it is `NULL'.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcdeflate(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcdeflate(const char *ptr, int size, int *sp);
/* Decompress a serial object compressed with Deflate encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcinflate(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcinflate(const char *ptr, int size, int *sp);
/* Compress a serial object with GZIP encoding.
If successful, the return value is the pointer to the result object, else, it is `NULL'.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcgzipencode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcgzipencode(const char *ptr, int size, int *sp);
/* Decompress a serial object compressed with GZIP encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcgzipdecode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcgzipdecode(const char *ptr, int size, int *sp);
/* Get the CRC32 checksum of a serial object.
`ptr' specifies the pointer to the region.
`size' specifies the size of the region.
The return value is the CRC32 checksum of the object. */
-unsigned int tcgetcrc(const char *ptr, int size);
+EJDB_EXPORT unsigned int tcgetcrc(const char *ptr, int size);
/* Compress a serial object with BZIP2 encoding.
If successful, the return value is the pointer to the result object, else, it is `NULL'.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcbzipencode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcbzipencode(const char *ptr, int size, int *sp);
/* Decompress a serial object compressed with BZIP2 encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcbzipdecode(const char *ptr, int size, int *sp);
+EJDB_EXPORT char *tcbzipdecode(const char *ptr, int size, int *sp);
/* Encode an array of nonnegative integers with BER encoding.
The return value is the pointer to the region of the result.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tcberencode(const unsigned int *ary, int anum, int *sp);
+EJDB_EXPORT char *tcberencode(const unsigned int *ary, int anum, int *sp);
/* Decode a serial object encoded with BER encoding.
The return value is the pointer to the array of the result.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-unsigned int *tcberdecode(const char *ptr, int size, int *np);
+EJDB_EXPORT unsigned int *tcberdecode(const char *ptr, int size, int *np);
/* Escape meta characters in a string with the entity references of XML.
This function escapes only `&', `<', `>', and `"'. Because the region of the return value
is allocated with the `malloc' call, it should be released with the `free' call when it is no
longer in use. */
-char *tcxmlescape(const char *str);
+EJDB_EXPORT char *tcxmlescape(const char *str);
/* Unescape entity references in a string of XML.
This function restores only `&', `<', `>', and `"'. Because the region of the
return value is allocated with the `malloc' call, it should be released with the `free' call
when it is no longer in use. */
-char *tcxmlunescape(const char *str);
+EJDB_EXPORT char *tcxmlunescape(const char *str);
The return value is the result string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tcwwwformencode(const TCMAP *params);
+EJDB_EXPORT char *tcwwwformencode(const TCMAP *params);
/* Decode a query string in the x-www-form-urlencoded format.
`str' specifies the query string.
`params' specifies a map object into which the result parameters are stored. */
-void tcwwwformdecode(const char *str, TCMAP *params);
+EJDB_EXPORT void tcwwwformdecode(const char *str, TCMAP *params);
/* Decode a data region in the x-www-form-urlencoded or multipart-form-data format.
`type' specifies the value of the content-type header. If it is `NULL', the type is specified
as x-www-form-urlencoded.
`params' specifies a map object into which the result parameters are stored. */
-void tcwwwformdecode2(const void *ptr, int size, const char *type, TCMAP *params);
+EJDB_EXPORT void tcwwwformdecode2(const void *ptr, int size, const char *type, TCMAP *params);
/* Split an XML string into tags and text sections.
Because the object of the return value is created with the function `tclistnew', it should
be deleted with the function `tclistdel' when it is no longer in use. Because this function
does not check validation, it can handle also HTML and SGML. */
-TCLIST *tcxmlbreak(const char *str);
+EJDB_EXPORT TCLIST *tcxmlbreak(const char *str);
/* Get the map of attributes of an XML tag.
unescaped. You can get the name of the tag with the key of an empty string.
Because the object of the return value is created with the function `tcmapnew', it should
be deleted with the function `tcmapdel' when it is no longer in use. */
-TCMAP *tcxmlattrs(const char *str);
+EJDB_EXPORT TCMAP *tcxmlattrs(const char *str);
/* Escape meta characters in a string with backslash escaping of the C language.
The return value is the pointer to the escaped string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tccstrescape(const char *str);
+EJDB_EXPORT char *tccstrescape(const char *str);
/* Unescape a string escaped by backslash escaping of the C language.
The return value is the unescaped string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tccstrunescape(const char *str);
+EJDB_EXPORT char *tccstrunescape(const char *str);
/* Escape meta characters in a string with backslash escaping of JSON.
The return value is the pointer to the escaped string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tcjsonescape(const char *str);
+EJDB_EXPORT char *tcjsonescape(const char *str);
/* Unescape a string escaped by backslash escaping of JSON.
The return value is the unescaped string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call if when is no longer in use. */
-char *tcjsonunescape(const char *str);
+EJDB_EXPORT char *tcjsonunescape(const char *str);
/* Create a template object.
The return value is the new template object. */
-TCTMPL *tctmplnew(void);
+EJDB_EXPORT TCTMPL *tctmplnew(void);
/* Delete a template object.
`tmpl' specifies the template object. */
-void tctmpldel(TCTMPL *tmpl);
+EJDB_EXPORT void tctmpldel(TCTMPL *tmpl);
/* Set the separator strings of a template object.
`tmpl' specifies the template object.
`begsep' specifies the beginning separator string. By default, it is "[%".
`endsep' specifies the ending separator string. By default, it is "%]". */
-void tctmplsetsep(TCTMPL *tmpl, const char *begsep, const char *endsep);
+EJDB_EXPORT void tctmplsetsep(TCTMPL *tmpl, const char *begsep, const char *endsep);
/* Load a template string into a template object.
element. The session variable setting directive needs the parameters for the variable name
and its value. The configuration directive needs the parameters for the variable name and
its value. */
-void tctmplload(TCTMPL *tmpl, const char *str);
+EJDB_EXPORT void tctmplload(TCTMPL *tmpl, const char *str);
/* Load a template string from a file into a template object.
`tmpl' specifies the template object.
`path' specifies the input file.
If successful, the return value is true, else, it is false. */
-bool tctmplload2(TCTMPL *tmpl, const char *path);
+EJDB_EXPORT bool tctmplload2(TCTMPL *tmpl, const char *path);
/* Serialize the template string of a template object.
The return value is the dumped template string.
Because the region of the return value is allocated with the `malloc' call, it should be
released with the `free' call when it is no longer in use. */
-char *tctmpldump(TCTMPL *tmpl, const TCMAP *vars);
+EJDB_EXPORT char *tctmpldump(TCTMPL *tmpl, const TCMAP *vars);
/* Get the value of a configuration variable of a template object.
`name' specifies the name of the configuration variable.
The return value is the string value of the configuration variable or `NULL' if it is not
defined. */
-const char *tctmplconf(TCTMPL *tmpl, const char *name);
+EJDB_EXPORT const char *tctmplconf(TCTMPL *tmpl, const char *name);
/* Store a list object into a list object with the type information.
`list' specifies the container list object.
`obj' specifies the list object to be stored. */
-void tclistpushlist(TCLIST *list, const TCLIST *obj);
+EJDB_EXPORT void tclistpushlist(TCLIST *list, const TCLIST *obj);
/* Store a map object into a list object with the type information.
`list' specifies the container list object.
`obj' specifies the map object to be stored. */
-void tclistpushmap(TCLIST *list, const TCMAP *obj);
+EJDB_EXPORT void tclistpushmap(TCLIST *list, const TCMAP *obj);
/* Store a list object into a map object with the type information.
`map' specifies the container map object.
`kstr' specifies the string of the key.
`obj' specifies the list object to be stored. */
-void tcmapputlist(TCMAP *map, const char *kstr, const TCLIST *obj);
+EJDB_EXPORT void tcmapputlist(TCMAP *map, const char *kstr, const TCLIST *obj);
/* Store a map object into a map object with the type information.
`map' specifies the container map object.
`kstr' specifies the string of the key.
`obj' specifies the map object to be stored. */
-void tcmapputmap(TCMAP *map, const char *kstr, const TCMAP *obj);
+EJDB_EXPORT void tcmapputmap(TCMAP *map, const char *kstr, const TCMAP *obj);
/* Create a pointer list object.
The return value is the new pointer list object. */
-TCPTRLIST *tcptrlistnew(void);
+EJDB_EXPORT TCPTRLIST *tcptrlistnew(void);
/* Create a pointer list object with expecting the number of elements.
`anum' specifies the number of elements expected to be stored in the list.
The return value is the new pointer list object. */
-TCPTRLIST *tcptrlistnew2(int anum);
+EJDB_EXPORT TCPTRLIST *tcptrlistnew2(int anum);
/* Copy a pointer list object.
`ptrlist' specifies the pointer list object.
The return value is the new pointer list object equivalent to the specified object. */
-TCPTRLIST *tcptrlistdup(const TCPTRLIST *ptrlist);
+EJDB_EXPORT TCPTRLIST *tcptrlistdup(const TCPTRLIST *ptrlist);
/* Delete a pointer list object.
`ptrlist' specifies the pointer list object.
Note that the deleted object and its derivatives can not be used anymore. */
-void tcptrlistdel(TCPTRLIST *ptrlist);
+EJDB_EXPORT void tcptrlistdel(TCPTRLIST *ptrlist);
/* Get the number of elements of a pointer list object.
`ptrlist' specifies the pointer list object.
The return value is the number of elements of the list. */
-int tcptrlistnum(const TCPTRLIST *ptrlist);
+EJDB_EXPORT int tcptrlistnum(const TCPTRLIST *ptrlist);
/* Get the pointer to the region of an element of a pointer list object.
`index' specifies the index of the element.
The return value is the pointer to the region of the value.
If `index' is equal to or more than the number of elements, the return value is `NULL'. */
-void *tcptrlistval(const TCPTRLIST *ptrlist, int index);
+EJDB_EXPORT void *tcptrlistval(const TCPTRLIST *ptrlist, int index);
/* Add an element at the end of a pointer list object.
`ptrlist' specifies the pointer list object.
`ptr' specifies the pointer to the region of the new element. */
-void tcptrlistpush(TCPTRLIST *ptrlist, void *ptr);
+EJDB_EXPORT void tcptrlistpush(TCPTRLIST *ptrlist, void *ptr);
/* Remove an element of the end of a pointer list object.
`ptrlist' specifies the pointer list object.
The return value is the pointer to the region of the removed element.
If the list is empty, the return value is `NULL'. */
-void *tcptrlistpop(TCPTRLIST *ptrlist);
+EJDB_EXPORT void *tcptrlistpop(TCPTRLIST *ptrlist);
/* Add an element at the top of a pointer list object.
`ptrlist' specifies the pointer list object.
`ptr' specifies the pointer to the region of the new element. */
-void tcptrlistunshift(TCPTRLIST *ptrlist, void *ptr);
+EJDB_EXPORT void tcptrlistunshift(TCPTRLIST *ptrlist, void *ptr);
/* Remove an element of the top of a pointer list object.
`ptrlist' specifies the pointer list object.
The return value is the pointer to the region of the removed element.
If the list is empty, the return value is `NULL'. */
-void *tcptrlistshift(TCPTRLIST *ptrlist);
+EJDB_EXPORT void *tcptrlistshift(TCPTRLIST *ptrlist);
/* Add an element at the specified location of a pointer list object.
`index' specifies the index of the new element.
`ptr' specifies the pointer to the region of the new element.
If `index' is equal to or more than the number of elements, this function has no effect. */
-void tcptrlistinsert(TCPTRLIST *ptrlist, int index, void *ptr);
+EJDB_EXPORT void tcptrlistinsert(TCPTRLIST *ptrlist, int index, void *ptr);
/* Remove an element at the specified location of a pointer list object.
The return value is the pointer to the region of the removed element.
If `index' is equal to or more than the number of elements, no element is removed and the
return value is `NULL'. */
-void *tcptrlistremove(TCPTRLIST *ptrlist, int index);
+EJDB_EXPORT void *tcptrlistremove(TCPTRLIST *ptrlist, int index);
/* Overwrite an element at the specified location of a pointer list object.
`index' specifies the index of the element to be overwritten.
`ptr' specifies the pointer to the region of the new content.
If `index' is equal to or more than the number of elements, this function has no effect. */
-void tcptrlistover(TCPTRLIST *ptrlist, int index, void *ptr);
+EJDB_EXPORT void tcptrlistover(TCPTRLIST *ptrlist, int index, void *ptr);
/* Clear a pointer list object.
`ptrlist' specifies the pointer list object.
All elements are removed. */
-void tcptrlistclear(TCPTRLIST *ptrlist);
+EJDB_EXPORT void tcptrlistclear(TCPTRLIST *ptrlist);
TCERMDIR, /* rmdir error */
TCEKEEP, /* existing record */
TCENOREC, /* no record found */
+ TCETR, /* illegal transaction state */
TCEMISC = 9999 /* miscellaneous error */
};
};
+/* Converts last errno value on file operation
+ * to matching TC error code or use default `tcerrdef`
+ * if no errno was set.
+ */
+EJDB_EXPORT int tcfilerrno2tcerr(int tcerrdef);
+
/* Get the message string corresponding to an error code.
`ecode' specifies the error code.
The return value is the message string of the error code. */
-const char *tcerrmsg(int ecode);
+EJDB_EXPORT const char *tcerrmsg(int ecode);
/* Show error message on the standard error output and exit.
`message' specifies an error message.
This function does not return. */
-void *tcmyfatal(const char *message);
+EJDB_EXPORT void *tcmyfatal(const char *message);
/* Allocate a large nullified region.
The return value is the pointer to the allocated nullified region.
This function handles failure of memory allocation implicitly. The region of the return value
should be released with the function `tczerounmap' when it is no longer in use. */
-void *tczeromap(uint64_t size);
+EJDB_EXPORT void *tczeromap(uint64_t size);
/* Free a large nullfied region.
`ptr' specifies the pointer to the region. */
-void tczerounmap(void *ptr);
+EJDB_EXPORT void tczerounmap(void *ptr);
/* Lock the global mutex object.
If successful, the return value is true, else, it is false. */
-bool tcglobalmutexlock(void);
+EJDB_EXPORT bool tcglobalmutexlock(void);
/* Lock the global mutex object by shared locking.
If successful, the return value is true, else, it is false. */
-bool tcglobalmutexlockshared(void);
+EJDB_EXPORT bool tcglobalmutexlockshared(void);
/* Unlock the global mutex object.
If successful, the return value is true, else, it is false. */
-bool tcglobalmutexunlock(void);
+EJDB_EXPORT bool tcglobalmutexunlock(void);
/* Lock the absolute path of a file.
`path' specifies the path of the file.
If successful, the return value is true, else, it is false. */
-bool tcpathlock(const char *path);
+EJDB_EXPORT bool tcpathlock(const char *path);
/* Unock the absolute path of a file.
`path' specifies the path of the file.
If successful, the return value is true, else, it is false. */
-bool tcpathunlock(const char *path);
+EJDB_EXPORT bool tcpathunlock(const char *path);
/* Convert an integer to the string as binary numbers.
`col' specifies the number of columns. If it is not more than 0, it depends on the integer.
`fc' specifies the filling character.
The return value is the length of the result string. */
-int tcnumtostrbin(uint64_t num, char *buf, int col, int fc);
+EJDB_EXPORT int tcnumtostrbin(uint64_t num, char *buf, int col, int fc);
/* Compare two keys by lexical order.
`op' is ignored.
The return value is positive if the former is big, negative if the latter is big, 0 if both
are equivalent. */
-int tccmplexical(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
+EJDB_EXPORT int tccmplexical(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
/* Compare two keys as decimal strings of real numbers.
`op' is ignored.
The return value is positive if the former is big, negative if the latter is big, 0 if both
are equivalent. */
-int tccmpdecimal(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
+EJDB_EXPORT int tccmpdecimal(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
/* Compare two keys as 32-bit integers in the native byte order.
`op' is ignored.
The return value is positive if the former is big, negative if the latter is big, 0 if both
are equivalent. */
-int tccmpint32(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
+EJDB_EXPORT int tccmpint32(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
/* Compare two keys as 64-bit integers in the native byte order.
`op' is ignored.
The return value is positive if the former is big, negative if the latter is big, 0 if both
are equivalent. */
-int tccmpint64(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
+EJDB_EXPORT int tccmpint64(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
/* Encode a serial object with BWT encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcbwtencode(const char *ptr, int size, int *idxp);
+EJDB_EXPORT char *tcbwtencode(const char *ptr, int size, int *idxp);
/* Decode a serial object encoded with BWT encoding.
the return value can be treated as a character string. Because the region of the return
value is allocated with the `malloc' call, it should be released with the `free' call when it
is no longer in use. */
-char *tcbwtdecode(const char *ptr, int size, int idx);
+EJDB_EXPORT char *tcbwtdecode(const char *ptr, int size, int idx);
/* Get the binary logarithm of an integer.
`num' specifies an integer.
The return value is the binary logarithm. */
-long tclog2l(long num);
+EJDB_EXPORT long tclog2l(long num);
/* Get the binary logarithm of a real number.
`num' specifies a real number.
The return value is the binary logarithm. */
-double tclog2d(double num);
+EJDB_EXPORT double tclog2d(double num);
/* Get the aligned offset of a file offset.
`off' specifies the file offset.
The return value is the aligned offset. */
-uint64_t tcpagealign(uint64_t off);
+EJDB_EXPORT uint64_t tcpagealign(uint64_t off);
+/**
+ * Get page size
+ */
+EJDB_EXPORT off_t tcpagsize(void);
/**
* Convert string into case insensitive normalized format.
* @return In case of success the length of the resulting UTF-8 string is
* returned, otherwise a negative value.
*/
-int tcicaseformat(const char *str, int strl, void *placeholder, int placeholdersz, char **dstptr);
-int tcutf8map(const uint8_t *str, int strl, void *placeholder, int placeholdersz, uint8_t **dstptr, int options);
+EJDB_EXPORT int tcicaseformat(const char *str, int strl, void *placeholder, int placeholdersz, char **dstptr);
+EJDB_EXPORT int tcutf8map(const uint8_t *str, int strl, void *placeholder, int placeholdersz, uint8_t **dstptr, int options);
/* Print debug information with a formatted string as with `printf'. */
--- /dev/null
+#include "platform.h"
+#include "../tcutil.h"
+#include "../myconf.h"
+
+struct tm *gmtime_r(const time_t *timep, struct tm *result) {
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_lock(&mutex);
+ struct tm *cas = gmtime(timep);
+ pthread_mutex_unlock(&mutex);
+ if (result == NULL) {
+ return NULL; /* was:cas */
+ }
+ memcpy(result, cas, sizeof (struct tm));
+ return result;
+}
+
+struct tm *localtime_r(const time_t *timep, struct tm *result) {
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_lock(&mutex);
+ struct tm *cas = localtime(timep);
+ pthread_mutex_unlock(&mutex);
+ if (result == NULL) {
+ return NULL;
+ }
+ memcpy(result, cas, sizeof (struct tm));
+ return result;
+}
+
+static int file_attr_to_st_mode(DWORD attr) {
+ int fMode = S_IREAD;
+ if (attr & FILE_ATTRIBUTE_DIRECTORY)
+ fMode |= S_IFDIR;
+ else
+ fMode |= S_IFREG;
+ if (!(attr & FILE_ATTRIBUTE_READONLY))
+ fMode |= S_IWRITE;
+ return fMode;
+}
+
+static long long filetime_to_hnsec(const FILETIME *ft) {
+ long long winTime = ((long long) ft->dwHighDateTime << 32) + ft->dwLowDateTime;
+ /* Windows to Unix Epoch conversion */
+ return winTime - 116444736000000000LL;
+}
+
+static time_t filetime_to_time_t(const FILETIME *ft) {
+ return (time_t) (filetime_to_hnsec(ft) / 10000000);
+}
+
+int win_fstat(HANDLE fh, struct stat *buf) {
+ BY_HANDLE_FILE_INFORMATION fdata;
+ if (fh == INVALID_HANDLE_VALUE) {
+ errno = EBADF;
+ return -1;
+ }
+ if (GetFileType(fh) != FILE_TYPE_DISK) {
+ errno = ENODEV;
+ return -1;
+ }
+ if (GetFileInformationByHandle(fh, &fdata)) {
+ buf->st_ino = 0;
+ buf->st_gid = 0;
+ buf->st_uid = 0;
+ buf->st_nlink = 1;
+ buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
+ buf->st_size = (off_t) ((((int64_t) fdata.nFileSizeHigh) << 32) | fdata.nFileSizeLow);
+ buf->st_dev = buf->st_rdev = 0; /* not used by Git */
+ buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
+ buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
+ buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
+ return 0;
+ }
+ errno = EBADF;
+ return -1;
+}
+
+ssize_t win_pwrite(HANDLE fd, const void *buf, size_t count, off_t off) {
+ DWORD written;
+ OVERLAPPED offset;
+ memset(&offset, 0, sizeof (OVERLAPPED));
+ ULARGE_INTEGER bigint;
+ bigint.QuadPart = off;
+ offset.Offset = bigint.LowPart;
+ offset.OffsetHigh = bigint.HighPart;
+ if (!WriteFile(fd, buf, count, &written, &offset)) {
+ return -1;
+ }
+ return written;
+}
+
+ssize_t win_pread(HANDLE fd, void *buf, size_t size, off_t off) {
+ DWORD bread;
+ OVERLAPPED offset;
+ memset(&offset, 0, sizeof (OVERLAPPED));
+ ULARGE_INTEGER bigint;
+ bigint.QuadPart = off;
+ offset.Offset = bigint.LowPart;
+ offset.OffsetHigh = bigint.HighPart;
+ if (!ReadFile(fd, buf, size, &bread, &offset)) {
+ return -1;
+ }
+ return bread;
+}
+
+void globfree(glob_t *_pglob) {
+ size_t i;
+ if (!_pglob->gl_pathv)
+ return;
+ for (i = 0; i < _pglob->gl_pathc; i++)
+ if (_pglob->gl_pathv[i])
+ free(_pglob->gl_pathv[i]);
+ free(_pglob->gl_pathv);
+ _pglob->gl_offs = _pglob->gl_pathc = 0;
+ _pglob->gl_pathv = NULL;
+}
+
+int glob(const char *pattern, int flags,
+ int (*errfunc) (const char *epath, int eerrno),
+ glob_t *pglob) {
+ WIN32_FIND_DATAA stat;
+ char *directory = NULL;
+ int dirlen = 0;
+ /* init pglob */
+ pglob->gl_pathc = 0;
+ pglob->gl_offs = 10;
+ if ((pglob->gl_pathv = calloc(10, sizeof (char *))) == NULL)
+ return GLOB_NOSPACE;
+ char *separator = strrchr(pattern, '/');
+
+ if (separator != NULL) {
+ directory = tccalloc(1, separator - pattern + 2);
+ strncpy(directory, pattern, separator - pattern + 1);
+ dirlen = strlen(directory);
+ }
+ HANDLE h = FindFirstFileA(pattern, &stat);
+ if (h == INVALID_HANDLE_VALUE) {
+ globfree(pglob);
+ if (directory != NULL)
+ TCFREE(directory);
+ return GLOB_ABORTED;
+ }
+ do {
+ /* add new path to list */
+ char *entry = tccalloc(1, strlen(stat.cFileName) + dirlen + 1);
+ if (directory != NULL) {
+ strcpy(entry, directory);
+ }
+ strcat(entry, stat.cFileName);
+ pglob->gl_pathv[pglob->gl_pathc++] = entry;
+ if (pglob->gl_pathc == pglob->gl_offs) {
+ /* increase array size */
+ void *tmp = realloc(pglob->gl_pathv, sizeof (char *)*(pglob->gl_offs + 10));
+ if (tmp == NULL) {
+ globfree(pglob);
+ if (directory != NULL)
+ TCFREE(directory);
+ return GLOB_NOSPACE;
+ }
+ pglob->gl_offs += 10;
+ pglob->gl_pathv = tmp;
+ }
+ } while (FindNextFileA(h, &stat));
+ FindClose(h);
+ if (directory != NULL)
+ TCFREE(directory);
+ return 0;
+}
+
+
--- /dev/null
+/*
+ * File: platform.h
+ * Author: adam
+ *
+ * Created on March 31, 2013, 9:34 PM
+ */
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+#include "../basedefs.h"
+#include <stddef.h>
+#include <time.h>
+#include <direct.h>
+#include <sys/stat.h>
+
+typedef struct {
+ size_t gl_pathc; /* Count of paths matched so far */
+ char **gl_pathv; /* List of matched pathnames. */
+ size_t gl_offs; /* Slots to reserve in gl_pathv. */
+} glob_t;
+
+#define GLOB_ERR 1
+#define GLOB_MARK 0
+#define GLOB_NOSORT 2
+#define GLOB_DOOFFS 0
+#define GLOB_NOCHECK 0
+#define GLOB_APPEND 0
+#define GLOB_NOESCAPE 0
+#define GLOB_PERIOD 0
+#define GLOB_ALTDIRFUNC 0
+#define GLOB_BRACE 0
+#define GLOB_NOMAGIC 0
+#define GLOB_TILDE 0
+#define GLOB_TILDE_CHECK 0
+#define GLOB_ONLYDIR 4
+
+#define GLOB_NOSPACE -1
+#define GLOB_ABORTED -2
+#define GLOB_NOMATCH -3
+
+int glob(const char *pattern, int flags, int (*errfunc) (const char *epath, int eerrno), glob_t *pglob);
+void globfree(glob_t *pglob);
+struct tm *gmtime_r(const time_t *timep, struct tm *result);
+struct tm *localtime_r(const time_t *timep, struct tm *result);
+int win_fstat(HANDLE fh, struct stat *buf);
+ssize_t win_pwrite(HANDLE fd, const void *buf, size_t count, off_t offset);
+ssize_t win_pread(HANDLE fd, void *buf, size_t size, off_t off);
+
+#define mkdir(a, b) _mkdir(a)
+#define fstat win_fstat
+#define lstat stat
+#define sysconf_SC_CLK_TCK 64
+#define fsync(a) !FlushFileBuffers(a)
+#define pwrite win_pwrite
+#define pread win_pread
+
+
+#ifndef WIFEXITED
+#define WIFEXITED(S) 1
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(S) (S)
+#endif
+
+#endif /* PLATFORM_H */
+