1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#include "gist.h"
/*
* GIST's query cache
*/
/* Holds the parent type of PGS_DATA_TYPES for cached key. */
static unsigned keytype = 0;
/* the cached key */
static int32 kcache[6];
/* pointer to cached query */
static void *cquery = NULL;
/* Holds the count of points, if cached query is a path or polygon. */
static int32 npts = 0;
/* If query type and value are equal, this value is true */
static bool res = false;
/*
* Depending on type of PGS_DATA_TYPES, compare current query and cached query.
* If query cache and current query are equal, set ref to true.
*/
#define GQ_MEMCMP(type) \
do \
{ \
if (keytype == PGS_TYPE_##type) \
{ \
if (memcmp((void *) cquery, (void *) query, sizeof(type)) == 0) res = true; \
} \
} while(0);
bool
gq_cache_get_value(unsigned pgstype, const void *query, int32 **key)
{
if (keytype == 0)
{
return false;
}
else
{
res = false;
switch (pgstype)
{
case PGS_TYPE_SPoint:
GQ_MEMCMP(SPoint);
break;
case PGS_TYPE_SCIRCLE:
GQ_MEMCMP(SCIRCLE);
break;
case PGS_TYPE_SELLIPSE:
GQ_MEMCMP(SELLIPSE);
break;
case PGS_TYPE_SLine:
GQ_MEMCMP(SLine);
break;
case PGS_TYPE_SBOX:
GQ_MEMCMP(SBOX);
break;
case PGS_TYPE_SPATH:
if (keytype == pgstype && ((SPATH *) query)->npts == npts)
{
if (memcmp((void *) cquery,
(void *) &((SPATH *) query)->p,
((SPATH *) query)->npts * sizeof(SPoint)) == 0)
res = true;
}
break;
case PGS_TYPE_SPOLY:
if (keytype == pgstype && ((SPOLY *) query)->npts == npts)
{
if (memcmp((void *) cquery,
(void *) &((SPOLY *) query)->p,
((SPOLY *) query)->npts * sizeof(SPoint)) == 0)
res = true;
}
break;
default:
res = false;
break;
}
if (res)
{
*key = &kcache[0];
}
return res;
}
return false;
}
/*
* Depending on type of PGS_DATA_TYPES, copy current query to cache.
*/
#define GQ_MEMCPY(type) \
do \
{ \
cquery = (void *) malloc(sizeof(type)); \
memcpy((void *) cquery, (void *) query, sizeof(type)); \
} while(0);
void
gq_cache_set_value(unsigned pgstype, const void *query, const int32 *key)
{
if (cquery)
{
free(cquery);
cquery = NULL;
}
keytype = pgstype;
switch (pgstype)
{
case PGS_TYPE_SPoint:
GQ_MEMCPY(SPoint);
break;
case PGS_TYPE_SCIRCLE:
GQ_MEMCPY(SCIRCLE);
break;
case PGS_TYPE_SELLIPSE:
GQ_MEMCPY(SELLIPSE);
break;
case PGS_TYPE_SLine:
GQ_MEMCPY(SLine);
break;
case PGS_TYPE_SBOX:
GQ_MEMCPY(SBOX);
break;
case PGS_TYPE_SPATH:
cquery = (void *) malloc(((SPATH *) query)->npts * sizeof(SPoint));
npts = ((SPATH *) query)->npts;
memcpy((void *) cquery,
(void *) &((SPATH *) query)->p,
((SPATH *) query)->npts * sizeof(SPoint));
break;
case PGS_TYPE_SPOLY:
cquery = (void *) malloc(((SPOLY *) query)->npts * sizeof(SPoint));
npts = ((SPOLY *) query)->npts;
memcpy((void *) cquery,
(void *) &((SPOLY *) query)->p,
((SPOLY *) query)->npts * sizeof(SPoint));
break;
default:
keytype = 0;
}
if (keytype > 0)
{
memcpy((void *) &kcache[0], (void *) key, KEYSIZE);
}
}
|