1075c23afSdanielk1977 /*
2075c23afSdanielk1977 ** 2008 September 1
3075c23afSdanielk1977 **
4075c23afSdanielk1977 ** The author disclaims copyright to this source code. In place of
5075c23afSdanielk1977 ** a legal notice, here is a blessing:
6075c23afSdanielk1977 **
7075c23afSdanielk1977 ** May you do good and not evil.
8075c23afSdanielk1977 ** May you find forgiveness for yourself and forgive others.
9075c23afSdanielk1977 ** May you share freely, never taking more than you give.
10075c23afSdanielk1977 **
11075c23afSdanielk1977 *************************************************************************
12075c23afSdanielk1977 **
13075c23afSdanielk1977 ** The code in this file contains sample implementations of the
14075c23afSdanielk1977 ** sqlite3_wsd_init() and sqlite3_wsd_find() functions required if the
15075c23afSdanielk1977 ** SQLITE_OMIT_WSD symbol is defined at build time.
16075c23afSdanielk1977 */
17075c23afSdanielk1977
18075c23afSdanielk1977 #if defined(SQLITE_OMIT_WSD) && defined(SQLITE_TEST)
19075c23afSdanielk1977
20075c23afSdanielk1977 #include "sqliteInt.h"
21075c23afSdanielk1977
22075c23afSdanielk1977 #define PLS_HASHSIZE 43
23075c23afSdanielk1977
24075c23afSdanielk1977 typedef struct ProcessLocalStorage ProcessLocalStorage;
25075c23afSdanielk1977 typedef struct ProcessLocalVar ProcessLocalVar;
26075c23afSdanielk1977
27075c23afSdanielk1977 struct ProcessLocalStorage {
28075c23afSdanielk1977 ProcessLocalVar *aData[PLS_HASHSIZE];
29075c23afSdanielk1977 int nFree;
30075c23afSdanielk1977 u8 *pFree;
31075c23afSdanielk1977 };
32075c23afSdanielk1977
33075c23afSdanielk1977 struct ProcessLocalVar {
34075c23afSdanielk1977 void *pKey;
35075c23afSdanielk1977 ProcessLocalVar *pNext;
36075c23afSdanielk1977 };
37075c23afSdanielk1977
38075c23afSdanielk1977 static ProcessLocalStorage *pGlobal = 0;
39075c23afSdanielk1977
sqlite3_wsd_init(int N,int J)40075c23afSdanielk1977 int sqlite3_wsd_init(int N, int J){
41075c23afSdanielk1977 if( !pGlobal ){
42075c23afSdanielk1977 int nMalloc = N + sizeof(ProcessLocalStorage) + J*sizeof(ProcessLocalVar);
43075c23afSdanielk1977 pGlobal = (ProcessLocalStorage *)malloc(nMalloc);
44075c23afSdanielk1977 if( pGlobal ){
45075c23afSdanielk1977 memset(pGlobal, 0, sizeof(ProcessLocalStorage));
46075c23afSdanielk1977 pGlobal->nFree = nMalloc - sizeof(ProcessLocalStorage);
47075c23afSdanielk1977 pGlobal->pFree = (u8 *)&pGlobal[1];
48075c23afSdanielk1977 }
49075c23afSdanielk1977 }
50075c23afSdanielk1977
51075c23afSdanielk1977 return pGlobal ? SQLITE_OK : SQLITE_NOMEM;
52075c23afSdanielk1977 }
53075c23afSdanielk1977
sqlite3_wsd_find(void * K,int L)54075c23afSdanielk1977 void *sqlite3_wsd_find(void *K, int L){
55075c23afSdanielk1977 int i;
56075c23afSdanielk1977 int iHash = 0;
57075c23afSdanielk1977 ProcessLocalVar *pVar;
58075c23afSdanielk1977
59075c23afSdanielk1977 /* Calculate a hash of K */
60075c23afSdanielk1977 for(i=0; i<sizeof(void*); i++){
61a8f83bfcSdanielk1977 iHash = (iHash<<3) + ((unsigned char *)&K)[i];
62075c23afSdanielk1977 }
63075c23afSdanielk1977 iHash = iHash%PLS_HASHSIZE;
64075c23afSdanielk1977
65075c23afSdanielk1977 /* Search the hash table for K. */
66075c23afSdanielk1977 for(pVar=pGlobal->aData[iHash]; pVar && pVar->pKey!=K; pVar=pVar->pNext);
67075c23afSdanielk1977
68075c23afSdanielk1977 /* If no entry for K was found, create and populate a new one. */
69075c23afSdanielk1977 if( !pVar ){
70*bc73971dSdanielk1977 int nByte = ROUND8(sizeof(ProcessLocalVar) + L);
71075c23afSdanielk1977 assert( pGlobal->nFree>=nByte );
72075c23afSdanielk1977 pVar = (ProcessLocalVar *)pGlobal->pFree;
73075c23afSdanielk1977 pVar->pKey = K;
74075c23afSdanielk1977 pVar->pNext = pGlobal->aData[iHash];
75075c23afSdanielk1977 pGlobal->aData[iHash] = pVar;
76075c23afSdanielk1977 pGlobal->nFree -= nByte;
77075c23afSdanielk1977 pGlobal->pFree += nByte;
78075c23afSdanielk1977 memcpy(&pVar[1], K, L);
79075c23afSdanielk1977 }
80075c23afSdanielk1977
81075c23afSdanielk1977 return (void *)&pVar[1];
82075c23afSdanielk1977 }
83075c23afSdanielk1977
84075c23afSdanielk1977 #endif
85