[1068] in Coldmud discussion meeting
[COLD] binarydb.patch
daemon@ATHENA.MIT.EDU (Mon Aug 19 20:20:22 1996
)
Date: Tue, 20 Aug 1996 01:58:46 +0200 (MET DST)
From: Miroslav Silovic <silovic@public.srce.hr>
To: coldstuff@cold.org
This patch should prevent most of the wild db growth. It also fixes a
nasty database dumping bug.
IMPORTANT NOTE: binarydb.c is critical part of the driver. When I
tested this, allocated_blocks wasn't updated right. On the other
hand, after 50,000 random object touches, there wasn't any db
corruption. I suppose that means that the code is safe.
The patch follows:
--------------------------------------------------------------------
*** binarydb.c Sat Jul 13 21:32:17 1996
*** 325,334 ****
if (fseek(dump_db_file, BLOCK_OFFSET (start), SEEK_SET))
panic("fseek(\"%s\") in copy: %s", dump_db_file, strerror(errno));
! for (i=0; i<blocks; i+=16) {
fread (buf, 1, BLOCK_SIZE, database_file);
fwrite (buf, 1, BLOCK_SIZE, dump_db_file);
! dump_bitmap[i >> 3] &= ~(1 << (i&7));
}
}
--- 325,334 ----
if (fseek(dump_db_file, BLOCK_OFFSET (start), SEEK_SET))
panic("fseek(\"%s\") in copy: %s", dump_db_file, strerror(errno));
! for (i=0; i<blocks; i++) {
fread (buf, 1, BLOCK_SIZE, database_file);
fwrite (buf, 1, BLOCK_SIZE, dump_db_file);
! dump_bitmap[(start+i) >> 3] &= ~(1 << ((start+i)&7));
}
}
***************
*** 456,461 ****
--- 456,463 ----
for (b = starting_block; b < starting_block + count; b++)
bitmap[b >> 3] |= (1 << (b & 7));
last_free = b;
+ /* printf ("Object alloc: %6d, total size: %6d allocated: %d\n",starting_block,bitmap_blocks,allocated_blocks);
+ fflush (stdout); */
return starting_block;
}
***************
*** 480,500 ****
return 1;
}
Int db_put(Obj *obj, Long objnum)
{
off_t old_offset, new_offset;
! Int old_size, new_size = size_object(obj);
db_is_dirty();
-
if (lookup_retrieve_objnum(objnum, &old_offset, &old_size)) {
! if (NEEDED(new_size, BLOCK_SIZE) > NEEDED(old_size, BLOCK_SIZE)) {
! db_unmark(LOGICAL_BLOCK(old_offset), old_size);
! new_offset = BLOCK_OFFSET(db_alloc(new_size));
! } else {
if (dump_db_file)
! dump_copy (LOGICAL_BLOCK(old_offset),
! NEEDED(old_size, BLOCK_SIZE));
new_offset = old_offset;
}
} else {
--- 482,530 ----
return 1;
}
+ Int check_free_blocks(Int blocks_needed, Int b)
+ {
+ Int count;
+
+ if (b >= bitmap_blocks)
+ return 0;
+ for (count = 0; count < blocks_needed; count++) {
+ if (bitmap[b >> 3] & (1 << (b & 7)))
+ break;
+ b++;
+ if (b >= bitmap_blocks)
+ break;
+ }
+ return count == blocks_needed;
+ }
+
Int db_put(Obj *obj, Long objnum)
{
off_t old_offset, new_offset;
! Int old_size, new_size = size_object(obj), tmp1, tmp2;
db_is_dirty();
if (lookup_retrieve_objnum(objnum, &old_offset, &old_size)) {
! if ((tmp1=NEEDED(new_size, BLOCK_SIZE)) > (tmp2=NEEDED(old_size, BLOCK_SIZE))) {
! /* check for the possible realloc */
! if (check_free_blocks(tmp1 - tmp2, LOGICAL_BLOCK(old_offset)+tmp2)) {
! /* no, we don't have to move, just overwrite */
! if (dump_db_file)
! dump_copy (LOGICAL_BLOCK(old_offset), tmp1);
! db_mark(LOGICAL_BLOCK(old_offset) + tmp2,
! BLOCK_SIZE * (tmp1 - tmp2));
! new_offset = old_offset;
! } else {
! db_unmark(LOGICAL_BLOCK(old_offset), old_size);
! new_offset = BLOCK_OFFSET(db_alloc(new_size));
! }
! } else {
if (dump_db_file)
! dump_copy (LOGICAL_BLOCK(old_offset), tmp2);
! if (tmp1 < tmp2) {
! db_unmark(LOGICAL_BLOCK(old_offset) + tmp1,
! BLOCK_SIZE * (tmp2 - tmp1));
! }
new_offset = old_offset;
}
} else {