Browse Source

tdb2: make internal coalesce() function return length coalesced.

This makes life easier for the next patch.
Rusty Russell 15 years ago
parent
commit
6b999f4511
2 changed files with 20 additions and 16 deletions
  1. 13 13
      ccan/tdb2/free.c
  2. 7 3
      ccan/tdb2/test/run-03-coalesce.c

+ 13 - 13
ccan/tdb2/free.c

@@ -333,10 +333,10 @@ static tdb_off_t ftable_offset(struct tdb_context *tdb, unsigned int ftable)
 	return off;
 }
 
-/* Note: we unlock the current bucket if we coalesce or fail. */
-static tdb_bool_err coalesce(struct tdb_context *tdb,
-			     tdb_off_t off, tdb_off_t b_off,
-			     tdb_len_t data_len)
+/* Note: we unlock the current bucket if we coalesce (> 0) or fail (-ve). */
+static tdb_len_t coalesce(struct tdb_context *tdb,
+			  tdb_off_t off, tdb_off_t b_off,
+			  tdb_len_t data_len)
 {
 	tdb_off_t end;
 	struct tdb_free_record rec;
@@ -414,7 +414,7 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
 
 	/* Didn't find any adjacent free? */
 	if (end == off + sizeof(struct tdb_used_record) + data_len)
-		return false;
+		return 0;
 
 	/* OK, expand initial record */
 	ecode = tdb_read_convert(tdb, off, &rec, sizeof(rec));
@@ -453,7 +453,8 @@ static tdb_bool_err coalesce(struct tdb_context *tdb,
 	if (ecode != TDB_SUCCESS) {
 		return ecode;
 	}
-	return true;
+	/* Return usable length. */
+	return end - off - sizeof(struct tdb_used_record);
 
 err:
 	/* To unify error paths, we *always* unlock bucket on error. */
@@ -506,9 +507,8 @@ again:
 
 	while (off) {
 		const struct tdb_free_record *r;
-		tdb_len_t len;
+		tdb_len_t len, coal;
 		tdb_off_t next;
-		int coal;
 
 		r = tdb_access_read(tdb, off, sizeof(*r), true);
 		if (TDB_PTR_IS_ERR(r)) {
@@ -544,14 +544,14 @@ again:
 
 		/* Since we're going slow anyway, try coalescing here. */
 		coal = coalesce(tdb, off, b_off, len);
-		if (coal == 1) {
-			/* This has unlocked list, restart. */
-			goto again;
-		}
-		if (coal < 0) {
+		if (TDB_OFF_IS_ERR(coal)) {
 			/* This has already unlocked on error. */
 			return coal;
 		}
+		if (coal > 0) {
+			/* This has unlocked list, restart. */
+			goto again;
+		}
 		off = next;
 	}
 

+ 7 - 3
ccan/tdb2/test/run-03-coalesce.c

@@ -91,7 +91,8 @@ int main(int argc, char *argv[])
 	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
 	/* Lock and coalesce. */
 	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
-	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
+	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024)
+	    == 1024 + sizeof(struct tdb_used_record) + 2048);
 	ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
 	ok1(free_record_length(tdb, layout->elem[1].base.off)
 	    == 1024 + sizeof(struct tdb_used_record) + 2048);
@@ -114,7 +115,8 @@ int main(int argc, char *argv[])
 	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
 	/* Lock and coalesce. */
 	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
-	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
+	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024)
+	    == 1024 + sizeof(struct tdb_used_record) + 512);
 	ok1(tdb->file->allrecord_lock.count == 0 && tdb->file->num_lockrecs == 0);
 	ok1(free_record_length(tdb, layout->elem[1].base.off)
 	    == 1024 + sizeof(struct tdb_used_record) + 512);
@@ -138,7 +140,9 @@ int main(int argc, char *argv[])
 	b_off = bucket_off(tdb->ftable_off, size_to_bucket(1024));
 	/* Lock and coalesce. */
 	ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
-	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
+	ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) ==
+	    1024 + sizeof(struct tdb_used_record) + 512
+	    + sizeof(struct tdb_used_record) + 256);
 	ok1(tdb->file->allrecord_lock.count == 0
 	    && tdb->file->num_lockrecs == 0);
 	ok1(free_record_length(tdb, layout->elem[1].base.off)