]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
In the unix OS implementation, replace inode hash tables with linked lists. (CVS...
authordrh <drh@noemail.net>
Wed, 30 Jul 2008 15:27:54 +0000 (15:27 +0000)
committerdrh <drh@noemail.net>
Wed, 30 Jul 2008 15:27:54 +0000 (15:27 +0000)
FossilOrigin-Name: db4022db64dc5864e6f1d0a20672183879ad43aa

manifest
manifest.uuid
src/os_unix.c
src/test1.c

index 0614359670504eda770cef8105e2e6d372924067..efd953eb3005a1afc3fb464387de85ecba9b2f0a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Implicit\sstring->numeric\sconversion\sshould\sgo\sto\san\sinteger\svalue\swhen\npossible.\s\sTicket\s#3257.\s(CVS\s5502)
-D 2008-07-30T13:27:11
+C In\sthe\sunix\sOS\simplementation,\sreplace\sinode\shash\stables\swith\slinked\slists.\s(CVS\s5503)
+D 2008-07-30T15:27:54
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in bbb62eecc851379aef5a48a1bf8787eb13e6ec06
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -133,7 +133,7 @@ F src/os.c 939ae7690a01d9401685ba124b4ba45fd4a7a2ad
 F src/os.h ef8abeb9afc694b82dbd169a91c9b7e26db3c892
 F src/os_common.h 24525d8b7bce66c374dfc1810a6c9043f3359b60
 F src/os_os2.c 676ed273b17bd260f905df81375c9f9950d85517
-F src/os_unix.c 1df6108efdb7957a9f28b9700600e58647c9c12d
+F src/os_unix.c c778a6b7098f54ee2e4420150265ad3d26824c96
 F src/os_win.c 50ec783403b418ddc9e6e05d541c6027dfd41070
 F src/pager.c a6ecad26297469a8a3d1fd7a7c3dc2d603955044
 F src/pager.h 588c1ac195228b2da45c4e5f7ab6c2fd253d1751
@@ -151,7 +151,7 @@ F src/sqliteLimit.h f435e728c6b620ef7312814d660a81f9356eb5c8
 F src/status.c ca61c18b6f1c632b771514e0c39a7d662c805bbf
 F src/table.c 22744786199c9195720c15a7a42cb97b2e2728d8
 F src/tclsqlite.c ec46084184f033ba396a9ee7b5514b695083d0f3
-F src/test1.c 346e9262793be825ebadd9e69600d1b4682650f1
+F src/test1.c c7d37c6d6ce5a84c45546dfafae12e5c46c656ce
 F src/test2.c 7a634c1e044be3ea5845e65155fdd1cab13936cb
 F src/test3.c e00795839be38f0345a4845170426fb17d828bf9
 F src/test4.c 41056378671e7b00e6305fa9ac6fa27e6f96f406
@@ -614,7 +614,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 4a6ee88697ddc28e0c7df1954d1526de18191827
-R 1fc491d5b31cb2a2cf0986670de436ee
+P da0e4bff30a77f72ae283406b547401c2ebb42c5
+R 4761a1459dbfe21d158c4e02d11ac727
 U drh
-Z 6e72d4e65f10edd96172495856b81fe0
+Z 2fbbc6538919439da5b60f94f6787348
index 2035441ac03558d411a0d10c222c5cc2b6ea2101..660828ab409b2ff13e142c3bf0a0aae7a50e0481 100644 (file)
@@ -1 +1 @@
-da0e4bff30a77f72ae283406b547401c2ebb42c5
\ No newline at end of file
+db4022db64dc5864e6f1d0a20672183879ad43aa
\ No newline at end of file
index ca65836f46dc215447454b49f4acb5bbce5be003..48d2ff176922262f97cc324ed963d796956ba968 100644 (file)
@@ -12,7 +12,7 @@
 **
 ** This file contains code that is specific to Unix systems.
 **
-** $Id: os_unix.c,v 1.193 2008/07/10 00:32:42 drh Exp $
+** $Id: os_unix.c,v 1.194 2008/07/30 15:27:54 drh Exp $
 */
 #include "sqliteInt.h"
 #if SQLITE_OS_UNIX              /* This file is used on unix only */
@@ -311,6 +311,7 @@ struct lockInfo {
   int cnt;             /* Number of SHARED locks held */
   int locktype;        /* One of SHARED_LOCK, RESERVED_LOCK etc. */
   int nRef;            /* Number of pointers to this structure */
+  struct lockInfo *pNext, *pPrev;   /* List of all lockInfo objects */
 };
 
 /*
@@ -336,15 +337,17 @@ struct openCnt {
   int nLock;            /* Number of outstanding locks */
   int nPending;         /* Number of pending close() operations */
   int *aPending;        /* Malloced space holding fd's awaiting a close() */
+  struct openCnt *pNext, *pPrev;   /* List of all openCnt objects */
 };
 
