diff --git a/src/libmdb/data.c b/src/libmdb/data.c index 3f26b0e..1242248 100644 --- a/src/libmdb/data.c +++ b/src/libmdb/data.c @@ -21,6 +21,8 @@ #include "time.h" #include "math.h" +//#define FAST_READ 1 + char *mdb_money_to_string(MdbHandle *mdb, int start, char *s); static int _mdb_attempt_bind(MdbHandle *mdb, MdbColumn *col, unsigned char isnull, int offset, int len); @@ -342,12 +344,34 @@ int mdb_read_next_dpg(MdbTableDef *table) MdbCatalogEntry *entry = table->entry; MdbHandle *mdb = entry->mdb; +#if FAST_READ +int pgnum, i, bitn; + + pgnum = _mdb_get_int32(table->usage_map,1); + /* the first 5 bytes of the usage map mean something */ + for (i=5;imap_sz;i++) { + for (bitn=0;bitn<8;bitn++) { + if (table->usage_map[i] & 1 << bitn && pgnum > table->cur_phys_pg) { + table->cur_phys_pg = pgnum; + if (!mdb_read_pg(mdb, pgnum)) { + return 0; + } else { + return pgnum; + } + } + pgnum++; + } + } + /* didn't find anything */ + return 0; +#else do { if (!mdb_read_pg(mdb, table->cur_phys_pg++)) return 0; } while (mdb->pg_buf[0]!=0x01 || mdb_get_int32(mdb, 4)!=entry->table_pg); /* fprintf(stderr,"returning new page %ld\n", table->cur_phys_pg); */ return table->cur_phys_pg; +#endif } int mdb_rewind_table(MdbTableDef *table) { @@ -418,6 +442,17 @@ int mdb_is_fixed_col(MdbColumn *col) { return col->is_fixed; } +static char *mdb_data_to_hex(MdbHandle *mdb, char *text, int start, int size) +{ +int i; + + for (i=start; ipg_buf[i]); + } + text[(i-start)*2]='\0'; + + return text; +} static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size) { guint16 memo_len; @@ -577,6 +612,7 @@ char *mdb_col_to_string(MdbHandle *mdb, int start, int datatype, int size) { /* FIX ME -- not thread safe */ static char text[MDB_BIND_SIZE]; +char tmpbuf[10]; time_t t; int i,j; diff --git a/src/libmdb/file.c b/src/libmdb/file.c index 4afc4d6..8e0b148 100644 --- a/src/libmdb/file.c +++ b/src/libmdb/file.c @@ -48,6 +48,7 @@ int j,pos; mdb->tab_num_cols_offset = 45; mdb->tab_num_idxs_offset = 47; mdb->tab_num_ridxs_offset = 51; + mdb->tab_usage_map_offset = 55; mdb->tab_first_dpg_offset = 56; mdb->tab_cols_start_offset = 63; mdb->tab_ridx_entry_size = 12; @@ -62,6 +63,7 @@ int j,pos; mdb->tab_num_cols_offset = 25; mdb->tab_num_idxs_offset = 27; mdb->tab_num_ridxs_offset = 31; + mdb->tab_usage_map_offset = 35; mdb->tab_first_dpg_offset = 36; mdb->tab_cols_start_offset = 43; mdb->tab_ridx_entry_size = 8; @@ -185,18 +187,26 @@ unsigned char *c; mdb->cur_pos+=3; return l; } -long mdb_get_int32(MdbHandle *mdb, int offset) +long _mdb_get_int32(unsigned char *buf, int offset) { long l; unsigned char *c; - if (offset <0 || offset+4 > mdb->pg_size) return -1; - c = &mdb->pg_buf[offset]; + c = &buf[offset]; l =c[3]; l<<=8; l+=c[2]; l<<=8; l+=c[1]; l<<=8; l+=c[0]; + return l; +} +long mdb_get_int32(MdbHandle *mdb, int offset) +{ +long l; + + if (offset <0 || offset+4 > mdb->pg_size) return -1; + + l = _mdb_get_int32(mdb->pg_buf, offset); mdb->cur_pos+=4; return l; } diff --git a/src/libmdb/table.c b/src/libmdb/table.c index 8ad47ab..d198ac0 100644 --- a/src/libmdb/table.c +++ b/src/libmdb/table.c @@ -43,6 +43,7 @@ MdbTableDef *mdb_read_table(MdbCatalogEntry *entry) MdbTableDef *table; MdbHandle *mdb = entry->mdb; int len, i; +int rownum, row_start, row_end; table = mdb_alloc_tabledef(entry); @@ -53,6 +54,22 @@ int len, i; table->num_cols = mdb_get_int16(mdb, mdb->tab_num_cols_offset); table->num_idxs = mdb_get_int32(mdb, mdb->tab_num_idxs_offset); table->num_real_idxs = mdb_get_int32(mdb, mdb->tab_num_ridxs_offset); + + /* grab a copy of the usage map */ + rownum = mdb->pg_buf[mdb->tab_usage_map_offset]; + mdb_read_alt_pg(mdb, mdb_get_int24(mdb, mdb->tab_usage_map_offset + 1)); + mdb_swap_pgbuf(mdb); + row_start = mdb_get_int16(mdb, (mdb->row_count_offset + 2) + (rownum*2)); + row_end = mdb_find_end_of_row(mdb, rownum); + table->map_sz = row_end - row_start; + table->usage_map = malloc(table->map_sz); + memcpy(table->usage_map, &mdb->pg_buf[row_start], table->map_sz); + buffer_dump(mdb->pg_buf, row_start, row_end); + /* swap back */ + mdb_swap_pgbuf(mdb); + printf ("usage map found on page %ld start %d end %d\n", mdb_get_int24(mdb, mdb->tab_usage_map_offset + 1), row_start, row_end); + + table->first_data_pg = mdb_get_int16(mdb, mdb->tab_first_dpg_offset); return table; @@ -208,7 +225,8 @@ MdbTableDef *table; MdbColumn *col; MdbIndex *idx; MdbHandle *mdb = entry->mdb; -int i; +int i,bitn; +int pgnum; table = mdb_read_table(entry); fprintf(stdout,"definition page = %d\n",entry->table_pg); @@ -233,4 +251,15 @@ int i; idx = g_ptr_array_index (table->indices, i); mdb_index_dump(table, idx); } + if (table->usage_map) { + pgnum = _mdb_get_int32(table->usage_map,1); + /* the first 5 bytes of the usage map mean something */ + for (i=5;imap_sz;i++) { + for (bitn=0;bitn<8;bitn++) { + if (table->usage_map[i] & 1 << bitn) + printf("page %ld is reserved by this object\n",pgnum); + pgnum++; + } + } + } }