15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2008 September 1
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The code in this file contains sample implementations of the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3_wsd_init() and sqlite3_wsd_find() functions required if the
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** SQLITE_OMIT_WSD symbol is defined at build time.
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(SQLITE_OMIT_WSD) && defined(SQLITE_TEST)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PLS_HASHSIZE 43
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ProcessLocalStorage ProcessLocalStorage;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct ProcessLocalVar ProcessLocalVar;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ProcessLocalStorage {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessLocalVar *aData[PLS_HASHSIZE];
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nFree;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 *pFree;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ProcessLocalVar {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *pKey;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessLocalVar *pNext;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static ProcessLocalStorage *pGlobal = 0;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_wsd_init(int N, int J){
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !pGlobal ){
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nMalloc = N + sizeof(ProcessLocalStorage) + J*sizeof(ProcessLocalVar);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pGlobal = (ProcessLocalStorage *)malloc(nMalloc);
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( pGlobal ){
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      memset(pGlobal, 0, sizeof(ProcessLocalStorage));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pGlobal->nFree = nMalloc - sizeof(ProcessLocalStorage);
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pGlobal->pFree = (u8 *)&pGlobal[1];
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pGlobal ? SQLITE_OK : SQLITE_NOMEM;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void *sqlite3_wsd_find(void *K, int L){
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iHash = 0;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProcessLocalVar *pVar;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Calculate a hash of K */
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(void*); i++){
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    iHash = (iHash<<3) + ((unsigned char *)&K)[i];
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  iHash = iHash%PLS_HASHSIZE;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Search the hash table for K. */
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(pVar=pGlobal->aData[iHash]; pVar && pVar->pKey!=K; pVar=pVar->pNext);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* If no entry for K was found, create and populate a new one. */
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( !pVar ){
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nByte = ROUND8(sizeof(ProcessLocalVar) + L);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    assert( pGlobal->nFree>=nByte );
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pVar = (ProcessLocalVar *)pGlobal->pFree;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pVar->pKey = K;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pVar->pNext = pGlobal->aData[iHash];
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pGlobal->aData[iHash] = pVar;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pGlobal->nFree -= nByte;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pGlobal->pFree += nByte;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcpy(&pVar[1], K, L);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return (void *)&pVar[1];
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
85