-/* 
-** These hash tables map inodes and file descriptors (really, lockKey and
-** openKey structures) into lockInfo and openCnt structures.  Access to 
-** these hash tables must be protected by a mutex.
+/*
+** List of all lockInfo and openCnt objects.  This used to be a hash
+** table.  But the number of objects is rarely more than a dozen and
+** never exceeds a few thousand.  And lookup is not on a critical
+** path oo a simple linked list will suffice.
 */
-static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
-static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
+static struct lockInfo *lockList = 0;
+static struct openCnt *openList = 0;
 
 /*
 ** The locking styles are associated with the different file locking
@@ -362,9 +365,9 @@ static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
 **   file systems that are known to be unsupported
 */
 #define LOCKING_STYLE_POSIX        1
-#define LOCKING_STYLE_FLOCK        2
+#define LOCKING_STYLE_NONE         2
 #define LOCKING_STYLE_DOTFILE      3
-#define LOCKING_STYLE_NONE         4
+#define LOCKING_STYLE_FLOCK        4
 #define LOCKING_STYLE_AFP          5
 
 /*
@@ -523,7 +526,17 @@ static void releaseLockInfo(struct lockInfo *pLock){
   if( pLock ){
     pLock->nRef--;
     if( pLock->nRef==0 ){
-      sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
+      if( pLock->pPrev ){
+        assert( pLock->pPrev->pNext==pLock );
+        pLock->pPrev->pNext = pLock->pNext;
+      }else{
+        assert( lockList==pLock );
+        lockList = pLock->pNext;
+      }
+      if( pLock->pNext ){
+        assert( pLock->pNext->pPrev==pLock );
+        pLock->pNext->pPrev = pLock->pPrev;
+      }
       sqlite3_free(pLock);
     }
   }
@@ -536,8 +549,18 @@ static void releaseOpenCnt(struct openCnt *pOpen){
   if( pOpen ){
     pOpen->nRef--;
     if( pOpen->nRef==0 ){
-      sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
-      free(pOpen->aPending);
+      if( pOpen->pPrev ){
+        assert( pOpen->pPrev->pNext==pOpen );
+        pOpen->pPrev->pNext = pOpen->pNext;
+      }else{
+        assert( openList==pOpen );
+        openList = pOpen->pNext;
+      }
+      if( pOpen->pNext ){
+        assert( pOpen->pNext->pPrev==pOpen );
+        pOpen->pNext->pPrev = pOpen->pPrev;
+      }
+      sqlite3_free(pOpen->aPending);
       sqlite3_free(pOpen);
     }
   }
@@ -663,9 +686,11 @@ static int findLockInfo(
   memset(&key2, 0, sizeof(key2));
   key2.dev = statbuf.st_dev;
   key2.ino = statbuf.st_ino;
-  pLock = (struct lockInfo*)sqlite3HashFind(&lockHash, &key1, sizeof(key1));
+  pLock = lockList;
+  while( pLock && memcmp(&key1, &pLock->key, sizeof(key1)) ){
+    pLock = pLock->pNext;
+  }
   if( pLock==0 ){
-    struct lockInfo *pOld;
     pLock = sqlite3_malloc( sizeof(*pLock) );
     if( pLock==0 ){
       rc = SQLITE_NOMEM;
@@ -675,21 +700,20 @@ static int findLockInfo(
     pLock->nRef = 1;
     pLock->cnt = 0;
     pLock->locktype = 0;
-    pOld = sqlite3HashInsert(&lockHash, &pLock->key, sizeof(key1), pLock);
-    if( pOld!=0 ){
-      assert( pOld==pLock );
-      sqlite3_free(pLock);
-      rc = SQLITE_NOMEM;
-      goto exit_findlockinfo;
-    }
+    pLock->pNext = lockList;
+    pLock->pPrev = 0;
+    if( lockList ) lockList->pPrev = pLock;
+    lockList = pLock;
   }else{
     pLock->nRef++;
   }
   *ppLock = pLock;
   if( ppOpen!=0 ){
-    pOpen = (struct openCnt*)sqlite3HashFind(&openHash, &key2, sizeof(key2));
+    pOpen = openList;
+    while( pOpen && memcmp(&key2, &pOpen->key, sizeof(key2)) ){
+      pOpen = pOpen->pNext;
+    }
     if( pOpen==0 ){
-      struct openCnt *pOld;
       pOpen = sqlite3_malloc( sizeof(*pOpen) );
       if( pOpen==0 ){
         releaseLockInfo(pLock);
@@ -701,14 +725,10 @@ static int findLockInfo(
       pOpen->nLock = 0;
       pOpen->nPending = 0;
       pOpen->aPending = 0;
-      pOld = sqlite3HashInsert(&openHash, &pOpen->key, sizeof(key2), pOpen);
-      if( pOld!=0 ){
-        assert( pOld==pOpen );
-        sqlite3_free(pOpen);
-        releaseLockInfo(pLock);
-        rc = SQLITE_NOMEM;
-        goto exit_findlockinfo;
-      }
+      pOpen->pNext = openList;
+      pOpen->pPrev = 0;
+      if( openList ) openList->pPrev = pOpen;
+      openList = pOpen;
     }else{
       pOpen->nRef++;
     }
@@ -1424,7 +1444,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){
         for(i=0; i<pOpen->nPending; i++){
           close(pOpen->aPending[i]);
         }
-        free(pOpen->aPending);
+        sqlite3_free(pOpen->aPending);
         pOpen->nPending = 0;
         pOpen->aPending = 0;
       }
@@ -1473,7 +1493,7 @@ static int unixClose(sqlite3_file *id){
       */
       int *aNew;
       struct openCnt *pOpen = pFile->pOpen;
