]> pd.if.org Git - btree/blobdiff - btree2t.c
Fix small bug in main when there is less t han one input file
[btree] / btree2t.c
index 3eb84e0a1b9923cda33926f4a6b4740387b6a87a..1a544e956f88970c9157ffb25c2a9d58104a951e 100644 (file)
--- a/btree2t.c
+++ b/btree2t.c
@@ -1,6 +1,6 @@
-// btree version 2t
+// btree version 2t  sched_yield version of spinlocks
 //     with reworked bt_deletekey code
-// 25 FEB 2014
+// 12 MAR 2014
 
 // author: karl malbrain, malbrain@cal.berkeley.edu
 
@@ -56,7 +56,7 @@ typedef unsigned short                ushort;
 typedef unsigned int           uint;
 #endif
 
-#define BT_latchtable  128                                     // number of latch manager slots
+#define BT_latchtable  8192                                    // number of latch manager slots
 
 #define BT_ro 0x6f72   // ro
 #define BT_rw 0x7772   // rw
@@ -91,12 +91,16 @@ typedef enum{
 // grant write lock when share == 0
 
 volatile typedef struct {
-       unsigned char mutex[1];
-       unsigned char exclusive:1;
-       unsigned char pending:1;
-       ushort share;
+       ushort exclusive:1;
+       ushort pending:1;
+       ushort share:14;
 } BtSpinLatch;
 
+#define XCL 1
+#define PEND 2
+#define BOTH 3
+#define SHARE 4
+
 //  hash table entries
 
 typedef struct {
@@ -358,7 +362,7 @@ BtKey ptr;
        return bt->err = err;
 }
 
-//     Latch Manager
+//     Spin Latch Manager
 
 //     wait until write lock mode is clear
 //     and add 1 to the share count
@@ -368,28 +372,20 @@ void bt_spinreadlock(BtSpinLatch *latch)
 ushort prev;
 
   do {
-       //      obtain latch mutex
 #ifdef unix
-       if( __sync_lock_test_and_set(latch->mutex, 1) )
-               continue;
+       prev = __sync_fetch_and_add ((ushort *)latch, SHARE);
 #else
-       if( _InterlockedExchange8(latch->mutex, 1) )
-               continue;
+       prev = _InterlockedExchangeAdd16((ushort *)latch, SHARE);
 #endif
        //  see if exclusive request is granted or pending
 
-       if( prev = !(latch->exclusive | latch->pending) )
-               latch->share++;
-
+       if( !(prev & BOTH) )
+               return;
 #ifdef unix
-       *latch->mutex = 0;
+       prev = __sync_fetch_and_add ((ushort *)latch, -SHARE);
 #else
-       _InterlockedExchange8(latch->mutex, 0);
+       prev = _InterlockedExchangeAdd16((ushort *)latch, -SHARE);
 #endif
-
-       if( prev )
-               return;
-
 #ifdef  unix
   } while( sched_yield(), 1 );
 #else
@@ -401,27 +397,23 @@ ushort prev;
 
 void bt_spinwritelock(BtSpinLatch *latch)
 {
-uint prev;
+ushort prev;
 
   do {
 #ifdef  unix
-       if( __sync_lock_test_and_set(latch->mutex, 1) )
-               continue;
+       prev = __sync_fetch_and_or((ushort *)latch, PEND | XCL);
 #else
-       if( _InterlockedExchange8(latch->mutex, 1) )
-               continue;
+       prev = _InterlockedOr16((ushort *)latch, PEND | XCL);
 #endif
-       if( prev = !(latch->share | latch->exclusive) )
-               latch->exclusive = 1, latch->pending = 0;
-       else
-               latch->pending = 1;
+       if( !(prev & XCL) )
+         if( !(prev & ~BOTH) )
+               return;
+         else
 #ifdef unix
-       *latch->mutex = 0;
+               __sync_fetch_and_and ((ushort *)latch, ~XCL);
 #else
-       _InterlockedExchange8(latch->mutex, 0);
+               _InterlockedAnd16((ushort *)latch, ~XCL);
 #endif
-       if( prev )
-               return;
 #ifdef  unix
   } while( sched_yield(), 1 );
 #else
@@ -436,26 +428,25 @@ uint prev;
 
 int bt_spinwritetry(BtSpinLatch *latch)
 {
-uint prev;
+ushort prev;
 
-#ifdef unix
-       if( __sync_lock_test_and_set(latch->mutex, 1) )
-               return 0;
+#ifdef  unix
+       prev = __sync_fetch_and_or((ushort *)latch, XCL);
 #else
-       if( _InterlockedExchange8(latch->mutex, 1) )
-               return 0;
+       prev = _InterlockedOr16((ushort *)latch, XCL);
 #endif
        //      take write access if all bits are clear
 
-       if( prev = !(latch->exclusive | latch->share) )
-               latch->exclusive = 1;
-
+       if( !(prev & XCL) )
+         if( !(prev & ~BOTH) )
+               return 1;
+         else
 #ifdef unix
-       *latch->mutex = 0;
+               __sync_fetch_and_and ((ushort *)latch, ~XCL);
 #else
-       _InterlockedExchange8(latch->mutex, 0);
+               _InterlockedAnd16((ushort *)latch, ~XCL);
 #endif
-       return prev;
+       return 0;
 }
 
 //     clear write mode
@@ -463,17 +454,9 @@ uint prev;
 void bt_spinreleasewrite(BtSpinLatch *latch)
 {
 #ifdef unix
-       while( __sync_lock_test_and_set(latch->mutex, 1) )
-               sched_yield();
-#else
-       while( _InterlockedExchange8(latch->mutex, 1) )
-               SwitchToThread();
-#endif
-       latch->exclusive = 0;
-#ifdef unix
-       *latch->mutex = 0;
+       __sync_fetch_and_and((ushort *)latch, ~BOTH);
 #else
-       _InterlockedExchange8(latch->mutex, 0);
+       _InterlockedAnd16((ushort *)latch, ~BOTH);
 #endif
 }
 
@@ -482,17 +465,9 @@ void bt_spinreleasewrite(BtSpinLatch *latch)
 void bt_spinreleaseread(BtSpinLatch *latch)
 {
 #ifdef unix
-       while( __sync_lock_test_and_set(latch->mutex, 1) )
-               sched_yield();
+       __sync_fetch_and_add((ushort *)latch, -SHARE);
 #else
-       while( _InterlockedExchange8(latch->mutex, 1) )
-               SwitchToThread();
-#endif
-       latch->share--;
-#ifdef unix
-       *latch->mutex = 0;
-#else
-       _InterlockedExchange8(latch->mutex, 0);
+       _InterlockedExchangeAdd16((ushort *)latch, -SHARE);
 #endif
 }
 
@@ -728,6 +703,7 @@ int flag;
 #ifndef unix
 SYSTEM_INFO sysinfo[1];
 OVERLAPPED ovl[1];
+uint len, flags;
 #else
 struct flock lock[1];
 #endif
@@ -835,7 +811,7 @@ struct flock lock[1];
 
        bt->hashsize = hashsize;
 
-       if( bt->nodemax = nodemax ) {
+       if( bt->nodemax = nodemax++ ) {
 #ifdef unix
          bt->nodes = calloc (nodemax, sizeof(BtHash));
          bt->cache = calloc (hashsize, sizeof(ushort));
@@ -854,12 +830,19 @@ struct flock lock[1];
        // and page(s) of latches
 
        memset (latchmgr, 0, 1 << bits);
-       nlatchpage = BT_latchtable / (bt->page_size / sizeof(BtLatchSet)) + 1; 
+
+       nlatchpage = BT_latchtable;
+       if( nlatchpage > nodemax )
+               nlatchpage = nodemax;
+       nlatchpage *= sizeof(BtLatchSet);
+       nlatchpage += bt->page_size - 1;
+       nlatchpage /= bt->page_size;
+
        bt_putid(latchmgr->alloc->right, MIN_lvl+1+nlatchpage);
        latchmgr->alloc->bits = bt->page_bits;
 
        latchmgr->nlatchpage = nlatchpage;
-       latchmgr->latchtotal = nlatchpage * (bt->page_size / sizeof(BtLatchSet));
+       latchmgr->latchtotal = nlatchpage * bt->page_size / sizeof(BtLatchSet);
 
        //  initialize latch manager
 
@@ -1197,12 +1180,12 @@ BtHash *hash;
 BtPage bt_linklru(BtDb *bt, BtHash *hash, uid page_no)
 {
 int flag;
-off64_t off = (page_no & ~bt->hashmask) << bt->page_bits;
+off64_t off = (page_no & ~(uid)bt->hashmask) << bt->page_bits;
 off64_t limit = off + ((bt->hashmask+1) << bt->page_bits);
 BtHash *node;
 
        memset(hash, 0, sizeof(BtHash));
-       hash->page_no = (page_no & ~bt->hashmask);
+       hash->page_no = (page_no & ~(uid)bt->hashmask);
        bt_linkhash(bt, hash, page_no);
 
        if( node = hash->lrunext = bt->lrufirst )
@@ -1282,7 +1265,7 @@ BtPage page;
 #ifdef unix
                munmap (hash->page, (bt->hashmask+1) << bt->page_bits);
 #else
-               FlushViewOfFile(hash->page, 0);
+//             FlushViewOfFile(hash->page, 0);
                UnmapViewOfFile(hash->page);
                CloseHandle(hash->hmap);
 #endif
@@ -2133,6 +2116,8 @@ 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;
@@ -2179,7 +2164,20 @@ BtKey ptr;
        page_no = LEAF_page;
 
        while( page_no < bt_getid(bt->latchmgr->alloc->right) ) {
-               pread (bt->idx, bt->frame, bt->page_size, page_no << bt->page_bits);
+       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);
@@ -2195,7 +2193,6 @@ BtKey ptr;
                page_no = next;
        }
        return cnt - 1;
-#endif
 }
 
 #ifndef unix
@@ -2383,15 +2380,30 @@ FILE *in;
                break;
 
        case 's':
-               scan++;
+               fprintf(stderr, "started scaning\n");
+               cnt = len = key[0] = 0;
 
-       case 'c':
-         cnt = 0;
+               if( slot = bt_startkey (bt, key, len) )
+                 slot--;
+               else
+                 fprintf(stderr, "Error %d in StartKey. Syserror: %d\n", bt->err, errno), exit(0);
+
+               while( slot = bt_nextkey (bt, slot) ) {
+                       ptr = bt_key(bt, slot);
+                       fwrite (ptr->key, ptr->len, 1, stdout);
+                       fputc ('\n', stdout);
+                       cnt++;
+               }
+
+               fprintf(stderr, " Total keys read %d\n", cnt - 1);
+               break;
 
+       case 'c':
          fprintf(stderr, "started counting\n");
 
          next = bt->latchmgr->nlatchpage + LATCH_page;
          page_no = LEAF_page;
+         cnt = 0;
 
          while( page_no < bt_getid(bt->latchmgr->alloc->right) ) {
          uid off = page_no << bt->page_bits;