summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
0753972)
We don't need to copy into a buffer to examine the old data: in the
common case, it's mmaped already. It's made a bit trickier because
the tdb_access_read() function uses the current I/O methods, so we
need to restore that temporarily.
The difference was in the noise, however (the sync no-doubt
dominates).
Before:
$ time ./growtdb-bench 250000 10 > /dev/null && ls -l /tmp/growtdb.tdb && time ./tdbtorture -s 0 && ls -l torture.tdb && ./speed --transaction
2000000
real 0m45.021s
user 0m16.261s
sys 0m2.432s
-rw------- 1 rusty rusty
364469344 2011-04-27 22:55 /tmp/growtdb.tdb
testing with 3 processes, 5000 loops, seed=0
OK
real 1m10.144s
user 0m0.480s
sys 0m0.460s
-rw------- 1 rusty rusty 391992 2011-04-27 22:56 torture.tdb
Adding
2000000 records: 863 ns (
110601144 bytes)
Finding
2000000 records: 565 ns (
110601144 bytes)
Missing
2000000 records: 383 ns (
110601144 bytes)
Traversing
2000000 records: 409 ns (
110601144 bytes)
Deleting
2000000 records: 676 ns (
225354680 bytes)
Re-adding
2000000 records: 784 ns (
225354680 bytes)
Appending
2000000 records: 1191 ns (
247890168 bytes)
Churning
2000000 records: 2166 ns (
423133432 bytes)
After:
real 0m47.141s
user 0m16.073s
sys 0m2.460s
-rw------- 1 rusty rusty
364469344 2011-04-27 22:58 /tmp/growtdb.tdb
testing with 3 processes, 5000 loops, seed=0
OK
real 1m4.207s
user 0m0.416s
sys 0m0.504s
-rw------- 1 rusty rusty 313576 2011-04-27 22:59 torture.tdb
Adding
2000000 records: 874 ns (
110601144 bytes)
Finding
2000000 records: 565 ns (
110601144 bytes)
Missing
2000000 records: 393 ns (
110601144 bytes)
Traversing
2000000 records: 404 ns (
110601144 bytes)
Deleting
2000000 records: 684 ns (
225354680 bytes)
Re-adding
2000000 records: 792 ns (
225354680 bytes)
Appending
2000000 records: 1212 ns (
247890168 bytes)
Churning
2000000 records: 2191 ns (
423133432 bytes)
size_t i;
enum TDB_ERROR ecode;
unsigned char *p;
size_t i;
enum TDB_ERROR ecode;
unsigned char *p;
- const struct tdb_methods *methods = tdb->transaction->io_methods;
+ const struct tdb_methods *old_methods = tdb->methods;
rec = malloc(sizeof(*rec) + tdb_recovery_size(tdb));
if (!rec) {
rec = malloc(sizeof(*rec) + tdb_recovery_size(tdb));
if (!rec) {
return TDB_ERR_PTR(TDB_ERR_OOM);
}
return TDB_ERR_PTR(TDB_ERR_OOM);
}
+ /* We temporarily revert to the old I/O methods, so we can use
+ * tdb_access_read */
+ tdb->methods = tdb->transaction->io_methods;
+
/* build the recovery data into a single blob to allow us to do a single
large write, which should be more efficient */
p = (unsigned char *)(rec + 1);
/* build the recovery data into a single blob to allow us to do a single
large write, which should be more efficient */
p = (unsigned char *)(rec + 1);
tdb_off_t offset;
tdb_len_t length;
unsigned int off;
tdb_off_t offset;
tdb_len_t length;
unsigned int off;
- unsigned char buffer[PAGESIZE];
+ const unsigned char *buffer;
if (tdb->transaction->blocks[i] == NULL) {
continue;
if (tdb->transaction->blocks[i] == NULL) {
continue;
}
if (offset + length > tdb->file->map_size) {
}
if (offset + length > tdb->file->map_size) {
- free(rec);
- tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
- "tdb_transaction_setup_recovery:"
- " transaction data over new region"
- " boundary");
- return TDB_ERR_PTR(TDB_ERR_CORRUPT);
+ ecode = tdb_logerr(tdb, TDB_ERR_CORRUPT, TDB_LOG_ERROR,
+ "tdb_transaction_setup_recovery:"
+ " transaction data over new region"
+ " boundary");
+ goto fail;
}
if (offset + length > tdb->transaction->old_map_size) {
/* Short read at EOF. */
length = tdb->transaction->old_map_size - offset;
}
}
if (offset + length > tdb->transaction->old_map_size) {
/* Short read at EOF. */
length = tdb->transaction->old_map_size - offset;
}
- ecode = methods->tread(tdb, offset, buffer, length);
- if (ecode != TDB_SUCCESS) {
- free(rec);
- return TDB_ERR_PTR(ecode);
+ buffer = tdb_access_read(tdb, offset, length, false);
+ if (TDB_PTR_IS_ERR(buffer)) {
+ ecode = TDB_PTR_ERR(buffer);
+ goto fail;
}
/* Skip over anything the same at the start. */
}
/* Skip over anything the same at the start. */
off += len + samelen;
offset += len + samelen;
}
off += len + samelen;
offset += len + samelen;
}
+ tdb_access_release(tdb, buffer);
}
*len = p - (unsigned char *)(rec + 1);
}
*len = p - (unsigned char *)(rec + 1);
+ tdb->methods = old_methods;
+
+fail:
+ free(rec);
+ tdb->methods = old_methods;
+ return TDB_ERR_PTR(ecode);
}
static tdb_off_t create_recovery_area(struct tdb_context *tdb,
}
static tdb_off_t create_recovery_area(struct tdb_context *tdb,