-      aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
+      aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
       if( aNew==0 ){
         /* If a malloc fails, just leak the file descriptor */
       }else{
@@ -1970,7 +1990,7 @@ static int dotlockClose(sqlite3_file *id) {
 }
 
 
-#pragma mark No locking
+#endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
 /*
 ** The nolockLockingContext is void
@@ -1997,8 +2017,6 @@ static int nolockClose(sqlite3_file *id) {
   return closeUnixFile(id);
 }
 
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
 
 /*
 ** Information and control of an open file handle.
@@ -2047,8 +2065,13 @@ static int fillInUnixFile(
   int h,                  /* Open file descriptor of file being opened */
   int dirfd,              /* Directory file descriptor */
   sqlite3_file *pId,      /* Write to the unixFile structure here */
-  const char *zFilename   /* Name of the file being opened */
+  const char *zFilename,  /* Name of the file being opened */
+  int noLock              /* Omit locking if true */
 ){
+  int eLockingStyle;
+  unixFile *pNew = (unixFile *)pId;
+  int rc = SQLITE_OK;
+
   /* Macro to define the static contents of an sqlite3_io_methods 
   ** structure for a unix backend file. Different locking methods
   ** require different functions for the xClose, xLock, xUnlock and
@@ -2071,17 +2094,21 @@ static int fillInUnixFile(
   }
   static sqlite3_io_methods aIoMethod[] = {
     IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock) 
+   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
 #ifdef SQLITE_ENABLE_LOCKING_STYLE
-   ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
    ,IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock)
-   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
+   ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
    ,IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock)
 #endif
   };
-
-  int eLockingStyle;
-  unixFile *pNew = (unixFile *)pId;
-  int rc = SQLITE_OK;
+  /* The order of the IOMETHODS macros above is important.  It must be the
+  ** same order as the LOCKING_STYLE numbers
+  */
+  assert(LOCKING_STYLE_POSIX==1);
+  assert(LOCKING_STYLE_NONE==2);
+  assert(LOCKING_STYLE_DOTFILE==3);
+  assert(LOCKING_STYLE_FLOCK==4);
+  assert(LOCKING_STYLE_AFP==5);
 
   assert( pNew->pLock==NULL );
   assert( pNew->pOpen==NULL );
@@ -2091,12 +2118,11 @@ static int fillInUnixFile(
   pNew->dirfd = dirfd;
   SET_THREADID(pNew);
 
-  assert(LOCKING_STYLE_POSIX==1);
-  assert(LOCKING_STYLE_FLOCK==2);
-  assert(LOCKING_STYLE_DOTFILE==3);
-  assert(LOCKING_STYLE_NONE==4);
-  assert(LOCKING_STYLE_AFP==5);
-  eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+  if( noLock ){
+    eLockingStyle = LOCKING_STYLE_NONE;
+  }else{
+    eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+  }
 
   switch( eLockingStyle ){
 
@@ -2280,6 +2306,7 @@ static int unixOpen(
   int dirfd = -1;                /* Directory file descriptor */
   int oflags = 0;                /* Flags to pass to open() */
   int eType = flags&0xFFFFFF00;  /* Type of file to open */
+  int noLock;                    /* True to omit locking primitives */
 
   int isExclusive  = (flags & SQLITE_OPEN_EXCLUSIVE);
   int isDelete     = (flags & SQLITE_OPEN_DELETEONCLOSE);
@@ -2375,7 +2402,8 @@ static int unixOpen(
   fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
 #endif
 
-  return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath);
+  noLock = eType!=SQLITE_OPEN_MAIN_DB;
+  return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock);
 }
 
 /*
index 529ed84b450df41f5dcb90f27b6461b0d6103cad..1062d87c669f29c4f4c60b672f9bd9c68cded992 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test1.c,v 1.315 2008/07/12 14:52:20 drh Exp $
+** $Id: test1.c,v 1.316 2008/07/30 15:27:54 drh Exp $
 */
 #include "sqliteInt.h"
 #include "tcl.h"
@@ -3787,167 +3787,6 @@ static int test_stmt_int(
   return TCL_OK;
 }
 
-#ifndef SQLITE_OMIT_DISKIO
-#if 0
-/*
-** Usage:  sqlite3OsOpenReadWrite <filename>
-*/
-static int test_sqlite3OsOpenReadWrite(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  sqlite3_file *pFile;
-  int rc;
-  int dummy;
-  char zBuf[100];
-
-  if( objc!=2 ){
-    Tcl_AppendResult(interp, "wrong # args: should be \"", 
-       Tcl_GetString(objv[0]), " filename", 0);
-    return TCL_ERROR;
-  }
-
-  rc = sqlite3OsOpenReadWrite(Tcl_GetString(objv[1]), &pFile, &dummy);
-  if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
-    return TCL_ERROR;
-  }
-  sqlite3TestMakePointerStr(interp, zBuf, pFile);
-  Tcl_SetResult(interp, zBuf, 0);
-  return TCL_ERROR;
-}
-
-/*
-** Usage:  sqlite3OsClose <file handle>
-*/
-static int test_sqlite3OsClose(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  sqlite3_file *pFile;
-  int rc;
-
-  if( objc!=2 ){
-    Tcl_AppendResult(interp, "wrong # args: should be \"", 
-       Tcl_GetString(objv[0]), " filehandle", 0);
-    return TCL_ERROR;
-  }
-
-  if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
-    return TCL_ERROR;
-  }
-  rc = sqlite3OsClose(&pFile);
-  if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
-    return TCL_ERROR;
-  }
-  return TCL_OK;
-}
-
-/*
-** Usage:  sqlite3OsLock <file handle> <locktype>
-*/
-static int test_sqlite3OsLock(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  sqlite3_file * pFile;
-  int rc;
-
-  if( objc!=3 ){
-    Tcl_AppendResult(interp, "wrong # args: should be \"", 
-        Tcl_GetString(objv[0]), 
-        " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
-    return TCL_ERROR;
-  }
-
-  if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
-    return TCL_ERROR;
-  }
-
-  if( 0==strcmp("SHARED", Tcl_GetString(objv[2])) ){
-    rc = sqlite3OsLock(pFile, SHARED_LOCK);
-  }
-  else if( 0==strcmp("RESERVED", Tcl_GetString(objv[2])) ){
-    rc = sqlite3OsLock(pFile, RESERVED_LOCK);
-  }
-  else if( 0==strcmp("PENDING", Tcl_GetString(objv[2])) ){
-    rc = sqlite3OsLock(pFile, PENDING_LOCK);
-  }
-  else if( 0==strcmp("EXCLUSIVE", Tcl_GetString(objv[2])) ){
-    rc = sqlite3OsLock(pFile, EXCLUSIVE_LOCK);
-  }else{
-    Tcl_AppendResult(interp, "wrong # args: should be \"", 
-        Tcl_GetString(objv[0]), 
-        " filehandle (SHARED|RESERVED|PENDING|EXCLUSIVE)", 0);
-    return TCL_ERROR;
-  }
-
-  if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
-    return TCL_ERROR;
-  }
-  return TCL_OK;
-}
-
-/*
-** Usage:  sqlite3OsUnlock <file handle>
-*/
-static int test_sqlite3OsUnlock(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  sqlite3_file * pFile;
-  int rc;
-
-  if( objc!=2 ){
-    Tcl_AppendResult(interp, "wrong # args: should be \"", 
-       Tcl_GetString(objv[0]), " filehandle", 0);
-    return TCL_ERROR;
-  }
-
-  if( getFilePointer(interp, Tcl_GetString(objv[1]), &pFile) ){
-    return TCL_ERROR;
-  }
-  rc = sqlite3OsUnlock(pFile, NO_LOCK);
-  if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
-    return TCL_ERROR;
-  }
-  return TCL_OK;
-}
-
-/*
-** Usage:  sqlite3OsTempFileName
-*/
-static int test_sqlite3OsTempFileName(
-  void * clientData,
-  Tcl_Interp *interp,
-  int objc,
-  Tcl_Obj *CONST objv[]
-){
-  char zFile[SQLITE_TEMPNAME_SIZE];
-  int rc;
-
-  rc = sqlite3OsTempFileName(zFile);
-  if( rc!=SQLITE_OK ){
-    Tcl_SetResult(interp, (char *)t1ErrorName(rc), TCL_STATIC);
-    return TCL_ERROR;
-  }
-  Tcl_AppendResult(interp, zFile, 0);
-  return TCL_OK;
-}
-#endif
-#endif
-
 /*
 ** Usage:  sqlite_set_magic  DB  MAGIC-NUMBER
 **
@@ -4809,17 +4648,6 @@ int Sqlitetest1_Init(Tcl_Interp *interp){
      { "sqlite3_vfs_list",           vfs_list,     0   },
 
      /* Functions from os.h */
-#ifndef SQLITE_OMIT_DISKIO
-#if 0
-     { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
-     { "sqlite3OsClose",        test_sqlite3OsClose, 0 },
-     { "sqlite3OsLock",         test_sqlite3OsLock, 0 },
-     { "sqlite3OsTempFileName", test_sqlite3OsTempFileName, 0 },
-   
-     /* Custom test interfaces */
-     { "sqlite3OsUnlock",         test_sqlite3OsUnlock, 0    },
-#endif
-#endif
 #ifndef SQLITE_OMIT_UTF16
      { "add_test_collate",        test_collate, 0            },
      { "add_test_collate_needed", test_collate_needed, 0     },