123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <grass/raster3d.h>
- #include "raster3d_intern.h"
- #include "cachehash.h"
- /*---------------------------------------------------------------------------*/
- #define IS_ACTIVE_ELT(elt) (c->locks[elt] != 2)
- #define IS_NOT_ACTIVE_ELT(elt) (c->locks[elt] == 2)
- #define IS_LOCKED_ELT(elt) (c->locks[elt] == 1)
- #define IS_UNLOCKED_ELT(elt) (c->locks[elt] == 0)
- #define IS_NOT_IN_QUEUE_ELT(elt) (IS_LOCKED_ELT (elt))
- #define IS_IN_QUEUE_ELT(elt) (! IS_NOT_IN_QUEUE_ELT (elt))
- #define DEACTIVATE_ELT(elt) ((IS_LOCKED_ELT(elt) ? \
- (c->nofUnlocked)++ : (0)), \
- c->locks[elt] = 2)
- #define LOCK_ELT(elt) ((IS_LOCKED_ELT(elt) ? \
- (0) : (c->nofUnlocked)--), \
- (c->locks[elt] = 1))
- #define UNLOCK_ELT(elt) ((IS_LOCKED_ELT(elt) ? \
- (c->nofUnlocked)++ : (0)), \
- (c->locks[elt] = 0))
- #define ONE_UNLOCKED_ELT_ONLY (c->first == c->last)
- #define ARE_MIN_UNLOCKED (c->nofUnlocked <= c->minUnlocked)
- /*---------------------------------------------------------------------------*/
- void Rast3d_cache_reset(RASTER3D_cache * c)
- {
- int i;
- for (i = 0; i < c->nofElts; i++) {
- DEACTIVATE_ELT(i);
- c->next[i] = i + 1;
- c->prev[i] = i - 1;
- c->names[i] = -1;
- }
- c->prev[0] = c->next[c->nofElts - 1] = -1;
- c->first = 0;
- c->last = c->nofElts - 1;
- c->autoLock = 0;
- c->nofUnlocked = c->nofElts;
- c->minUnlocked = 1;
- Rast3d_cache_hash_reset(c->hash);
- }
- /*---------------------------------------------------------------------------*/
- static int cache_dummy_fun(int tileIndex, const void *tileBuf, void *map)
- {
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- void Rast3d_cache_dispose(RASTER3D_cache * c)
- {
- if (c == NULL)
- return;
- Rast3d_cache_hash_dispose(c->hash);
- if (c->elts != NULL)
- Rast3d_free(c->elts);
- if (c->names != NULL)
- Rast3d_free(c->names);
- if (c->locks != NULL)
- Rast3d_free(c->locks);
- if (c->next != NULL)
- Rast3d_free(c->next);
- if (c->prev != NULL)
- Rast3d_free(c->prev);
- Rast3d_free(c);
- }
- /*---------------------------------------------------------------------------*/
- void *Rast3d_cache_new(int nofElts, int sizeOfElts, int nofNames,
- int (*eltRemoveFun) (), void *eltRemoveFunData,
- int (*eltLoadFun) (), void *eltLoadFunData)
- {
- RASTER3D_cache *tmp;
- int i;
- tmp = Rast3d_malloc(sizeof(RASTER3D_cache));
- if (tmp == NULL) {
- Rast3d_error("Rast3d_cache_new: error in Rast3d_malloc");
- return (void *)NULL;
- }
- tmp->hash = NULL;
- tmp->nofElts = nofElts;
- tmp->eltSize = sizeOfElts;
- tmp->elts = Rast3d_malloc(tmp->eltSize * tmp->nofElts);
- tmp->names = Rast3d_malloc(sizeof(int) * tmp->nofElts);
- tmp->locks = Rast3d_malloc(tmp->nofElts);
- tmp->next = Rast3d_malloc(sizeof(int) * tmp->nofElts);
- tmp->prev = Rast3d_malloc(sizeof(int) * tmp->nofElts);
- if ((tmp->elts == NULL) || (tmp->names == NULL) || (tmp->locks == NULL) ||
- (tmp->next == NULL) || (tmp->prev == NULL)) {
- Rast3d_cache_dispose(tmp);
- Rast3d_error("Rast3d_cache_new: error in Rast3d_malloc");
- return (void *)NULL;
- }
- /* Init the cache lock */
- for(i = 0; i < tmp->nofElts; i++)
- tmp->locks[i] = 0;
-
- tmp->eltRemoveFun = eltRemoveFun;
- tmp->eltRemoveFunData = eltRemoveFunData;
- tmp->eltLoadFun = eltLoadFun;
- tmp->eltLoadFunData = eltLoadFunData;
- tmp->hash = Rast3d_cache_hash_new(nofNames);
- if (tmp->hash == NULL) {
- Rast3d_cache_dispose(tmp);
- Rast3d_error("Rast3d_cache_new: error in Rast3d_cache_hash_new");
- return (void *)NULL;
- }
- Rast3d_cache_reset(tmp);
- return tmp;
- }
- /*---------------------------------------------------------------------------*/
- void
- Rast3d_cache_set_remove_fun(RASTER3D_cache * c, int (*eltRemoveFun) (),
- void *eltRemoveFunData)
- {
- c->eltRemoveFun = eltRemoveFun;
- c->eltRemoveFunData = eltRemoveFunData;
- }
- /*---------------------------------------------------------------------------*/
- void
- Rast3d_cache_set_load_fun(RASTER3D_cache * c, int (*eltLoadFun) (),
- void *eltLoadFunData)
- {
- c->eltLoadFun = eltLoadFun;
- c->eltLoadFunData = eltLoadFunData;
- }
- /*---------------------------------------------------------------------------*/
- void *Rast3d_cache_new_read(int nofElts, int sizeOfElts, int nofNames,
- read_fn * eltLoadFun, void *eltLoadFunData)
- {
- return Rast3d_cache_new(nofElts, sizeOfElts, nofNames,
- cache_dummy_fun, NULL, eltLoadFun, eltLoadFunData);
- }
- /*---------------------------------------------------------------------------*/
- static void cache_queue_dequeue(RASTER3D_cache * c, int index)
- {
- if (IS_NOT_IN_QUEUE_ELT(index))
- Rast3d_fatal_error("cache_queue_dequeue: index not in queue");
- if (index == c->first)
- c->first = c->next[index];
- if (index == c->last)
- c->last = c->prev[index];
- if (c->next[index] != -1)
- c->prev[c->next[index]] = c->prev[index];
- if (c->prev[index] != -1)
- c->next[c->prev[index]] = c->next[index];
- c->next[index] = c->prev[index] = -1;
- }
- /*---------------------------------------------------------------------------*/
- static void cache_queue_enqueue(RASTER3D_cache * c, int left, int index)
- {
- if (IS_IN_QUEUE_ELT(index))
- Rast3d_fatal_error("cache_queue_enqueue: index already in queue");
- if (c->first == -1) {
- if (left != c->last)
- Rast3d_fatal_error("cache_queue_enqueue: position out of range");
- c->first = c->last = index;
- return;
- }
- if (left >= 0 && IS_NOT_IN_QUEUE_ELT(left))
- Rast3d_fatal_error("cache_queue_enqueue: position not in queue");
- if (left == -1) {
- c->next[index] = c->first;
- c->prev[c->first] = index;
- c->first = index;
- return;
- }
- c->prev[index] = left;
- if (c->next[left] == -1) {
- c->next[left] = index;
- c->last = index;
- return;
- }
- c->prev[c->next[left]] = index;
- c->next[index] = c->next[left];
- c->next[left] = index;
- }
- /*---------------------------------------------------------------------------*/
- static int cache_queue_get_top(RASTER3D_cache * c)
- {
- int top;
- top = c->first;
- cache_queue_dequeue(c, c->first);
- return top;
- }
- /*---------------------------------------------------------------------------*/
- static void cache_queue_append(RASTER3D_cache * c, int index)
- {
- cache_queue_enqueue(c, c->last, index);
- }
- /*---------------------------------------------------------------------------*/
- static void cache_queue_preppend(RASTER3D_cache * c, int index)
- {
- cache_queue_enqueue(c, -1, index);
- }
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* EXPORTED FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_lock(RASTER3D_cache * c, int name)
- {
- int index;
- index = Rast3d_cache_hash_name2index(c->hash, name);
- if (index == -1) {
- Rast3d_error("Rast3d_cache_lock: name not in cache");
- return 0;
- }
- if (IS_LOCKED_ELT(index))
- return 1;
- if (ONE_UNLOCKED_ELT_ONLY)
- return -1;
- if (ARE_MIN_UNLOCKED)
- return -1;
- cache_queue_dequeue(c, index);
- LOCK_ELT(index);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- void Rast3d_cache_lock_intern(RASTER3D_cache * c, int index)
- {
- if (IS_LOCKED_ELT(index))
- return;
- cache_queue_dequeue(c, index);
- LOCK_ELT(index);
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_unlock(RASTER3D_cache * c, int name)
- {
- int index;
- index = Rast3d_cache_hash_name2index(c->hash, name);
- if (index == -1) {
- Rast3d_error("Rast3d_cache_unlock: name not in cache");
- return 0;
- }
- if (IS_UNLOCKED_ELT(index))
- return 1;
- cache_queue_append(c, index);
- UNLOCK_ELT(index);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_unlock_all(RASTER3D_cache * c)
- {
- int index;
- for (index = 0; index < c->nofElts; index++)
- if (IS_LOCKED_ELT(index))
- if (!Rast3d_cache_unlock(c, c->names[index])) {
- Rast3d_error("Rast3d_cache_unlock_all: error in Rast3d_cache_unlock");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_lock_all(RASTER3D_cache * c)
- {
- int index;
- for (index = 0; index < c->nofElts; index++)
- if (IS_UNLOCKED_ELT(index))
- Rast3d_cache_lock_intern(c, index);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- void Rast3d_cache_autolock_on(RASTER3D_cache * c)
- {
- c->autoLock = 1;
- }
- /*---------------------------------------------------------------------------*/
- void Rast3d_cache_autolock_off(RASTER3D_cache * c)
- {
- c->autoLock = 0;
- }
- /*---------------------------------------------------------------------------*/
- void Rast3d_cache_set_min_unlock(RASTER3D_cache * c, int nofMinUnLocked)
- {
- c->minUnlocked = nofMinUnLocked;
- }
- /*---------------------------------------------------------------------------*/
- static int cache_remove_elt(RASTER3D_cache * c, int name, int doFlush)
- {
- int index;
- index = Rast3d_cache_hash_name2index(c->hash, name);
- if (index == -1) {
- Rast3d_error("Rast3d_cache_deactivate_elt : name not in cache");
- return 0;
- }
- if (IS_NOT_ACTIVE_ELT(index))
- return 1;
- if (IS_IN_QUEUE_ELT(index)) {
- cache_queue_dequeue(c, index);
- LOCK_ELT(index);
- }
- if (doFlush)
- if (!c->eltRemoveFun(name, c->elts + c->eltSize * index,
- c->eltRemoveFunData)) {
- Rast3d_error("cache_remove_elt: error in c->eltRemoveFun");
- return 0;
- }
- cache_queue_preppend(c, index);
- DEACTIVATE_ELT(index);
- Rast3d_cache_hash_remove_name(c->hash, name);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_remove_elt(RASTER3D_cache * c, int name)
- {
- if (!cache_remove_elt(c, name, 0)) {
- Rast3d_error("Rast3d_cache_remove_elt: error in cache_remove_elt");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_flush(RASTER3D_cache * c, int name)
- {
- if (!cache_remove_elt(c, name, 1)) {
- Rast3d_error("Rast3d_cache_flush: error in cache_remove_elt");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_remove_all(RASTER3D_cache * c)
- {
- int index;
- for (index = 0; index < c->nofElts; index++)
- if (IS_ACTIVE_ELT(index))
- if (!Rast3d_cache_remove_elt(c, c->names[index])) {
- Rast3d_error
- ("Rast3d_cache_remove_all: error in Rast3d_cache_remove_elt");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_flush_all(RASTER3D_cache * c)
- {
- int index;
- for (index = 0; index < c->nofElts; index++)
- if (IS_ACTIVE_ELT(index))
- if (!Rast3d_cache_flush(c, c->names[index])) {
- Rast3d_error("Rast3d_cache_flush_all: error in Rast3d_cache_flush");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- void *Rast3d_cache_elt_ptr(RASTER3D_cache * c, int name)
- {
- int index, oldName, doUnlock;
- index = Rast3d_cache_hash_name2index(c->hash, name);
- if (index != -1) {
- if (c->autoLock)
- if (IS_UNLOCKED_ELT(index) && (!ONE_UNLOCKED_ELT_ONLY) &&
- (!ARE_MIN_UNLOCKED))
- Rast3d_cache_lock_intern(c, index);
- return c->elts + c->eltSize * index;
- }
- index = c->first;
- if (IS_ACTIVE_ELT(index)) {
- oldName = c->names[index];
- Rast3d_cache_hash_remove_name(c->hash, oldName);
- if (!c->eltRemoveFun(oldName, c->elts + c->eltSize * index,
- c->eltRemoveFunData)) {
- Rast3d_error("Rast3d_cache_elt_ptr: error in c->eltRemoveFun");
- return NULL;
- }
- }
- Rast3d_cache_hash_load_name(c->hash, name, index);
- doUnlock = ((!c->autoLock) || ONE_UNLOCKED_ELT_ONLY || ARE_MIN_UNLOCKED);
- UNLOCK_ELT(index);
- c->names[index] = name;
- Rast3d_cache_lock_intern(c, index);
- if (doUnlock)
- if (!Rast3d_cache_unlock(c, name)) {
- Rast3d_error("Rast3d_cache_elt_ptr: error in Rast3d_cache_unlock");
- return NULL;
- }
- if (!c->eltLoadFun(name, c->elts + c->eltSize * index, c->eltLoadFunData)) {
- Rast3d_error("Rast3d_cache_elt_ptr: error in c->eltLoadFun");
- return NULL;
- }
- return c->elts + c->eltSize * index;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_load(RASTER3D_cache * c, int name)
- {
- if (Rast3d_cache_elt_ptr(c, name) == NULL) {
- Rast3d_error("Rast3d_cache_load: error in Rast3d_cache_elt_ptr");
- return 0;
- }
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_get_elt(RASTER3D_cache * c, int name, void *dst)
- {
- const void *elt;
- elt = Rast3d_cache_elt_ptr(c, name);
- if (elt == NULL) {
- Rast3d_error("Rast3d_cache_get_elt: error in Rast3d_cache_elt_ptr");
- return 0;
- }
- memcpy(dst, elt, c->eltSize);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- int Rast3d_cache_put_elt(RASTER3D_cache * c, int name, const void *src)
- {
- void *elt;
- elt = Rast3d_cache_elt_ptr(c, name);
- if (elt == NULL) {
- Rast3d_error("Rast3d_cache_put_elt: error in Rast3d_cache_elt_ptr");
- return 0;
- }
- memcpy(elt, src, c->eltSize);
- return 1;
- }
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- /* TEST FUNCTIONS */
- /*---------------------------------------------------------------------------*/
- /*---------------------------------------------------------------------------*/
- static void cache_test_print(RASTER3D_cache * c)
- {
- int i, al;
- int *a;
- al = c->autoLock;
- Rast3d_cache_autolock_off(c);
- printf("\n--------------------------------\n");
- for (i = 0; i < c->nofElts; i++) {
- printf("elt %d: ", i);
- if (IS_NOT_ACTIVE_ELT(i)) {
- printf("na\n");
- continue;
- }
- a = (int *)Rast3d_cache_elt_ptr(c, c->names[i]);
- /*Rast3d_cache_get_elt (c, c->names[i], a); */
- printf("name %d val %d %s\n", c->names[i], a[17],
- (IS_LOCKED_ELT(i) ? "locked" :
- IS_UNLOCKED_ELT(i) ? "unlocked" : ""));
- }
- printf("\n--------------------------------\n");
- if (al)
- Rast3d_cache_autolock_on(c);
- }
- /*---------------------------------------------------------------------------*/
- static int cache_test_flush_fun(int name, const void *eltPtr, void *data)
- {
- printf("flushing name %d value %d\n", name, ((const int *)eltPtr)[17]);
- return 0;
- }
- /*---------------------------------------------------------------------------*/
- typedef struct
- {
- int *value;
- int size;
- } cache_test_data_type;
- static int cache_test_load_fun(int name, void *eltPtr, void *data)
- {
- const void *src;
- printf("loading name %d value %d\n", name,
- ((cache_test_data_type *) data)->value[17]);
- src = ((cache_test_data_type *) data)->value;
- memcpy(eltPtr, src, ((cache_test_data_type *) data)->size);
- return 0;
- }
- /*---------------------------------------------------------------------------*/
- static cache_test_data_type ctd;
- static void cache_test_add(void *c, int name, int val)
- {
- static int firstTime = 1;
- if (firstTime) {
- ctd.value = Rast3d_malloc(((RASTER3D_cache *) c)->eltSize * sizeof(int));
- firstTime = 0;
- }
- ctd.value[17] = val;
- ctd.size = ((RASTER3D_cache *) c)->eltSize;
- Rast3d_cache_load(c, name);
- }
- /*---------------------------------------------------------------------------*/
- int MAIN()
- {
- void *c;
- c = Rast3d_cache_new(3, 76 * sizeof(int), 100000,
- cache_test_flush_fun, NULL, cache_test_load_fun, &ctd);
- Rast3d_cache_autolock_on(c);
- cache_test_print(c);
- cache_test_add(c, 1111, -11);
- cache_test_print(c);
- cache_test_add(c, 2222, -22);
- cache_test_print(c);
- cache_test_add(c, 3333, -33);
- cache_test_print(c);
- cache_test_add(c, 4444, -44);
- cache_test_print(c);
- Rast3d_cache_unlock_all(c);
- cache_test_print(c);
- Rast3d_cache_load(c, 2222);
- cache_test_print(c);
- cache_test_add(c, 5555, -55);
- cache_test_print(c);
- cache_test_add(c, 6666, -66);
- cache_test_print(c);
- cache_test_add(c, 7777, -77);
- cache_test_print(c);
- cache_test_add(c, 8888, -88);
- cache_test_print(c);
- cache_test_add(c, 9999, -99);
- cache_test_print(c);
- Rast3d_cache_flush(c, 9999);
- cache_test_print(c);
- Rast3d_cache_flush_all(c);
- cache_test_print(c);
- cache_test_add(c, 1111, -11);
- cache_test_print(c);
- cache_test_add(c, 2222, -22);
- cache_test_print(c);
- cache_test_add(c, 3333, -33);
- cache_test_print(c);
- Rast3d_cache_reset(c);
- cache_test_print(c);
- cache_test_add(c, 1111, -11);
- cache_test_print(c);
- cache_test_add(c, 2222, -22);
- cache_test_print(c);
- cache_test_add(c, 3333, -33);
- cache_test_print(c);
- return 0;
- }
|