+
+uint bt_audit (BtDb *bt)
+{
+ushort idx, hashidx;
+uid next, page_no;
+BtLatchSet *latch;
+uint cnt = 0;
+BtKey ptr;
+
+#ifdef unix
+ posix_fadvise( bt->idx, 0, 0, POSIX_FADV_SEQUENTIAL);
+#endif
+ if( *(ushort *)(bt->latchmgr->lock) )
+ fprintf(stderr, "Alloc page locked\n");
+ *(ushort *)(bt->latchmgr->lock) = 0;
+
+ for( idx = 1; idx <= bt->latchmgr->latchdeployed; idx++ ) {
+ latch = bt->latchsets + idx;
+ if( *(ushort *)latch->readwr )
+ fprintf(stderr, "latchset %d rwlocked for page %.8x\n", idx, latch->page_no);
+ *(ushort *)latch->readwr = 0;
+
+ if( *(ushort *)latch->access )
+ fprintf(stderr, "latchset %d accesslocked for page %.8x\n", idx, latch->page_no);
+ *(ushort *)latch->access = 0;
+
+ if( *(ushort *)latch->parent )
+ fprintf(stderr, "latchset %d parentlocked for page %.8x\n", idx, latch->page_no);
+ *(ushort *)latch->parent = 0;
+
+ if( latch->pin ) {
+ fprintf(stderr, "latchset %d pinned for page %.8x\n", idx, latch->page_no);
+ latch->pin = 0;
+ }
+ }
+
+ for( hashidx = 0; hashidx < bt->latchmgr->latchhash; hashidx++ ) {
+ if( *(ushort *)(bt->latchmgr->table[hashidx].latch) )
+ fprintf(stderr, "hash entry %d locked\n", hashidx);
+
+ *(ushort *)(bt->latchmgr->table[hashidx].latch) = 0;
+
+ if( idx = bt->latchmgr->table[hashidx].slot ) do {
+ latch = bt->latchsets + idx;
+ if( *(ushort *)latch->busy )
+ fprintf(stderr, "latchset %d busylocked for page %.8x\n", idx, latch->page_no);
+ *(ushort *)latch->busy = 0;
+ if( latch->hash != hashidx )
+ fprintf(stderr, "latchset %d wrong hashidx\n", idx);
+ if( latch->pin )
+ fprintf(stderr, "latchset %d pinned for page %.8x\n", idx, latch->page_no);
+ } while( idx = latch->next );
+ }
+
+ next = bt->latchmgr->nlatchpage + LATCH_page;
+ page_no = LEAF_page;
+
+ while( page_no < bt_getid(bt->latchmgr->alloc->right) ) {
+ off64_t off = page_no << bt->page_bits;
+#ifdef unix
+ pread (bt->idx, bt->frame, bt->page_size, off);
+#else
+ DWORD amt[1];
+
+ SetFilePointer (bt->idx, (long)off, (long*)(&off)+1, FILE_BEGIN);
+
+ if( !ReadFile(bt->idx, bt->frame, bt->page_size, amt, NULL))
+ fprintf(stderr, "page %.8x unable to read\n", page_no);
+
+ if( *amt < bt->page_size )
+ fprintf(stderr, "page %.8x unable to read\n", page_no);
+#endif
+ if( !bt->frame->free ) {
+ for( idx = 0; idx++ < bt->frame->cnt - 1; ) {
+ ptr = keyptr(bt->frame, idx+1);
+ if( keycmp (keyptr(bt->frame, idx), ptr->key, ptr->len) >= 0 )
+ fprintf(stderr, "page %.8x idx %.2x out of order\n", page_no, idx);
+ }
+ if( !bt->frame->lvl )
+ cnt += bt->frame->act;
+ }
+
+ if( page_no > LEAF_page )
+ next = page_no + 1;
+ page_no = next;
+ }
+ return cnt - 1;
+}
+
+#ifndef unix
+double getCpuTime(int type)
+{
+FILETIME crtime[1];
+FILETIME xittime[1];
+FILETIME systime[1];
+FILETIME usrtime[1];
+SYSTEMTIME timeconv[1];
+double ans = 0;
+
+ memset (timeconv, 0, sizeof(SYSTEMTIME));
+
+ switch( type ) {
+ case 0:
+ GetSystemTimeAsFileTime (xittime);
+ FileTimeToSystemTime (xittime, timeconv);
+ ans = (double)timeconv->wDayOfWeek * 3600 * 24;
+ break;
+ case 1:
+ GetProcessTimes (GetCurrentProcess(), crtime, xittime, systime, usrtime);
+ FileTimeToSystemTime (usrtime, timeconv);
+ break;
+ case 2:
+ GetProcessTimes (GetCurrentProcess(), crtime, xittime, systime, usrtime);
+ FileTimeToSystemTime (systime, timeconv);
+ break;
+ }
+
+ ans += (double)timeconv->wHour * 3600;
+ ans += (double)timeconv->wMinute * 60;
+ ans += (double)timeconv->wSecond;
+ ans += (double)timeconv->wMilliseconds / 1000;
+ return ans;
+}
+#else
+#include <time.h>
+#include <sys/resource.h>
+
+double getCpuTime(int type)
+{
+struct rusage used[1];
+struct timeval tv[1];
+
+ switch( type ) {
+ case 0:
+ gettimeofday(tv, NULL);
+ return (double)tv->tv_sec + (double)tv->tv_usec / 1000000;
+
+ case 1:
+ getrusage(RUSAGE_SELF, used);
+ return (double)used->ru_utime.tv_sec + (double)used->ru_utime.tv_usec / 1000000;
+
+ case 2:
+ getrusage(RUSAGE_SELF, used);
+ return (double)used->ru_stime.tv_sec + (double)used->ru_stime.tv_usec / 1000000;
+ }
+
+ return 0;
+}
+#endif
+