2007-10-10 17:41:01 +00:00
|
|
|
#include <unistd.h>
|
2007-08-10 19:24:45 +00:00
|
|
|
#include <dirent.h>
|
|
|
|
#include <errno.h>
|
2007-08-10 21:39:55 +00:00
|
|
|
#include <fcntl.h>
|
2007-08-10 19:24:45 +00:00
|
|
|
#include <stdio.h>
|
2007-08-10 21:39:55 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/uio.h>
|
2007-11-21 13:07:49 +00:00
|
|
|
|
|
|
|
#include "brt-internal.h"
|
|
|
|
#include "log-internal.h"
|
|
|
|
#include "wbuf.h"
|
|
|
|
#include "memory.h"
|
2007-11-14 17:58:38 +00:00
|
|
|
#include "../src/ydb-internal.h"
|
2007-08-10 19:24:45 +00:00
|
|
|
|
2007-08-10 21:15:17 +00:00
|
|
|
int tokulogger_find_next_unused_log_file(const char *directory, long long *result) {
|
2007-08-10 19:24:45 +00:00
|
|
|
DIR *d=opendir(directory);
|
|
|
|
long long max=-1;
|
|
|
|
struct dirent *de;
|
2007-11-21 13:10:47 +00:00
|
|
|
if (d==0) return errno;
|
2007-08-10 19:24:45 +00:00
|
|
|
while ((de=readdir(d))) {
|
2007-11-21 13:10:47 +00:00
|
|
|
if (de==0) return errno;
|
2007-08-10 19:24:45 +00:00
|
|
|
long long thisl;
|
|
|
|
int r = sscanf(de->d_name, "log%llu.tokulog", &thisl);
|
|
|
|
if (r==1 && thisl>max) max=thisl;
|
|
|
|
}
|
|
|
|
*result=max+1;
|
2007-09-28 17:11:22 +00:00
|
|
|
int r = closedir(d);
|
|
|
|
return r;
|
2007-08-10 19:24:45 +00:00
|
|
|
}
|
|
|
|
|
2007-08-10 21:39:55 +00:00
|
|
|
int tokulogger_create_and_open_logger (const char *directory, TOKULOGGER *resultp) {
|
2007-08-10 19:24:45 +00:00
|
|
|
TAGMALLOC(TOKULOGGER, result);
|
|
|
|
if (result==0) return -1;
|
|
|
|
int r;
|
|
|
|
long long nexti;
|
2007-08-10 21:15:17 +00:00
|
|
|
r = tokulogger_find_next_unused_log_file(directory, &nexti);
|
2007-08-10 19:24:45 +00:00
|
|
|
if (r!=0) {
|
|
|
|
died0:
|
|
|
|
toku_free(result);
|
2007-11-21 13:10:47 +00:00
|
|
|
return r;
|
2007-08-10 19:24:45 +00:00
|
|
|
}
|
|
|
|
result->directory = toku_strdup(directory);
|
2007-09-28 17:11:22 +00:00
|
|
|
if (result->directory==0) goto died0;
|
2007-08-10 21:39:55 +00:00
|
|
|
result->fd = -1;
|
2007-08-10 19:24:45 +00:00
|
|
|
result->next_log_file_number = nexti;
|
|
|
|
result->n_in_buf = 0;
|
2007-11-14 17:58:38 +00:00
|
|
|
|
|
|
|
result->lsn.lsn = 0; // WRONG!!! This should actually be calculated by looking at the log file.
|
|
|
|
|
2007-08-10 21:39:55 +00:00
|
|
|
*resultp=result;
|
2007-09-28 17:11:22 +00:00
|
|
|
return tokulogger_log_bytes(result, 0, "");
|
2007-08-10 21:39:55 +00:00
|
|
|
}
|
|
|
|
|
2007-09-28 17:11:22 +00:00
|
|
|
int tokulogger_log_bytes(TOKULOGGER logger, int nbytes, void *bytes) {
|
2007-08-10 21:39:55 +00:00
|
|
|
int r;
|
2007-10-19 17:05:10 +00:00
|
|
|
//fprintf(stderr, "%s:%d logging %d bytes\n", __FILE__, __LINE__, nbytes);
|
2007-08-10 21:39:55 +00:00
|
|
|
if (logger->fd==-1) {
|
|
|
|
int fnamelen = strlen(logger->directory)+50;
|
|
|
|
char fname[fnamelen];
|
|
|
|
snprintf(fname, fnamelen, "%s/log%012llu.tokulog", logger->directory, logger->next_log_file_number);
|
2007-11-18 12:48:36 +00:00
|
|
|
//fprintf(stderr, "%s:%d creat(%s, ...)\n", __FILE__, __LINE__, fname);
|
2007-08-10 21:39:55 +00:00
|
|
|
logger->fd = creat(fname, O_EXCL | 0700);
|
|
|
|
if (logger->fd==-1) return errno;
|
2007-10-01 21:19:53 +00:00
|
|
|
logger->next_log_file_number++;
|
2007-08-10 21:39:55 +00:00
|
|
|
}
|
|
|
|
if (logger->n_in_buf + nbytes > LOGGER_BUF_SIZE) {
|
|
|
|
struct iovec v[2];
|
|
|
|
v[0].iov_base = logger->buf;
|
|
|
|
v[0].iov_len = logger->n_in_buf;
|
|
|
|
v[1].iov_base = bytes;
|
|
|
|
v[1].iov_len = nbytes;
|
2007-10-19 17:05:10 +00:00
|
|
|
//fprintf(stderr, "%s:%d flushing log due to buffer overflow\n", __FILE__, __LINE__);
|
2007-08-10 21:39:55 +00:00
|
|
|
r=writev(logger->fd, v, 2);
|
|
|
|
if (r!=logger->n_in_buf + nbytes) return errno;
|
|
|
|
logger->n_in_file += logger->n_in_buf+nbytes;
|
|
|
|
logger->n_in_buf=0;
|
|
|
|
if (logger->n_in_file > 100<<20) {
|
2007-10-19 17:05:10 +00:00
|
|
|
fprintf(stderr, "%s:%d closing logfile\n", __FILE__, __LINE__);
|
2007-08-10 21:39:55 +00:00
|
|
|
r = close(logger->fd);
|
|
|
|
if (r!=0) return errno;
|
2007-10-01 21:19:53 +00:00
|
|
|
logger->fd=-1;
|
2007-08-10 21:39:55 +00:00
|
|
|
logger->n_in_file = 0;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
memcpy(logger->buf+logger->n_in_buf, bytes, nbytes);
|
|
|
|
logger->n_in_buf += nbytes;
|
|
|
|
}
|
2007-08-10 19:24:45 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2007-08-21 23:32:17 +00:00
|
|
|
|
2007-09-28 17:11:22 +00:00
|
|
|
int tokulogger_log_close(TOKULOGGER *loggerp) {
|
|
|
|
TOKULOGGER logger = *loggerp;
|
|
|
|
int r = 0;
|
|
|
|
if (logger->fd!=-1) {
|
2007-11-18 12:48:36 +00:00
|
|
|
//printf("%s:%d closing log: n_in_buf=%d\n", __FILE__, __LINE__, logger->n_in_buf);
|
2007-09-28 17:11:22 +00:00
|
|
|
if (logger->n_in_buf>0) {
|
|
|
|
r = write(logger->fd, logger->buf, logger->n_in_buf);
|
|
|
|
if (r==-1) return errno;
|
|
|
|
}
|
|
|
|
r = close(logger->fd);
|
|
|
|
}
|
|
|
|
toku_free(logger->directory);
|
|
|
|
toku_free(logger);
|
|
|
|
*loggerp=0;
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
#if 0
|
2007-08-21 23:32:17 +00:00
|
|
|
int tokulogger_log_brt_remove (TOKULOGGER logger,
|
|
|
|
TXNID txnid,
|
|
|
|
diskoff diskoff,
|
|
|
|
unsigned char *key,
|
|
|
|
int keylen,
|
|
|
|
unsigned char *val,
|
|
|
|
int vallen) {
|
2007-09-28 17:11:22 +00:00
|
|
|
n
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
int tokulogger_fsync (TOKULOGGER logger) {
|
2007-10-17 22:10:47 +00:00
|
|
|
//return 0;/// NO TXN
|
2007-10-19 17:05:10 +00:00
|
|
|
//fprintf(stderr, "%s:%d syncing log\n", __FILE__, __LINE__);
|
2007-09-28 17:11:22 +00:00
|
|
|
if (logger->n_in_buf>0) {
|
|
|
|
int r = write(logger->fd, logger->buf, logger->n_in_buf);
|
|
|
|
if (r==-1) return errno;
|
|
|
|
logger->n_in_buf=0;
|
|
|
|
}
|
|
|
|
{
|
|
|
|
int r = fsync(logger->fd);
|
|
|
|
if (r!=0) return errno;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-22 07:13:08 +00:00
|
|
|
int tokulogger_finish (TOKULOGGER logger, struct wbuf *wbuf) {
|
2007-11-14 17:58:38 +00:00
|
|
|
wbuf_int(wbuf, toku_crc32(0, wbuf->buf, wbuf->ndone));
|
|
|
|
wbuf_int(wbuf, 4+wbuf->ndone);
|
|
|
|
return tokulogger_log_bytes(logger, wbuf->ndone, wbuf->buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Log an insertion of a key-value pair into a particular node of the tree.
|
|
|
|
int tokulogger_log_brt_insert_with_no_overwrite (TOKULOGGER logger,
|
|
|
|
TXNID txnid,
|
|
|
|
FILENUM fileid,
|
|
|
|
DISKOFF diskoff,
|
|
|
|
unsigned char *key,
|
|
|
|
int keylen,
|
|
|
|
unsigned char *val,
|
|
|
|
int vallen) {
|
|
|
|
int buflen=(keylen+vallen+4+4 // key and value
|
|
|
|
+1 // command
|
|
|
|
+8 // lsn
|
|
|
|
+8 // txnid
|
|
|
|
+4 // fileid
|
|
|
|
+8 // diskoff
|
|
|
|
+8 // crc and len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init(&wbuf, buf, buflen) ;
|
|
|
|
wbuf_char(&wbuf, LT_INSERT_WITH_NO_OVERWRITE);
|
|
|
|
wbuf_lsn (&wbuf, logger->lsn); logger->lsn.lsn++;
|
|
|
|
wbuf_txnid(&wbuf, txnid);
|
|
|
|
wbuf_filenum(&wbuf, fileid);
|
|
|
|
wbuf_diskoff(&wbuf, diskoff);
|
|
|
|
wbuf_bytes(&wbuf, key, keylen);
|
|
|
|
wbuf_bytes(&wbuf, val, vallen);
|
|
|
|
return tokulogger_finish (logger, &wbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
int tokulogger_log_phys_add_or_delete_in_leaf (DB *db, TOKUTXN txn, DISKOFF diskoff, int is_add, const struct kv_pair *pair) {
|
|
|
|
if (txn==0) return 0;
|
|
|
|
assert(db);
|
|
|
|
int keylen = pair->keylen;
|
|
|
|
int vallen = pair->vallen;
|
|
|
|
const int buflen=(keylen+vallen+4+4 // the key and value
|
|
|
|
+1 // log command
|
|
|
|
+8 // lsn
|
|
|
|
+8 // txnid
|
|
|
|
+8 // fileid
|
|
|
|
+8 // diskoff
|
|
|
|
+8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init(&wbuf, buf, buflen) ;
|
|
|
|
wbuf_char(&wbuf, is_add ? LT_INSERT_WITH_NO_OVERWRITE : LT_DELETE);
|
|
|
|
wbuf_lsn (&wbuf, txn->logger->lsn);
|
|
|
|
txn->logger->lsn.lsn++;
|
|
|
|
wbuf_txnid(&wbuf, txn->txnid64);
|
|
|
|
wbuf_filenum(&wbuf, db->i->fileid);
|
|
|
|
wbuf_diskoff(&wbuf, diskoff);
|
|
|
|
wbuf_bytes(&wbuf, kv_pair_key_const(pair), keylen);
|
|
|
|
wbuf_bytes(&wbuf, kv_pair_val_const(pair), vallen);
|
|
|
|
return tokulogger_finish(txn->logger, &wbuf);
|
|
|
|
}
|
|
|
|
|
2007-09-28 17:11:22 +00:00
|
|
|
int tokulogger_log_commit (TOKUTXN txn) {
|
|
|
|
struct wbuf wbuf;
|
2007-11-14 17:58:38 +00:00
|
|
|
const int buflen = (1 // log command
|
|
|
|
+8 // lsn
|
|
|
|
+8 // txnid
|
|
|
|
+8 // crc & len
|
|
|
|
);
|
2007-09-28 17:11:22 +00:00
|
|
|
unsigned char buf[buflen];
|
|
|
|
wbuf_init(&wbuf, buf, buflen);
|
|
|
|
wbuf_char(&wbuf, LT_COMMIT);
|
2007-11-14 17:58:38 +00:00
|
|
|
wbuf_lsn (&wbuf, txn->logger->lsn);
|
|
|
|
txn->logger->lsn.lsn++;
|
2007-09-28 17:11:22 +00:00
|
|
|
wbuf_txnid(&wbuf, txn->txnid64);
|
2007-11-14 17:58:38 +00:00
|
|
|
int r = tokulogger_finish(txn->logger, &wbuf);
|
2007-09-28 17:11:22 +00:00
|
|
|
if (r!=0) return r;
|
2007-11-16 15:37:35 +00:00
|
|
|
int result;
|
|
|
|
if (txn->parent) result=0;
|
|
|
|
else result=tokulogger_fsync(txn->logger);
|
|
|
|
toku_free(txn);
|
|
|
|
return result;
|
2007-09-28 17:11:22 +00:00
|
|
|
}
|
|
|
|
|
2007-11-14 17:58:38 +00:00
|
|
|
int tokulogger_log_checkpoint (TOKULOGGER logger, LSN *lsn) {
|
|
|
|
struct wbuf wbuf;
|
|
|
|
const int buflen =10;
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
wbuf_init(&wbuf, buf, buflen);
|
|
|
|
wbuf_char(&wbuf, LT_CHECKPOINT);
|
|
|
|
wbuf_lsn (&wbuf, logger->lsn);
|
|
|
|
*lsn = logger->lsn;
|
|
|
|
logger->lsn.lsn++;
|
|
|
|
return tokulogger_log_bytes(logger, wbuf.ndone, wbuf.buf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-10-19 17:05:10 +00:00
|
|
|
int tokutxn_begin (TOKUTXN parent_tokutxn, TOKUTXN *tokutxn, TXNID txnid64, TOKULOGGER logger) {
|
2007-09-28 17:11:22 +00:00
|
|
|
TAGMALLOC(TOKUTXN, result);
|
|
|
|
if (result==0) return errno;
|
|
|
|
result->txnid64 = txnid64;
|
|
|
|
result->logger = logger;
|
2007-10-19 17:05:10 +00:00
|
|
|
result->parent = parent_tokutxn;
|
2007-09-28 17:11:22 +00:00
|
|
|
*tokutxn = result;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-11-14 17:58:38 +00:00
|
|
|
int tokulogger_log_block_rename (TOKULOGGER logger, FILENUM fileid, DISKOFF olddiskoff, DISKOFF newdiskoff, DISKOFF parentdiskoff, int childnum) {
|
|
|
|
const int buflen=(+1 // log command
|
|
|
|
+8 // lsn
|
|
|
|
+8 // fileid
|
|
|
|
+8 // olddiskoff
|
|
|
|
+8 // newdiskoff
|
|
|
|
+8 // parentdiskoff
|
|
|
|
+4 // childnum
|
|
|
|
+8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init (&wbuf, buf, buflen) ;
|
|
|
|
wbuf_char (&wbuf, LT_BLOCK_RENAME);
|
|
|
|
wbuf_lsn (&wbuf, logger->lsn);
|
|
|
|
logger->lsn.lsn++;
|
|
|
|
wbuf_filenum(&wbuf, fileid);
|
|
|
|
wbuf_diskoff(&wbuf, olddiskoff);
|
|
|
|
wbuf_diskoff(&wbuf, newdiskoff);
|
|
|
|
wbuf_diskoff(&wbuf, parentdiskoff);
|
|
|
|
wbuf_int (&wbuf, childnum);
|
|
|
|
return tokulogger_finish(logger, &wbuf);
|
|
|
|
}
|
|
|
|
|
2007-11-19 23:47:44 +00:00
|
|
|
int tokulogger_log_fcreate (TOKUTXN txn, const char *fname, int mode) {
|
2007-11-18 12:48:36 +00:00
|
|
|
if (txn==0) return 0;
|
|
|
|
const int fnamelen = strlen(fname);
|
|
|
|
const int buflen = (+1 // log command
|
2007-11-20 13:58:47 +00:00
|
|
|
+8 // lsn
|
|
|
|
+8 // txnid
|
2007-11-18 12:48:36 +00:00
|
|
|
+4 // length of fname
|
|
|
|
+fnamelen
|
|
|
|
+4 // mode
|
|
|
|
+8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init (&wbuf, buf, buflen);
|
2007-11-19 23:47:44 +00:00
|
|
|
wbuf_char (&wbuf, LT_FCREATE);
|
2007-11-20 13:58:47 +00:00
|
|
|
wbuf_lsn (&wbuf, txn->logger->lsn);
|
|
|
|
txn->logger->lsn.lsn++;
|
|
|
|
wbuf_txnid(&wbuf, txn->txnid64);
|
2007-11-18 12:48:36 +00:00
|
|
|
wbuf_bytes(&wbuf, fname, fnamelen);
|
|
|
|
wbuf_int (&wbuf, mode);
|
|
|
|
return tokulogger_finish(txn->logger, &wbuf);
|
|
|
|
}
|
|
|
|
|
2007-11-20 21:20:05 +00:00
|
|
|
/* fopen isn't really an action. It's just for bookkeeping. We need to know the filename that goes with a filenum. */
|
|
|
|
int tokulogger_log_fopen (TOKUTXN txn, const char * fname, FILENUM filenum) {
|
|
|
|
if (txn==0) return 0;
|
|
|
|
const int fnamelen = strlen(fname);
|
|
|
|
const int buflen = (+1 // log command
|
|
|
|
+8 // lsn
|
|
|
|
+8 // txnid
|
|
|
|
+4 // length of fname
|
|
|
|
+fnamelen
|
|
|
|
+4 // filenum len
|
|
|
|
+8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init (&wbuf, buf, buflen);
|
|
|
|
wbuf_char (&wbuf, LT_FOPEN);
|
|
|
|
wbuf_lsn (&wbuf, txn->logger->lsn);
|
|
|
|
txn->logger->lsn.lsn++;
|
|
|
|
wbuf_txnid(&wbuf, txn->txnid64);
|
|
|
|
wbuf_bytes(&wbuf, fname, fnamelen);
|
|
|
|
wbuf_filenum(&wbuf, filenum);
|
|
|
|
return tokulogger_finish(txn->logger, &wbuf);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-18 12:48:36 +00:00
|
|
|
int tokulogger_log_unlink (TOKUTXN txn, const char *fname) {
|
|
|
|
if (txn==0) return 0;
|
|
|
|
const int fnamelen = strlen(fname);
|
|
|
|
const int buflen = (+1 // log command
|
|
|
|
+4 // length of fname
|
|
|
|
+fnamelen
|
|
|
|
+8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init (&wbuf, buf, buflen);
|
|
|
|
wbuf_char (&wbuf, LT_UNLINK);
|
|
|
|
wbuf_bytes(&wbuf, fname, fnamelen);
|
|
|
|
return tokulogger_finish(txn->logger, &wbuf);
|
|
|
|
};
|
|
|
|
|
2007-11-21 13:07:49 +00:00
|
|
|
int tokulogger_log_header (TOKUTXN txn, FILENUM filenum, struct brt_header *h) {
|
|
|
|
if (txn==0) return 0;
|
|
|
|
int subsize=toku_serialize_brt_header_size(h);
|
|
|
|
int buflen = (1+
|
|
|
|
+ 8 // lsn
|
|
|
|
+ 8 // txnid
|
|
|
|
+ 4 // filenum
|
|
|
|
+ subsize
|
|
|
|
+ 8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char *buf=toku_malloc(buflen); // alloc on heap because it might be big
|
|
|
|
int r;
|
|
|
|
if (buf==0) return errno;
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init(&wbuf, buf, buflen);
|
|
|
|
wbuf_char(&wbuf, LT_FHEADER);
|
|
|
|
wbuf_lsn (&wbuf, txn->logger->lsn);
|
|
|
|
txn->logger->lsn.lsn++;
|
|
|
|
wbuf_txnid(&wbuf, txn->txnid64);
|
|
|
|
wbuf_filenum(&wbuf, filenum);
|
|
|
|
r=toku_serialize_brt_header_to_wbuf(&wbuf, h);
|
|
|
|
if (r!=0) return r;
|
|
|
|
r=tokulogger_finish(txn->logger, &wbuf);
|
|
|
|
toku_free(buf);
|
|
|
|
return r;
|
|
|
|
}
|
2007-11-18 12:48:36 +00:00
|
|
|
|
2007-11-21 19:06:32 +00:00
|
|
|
int tokulogger_log_newbrtnode (TOKUTXN txn, FILENUM filenum, DISKOFF offset, u_int32_t height, u_int32_t nodesize, char is_dup_sort_mode, u_int32_t rand4fingerprint) {
|
|
|
|
if (txn==0) return 0;
|
|
|
|
int buflen=(1+
|
|
|
|
+ 8 // lsn
|
|
|
|
+ 8 // txnid
|
|
|
|
+ 4 // filenum
|
|
|
|
+ 8 // diskoff
|
|
|
|
+ 4 // height
|
|
|
|
+ 4 // nodesize
|
|
|
|
+ 1 // is_dup_sort_mode
|
|
|
|
+ 4 // rand4fingerprint
|
|
|
|
+ 8 // crc & len
|
|
|
|
);
|
|
|
|
unsigned char buf[buflen];
|
|
|
|
struct wbuf wbuf;
|
|
|
|
wbuf_init (&wbuf, buf, buflen);
|
|
|
|
wbuf_char(&wbuf, LT_NEWBRTNODE);
|
|
|
|
wbuf_lsn (&wbuf, txn->logger->lsn);
|
|
|
|
txn->logger->lsn.lsn++;
|
|
|
|
wbuf_txnid(&wbuf, txn->txnid64);
|
|
|
|
wbuf_filenum(&wbuf, filenum);
|
|
|
|
wbuf_diskoff(&wbuf, offset);
|
|
|
|
wbuf_int(&wbuf, height);
|
|
|
|
wbuf_int(&wbuf, nodesize);
|
|
|
|
wbuf_char(&wbuf, is_dup_sort_mode);
|
|
|
|
wbuf_int(&wbuf, rand4fingerprint);
|
|
|
|
return tokulogger_finish(txn->logger, &wbuf);
|
|
|
|
}
|
|
|
|
|
2007-11-14 17:58:38 +00:00
|
|
|
/*
|
|
|
|
int brtenv_checkpoint (BRTENV env) {
|
|
|
|
init the checkpointing lock
|
|
|
|
acquire_spinlock(&env->checkpointing);
|
|
|
|
release_spinlock(&env->checkpointing);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*/
|