Factorizing usage map functions

This commit is contained in:
whydoubt 2004-08-19 12:54:50 +00:00
parent 1960e3808b
commit e60bfed490
2 changed files with 42 additions and 114 deletions

View File

@ -434,102 +434,20 @@ static int _mdb_attempt_bind(MdbHandle *mdb,
} }
return 1; return 1;
} }
static int int mdb_read_next_dpg(MdbTableDef *table)
mdb_read_next_dpg0(MdbTableDef *table)
{ {
MdbCatalogEntry *entry = table->entry; MdbCatalogEntry *entry = table->entry;
MdbHandle *mdb = entry->mdb; MdbHandle *mdb = entry->mdb;
unsigned int pgnum, i; int map_type;
unsigned char *usage_bitmap;
unsigned int usage_bitlen;
pgnum = mdb_get_int32(table->usage_map,1);
/* the first 5 bytes of the usage map mean something */
usage_bitmap = table->usage_map + 5;
usage_bitlen = (table->map_sz - 5) * 8;
for (i=table->cur_phys_pg-pgnum+1; i<usage_bitlen; i++) {
if (usage_bitmap[i/8] & (1 << (i%8))) {
table->cur_phys_pg = pgnum + i;
return (mdb_read_pg(mdb, table->cur_phys_pg))
? table->cur_phys_pg : 0;
}
}
/* didn't find anything */
return 0;
}
static int
mdb_read_next_dpg1(MdbTableDef *table)
{
MdbCatalogEntry *entry = table->entry;
MdbHandle *mdb = entry->mdb;
guint32 i, map_pg, map_ind, max_map_pgs, offset;
unsigned char *usage_bitmap;
unsigned int usage_bitlen = (mdb->fmt->pg_size - 4) * 8;
/*
* table->cur_phys_pg will tell us where to (re)start the scan
* for the next data page. each usage_map entry points to a
* 0x05 page which bitmaps (mdb->fmt->pg_size - 4) * 8 pages.
*
* map_ind gives us the starting usage_map entry
* offset gives us a page offset into the bitmap (must be converted
* to bytes and bits).
*/
max_map_pgs = (table->map_sz - 1) / 4;
map_ind = (table->cur_phys_pg + 1) / usage_bitlen;
offset = (table->cur_phys_pg + 1) % usage_bitlen;
//printf("map size %ld\n", table->map_sz);
for (; map_ind<max_map_pgs; map_ind++) {
map_pg = mdb_get_int32(table->usage_map, (map_ind*4)+1);
//printf("loop %d pg %ld %02x%02x%02x%02x\n",i, map_pg,table->usage_map[i],table->usage_map[i+1],table->usage_map[i+2],table->usage_map[i+3]);
/* if the usage_map entry is empty, skip it */
if (!map_pg) {
continue;
}
if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) {
fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg);
exit(1);
}
//printf("reading page %ld\n",map_pg);
usage_bitmap = mdb->alt_pg_buf + 4;
for (i=offset; i<usage_bitlen; i++) {
if (usage_bitmap[i/8] & (1 << (i%8))) {
table->cur_phys_pg = map_ind*usage_bitlen + i;
return (mdb_read_pg(mdb, table->cur_phys_pg))
? table->cur_phys_pg : 0;
}
}
offset = 0;
}
/* didn't find anything */
//printf("returning 0\n");
return 0;
}
int
mdb_read_next_dpg(MdbTableDef *table)
{
MdbCatalogEntry *entry = table->entry;
MdbHandle *mdb = entry->mdb;
int map_type;
guint32 pg;
#ifndef SLOW_READ #ifndef SLOW_READ
map_type = table->usage_map[0]; table->cur_phys_pg = mdb_map_find_next(mdb, table->usage_map,
if (map_type==0) { table->map_sz, table->cur_phys_pg);
pg = mdb_read_next_dpg0(table);
//printf("Next dpg = %lu\n", pg); if (table->cur_phys_pg && mdb_read_pg(mdb, table->cur_phys_pg)) {
return pg; return table->cur_phys_pg;
} else if (map_type==1) {
pg = mdb_read_next_dpg1(table);
//printf("Next dpg = %lu\n", pg);
return pg;
} else { } else {
fprintf(stderr,"Warning: unrecognized usage map type: %d, defaulting to brute force read\n",table->usage_map[0]); return 0;
} }
#endif #endif
/* can't do a fast read, go back to the old way */ /* can't do a fast read, go back to the old way */

View File

@ -26,16 +26,16 @@
static guint32 static guint32
mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg) mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
{ {
unsigned int pgnum, i, bitn; guint32 pgnum, i, usage_bitlen;
unsigned char *usage_bitmap;
pgnum = mdb_get_int32(map,1); pgnum = mdb_get_int32(map, 1);
/* the first 5 bytes of the usage map mean something */ usage_bitmap = map + 5;
for (i=5;i<map_sz;i++) { usage_bitlen = (map_sz - 5) * 8;
for (bitn=0;bitn<8;bitn++) {
if ((map[i] & (1 << bitn)) && (pgnum > start_pg)) { for (i=start_pg-pgnum+1; i<usage_bitlen; i++) {
return pgnum; if (usage_bitmap[i/8] & (1 << (i%8))) {
} return pgnum + i;
pgnum++;
} }
} }
/* didn't find anything */ /* didn't find anything */
@ -44,32 +44,42 @@ mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guin
static int static int
mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg) mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
{ {
guint32 pgnum, i, j, bitn, map_pg; guint32 map_ind, max_map_pgs, offset, usage_bitlen;
pgnum = 0; /*
//printf("map size %ld\n", table->map_sz); * start_pg will tell us where to (re)start the scan
for (i=1;i<map_sz-1;i+=4) { * for the next data page. each usage_map entry points to a
map_pg = mdb_get_int32(map, i); * 0x05 page which bitmaps (mdb->fmt->pg_size - 4) * 8 pages.
//printf("loop %d pg %ld %02x%02x%02x%02x\n",i, map_pg,table->usage_map[i],table->usage_map[i+1],table->usage_map[i+2],table->usage_map[i+3]); *
* map_ind gives us the starting usage_map entry
* offset gives us a page offset into the bitmap
*/
usage_bitlen = (mdb->fmt->pg_size - 4) * 8;
max_map_pgs = (map_sz - 1) / 4;
map_ind = (start_pg + 1) / usage_bitlen;
offset = (start_pg + 1) % usage_bitlen;
if (!map_pg) continue; for (; map_ind<max_map_pgs; map_ind++) {
unsigned char *usage_bitmap;
guint32 i, map_pg;
if (!(map_pg = mdb_get_int32(map, (map_ind*4)+1))) {
continue;
}
if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) { if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) {
fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg); fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg);
exit(1); exit(1);
} }
//printf("reading page %ld\n",map_pg);
for (j=4;j<mdb->fmt->pg_size;j++) { usage_bitmap = mdb->alt_pg_buf + 4;
for (bitn=0;bitn<8;bitn++) { for (i=offset; i<usage_bitlen; i++) {
if (mdb->alt_pg_buf[j] & 1 << bitn && pgnum > start_pg) { if (usage_bitmap[i/8] & (1 << (i%8))) {
return pgnum; return map_ind*usage_bitlen + i;
}
pgnum++;
} }
} }
offset = 0;
} }
/* didn't find anything */ /* didn't find anything */
//printf("returning 0\n");
return 0; return 0;
} }
guint32 guint32