Browse Source

raster3d: files renamed (no need for `g3d` prefix)

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@47532 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa 13 years ago
parent
commit
09dcd86c52

lib/raster3d/g3dalloc.c → lib/raster3d/alloc.c


+ 182 - 548
lib/raster3d/cache.c

@@ -1,422 +1,209 @@
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
+#include <fcntl.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <grass/G3d.h>
 #include "G3d_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 G3d_cache_reset(G3D_cache * c)
+static int cacheRead_readFun(int tileIndex, void *tileBuf, void *closure)
 {
-    int i;
+    G3D_Map *map = closure;
 
-    for (i = 0; i < c->nofElts; i++) {
-	DEACTIVATE_ELT(i);
-	c->next[i] = i + 1;
-	c->prev[i] = i - 1;
-	c->names[i] = -1;
+    if (!G3d_readTile(map, tileIndex, tileBuf, map->typeIntern)) {
+	G3d_error("cacheRead_readFun: error in G3d_readTile");
+	return 0;
     }
-
-    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;
-
-    G3d_cache_hash_reset(c->hash);
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int cache_dummy_fun(int tileIndex, const void *tileBuf, void *map)
-{
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-void G3d_cache_dispose(G3D_cache * c)
-{
-    if (c == NULL)
-	return;
-
-    G3d_cache_hash_dispose(c->hash);
-
-    if (c->elts != NULL)
-	G3d_free(c->elts);
-    if (c->names != NULL)
-	G3d_free(c->names);
-    if (c->locks != NULL)
-	G3d_free(c->locks);
-    if (c->next != NULL)
-	G3d_free(c->next);
-    if (c->prev != NULL)
-	G3d_free(c->prev);
-
-    G3d_free(c);
-}
-
-/*---------------------------------------------------------------------------*/
-
-void *G3d_cache_new(int nofElts, int sizeOfElts, int nofNames,
-		    int (*eltRemoveFun) (), void *eltRemoveFunData,
-		    int (*eltLoadFun) (), void *eltLoadFunData)
+static int initCacheRead(G3D_Map * map, int nCached)
 {
-    G3D_cache *tmp;
-
-    tmp = G3d_malloc(sizeof(G3D_cache));
-    if (tmp == NULL) {
-	G3d_error("G3d_cache_new: error in G3d_malloc");
-	return (void *)NULL;
-    }
-
-    tmp->hash = NULL;
-
-    tmp->nofElts = nofElts;
-    tmp->eltSize = sizeOfElts;
-    tmp->elts = G3d_malloc(tmp->eltSize * tmp->nofElts);
-    tmp->names = G3d_malloc(sizeof(int) * tmp->nofElts);
-    tmp->locks = G3d_malloc(tmp->nofElts);
-    tmp->next = G3d_malloc(sizeof(int) * tmp->nofElts);
-    tmp->prev = G3d_malloc(sizeof(int) * tmp->nofElts);
-
-    if ((tmp->elts == NULL) || (tmp->names == NULL) || (tmp->locks == NULL) ||
-	(tmp->next == NULL) || (tmp->prev == NULL)) {
-
-	G3d_cache_dispose(tmp);
-	G3d_error("G3d_cache_new: error in G3d_malloc");
-	return (void *)NULL;
-    }
-
-    tmp->eltRemoveFun = eltRemoveFun;
-    tmp->eltRemoveFunData = eltRemoveFunData;
-    tmp->eltLoadFun = eltLoadFun;
-    tmp->eltLoadFunData = eltLoadFunData;
-
-    tmp->hash = G3d_cache_hash_new(nofNames);
-    if (tmp->hash == NULL) {
-	G3d_cache_dispose(tmp);
-	G3d_error("G3d_cache_new: error in G3d_cache_hash_new");
-	return (void *)NULL;
+    map->cache = G3d_cache_new_read(nCached,
+				    map->tileSize * map->numLengthIntern,
+				    map->nTiles, cacheRead_readFun, map);
+    if (map->cache == NULL) {
+	G3d_error("initCacheRead: error in G3d_cache_new_read");
+	return 0;
     }
 
-    G3d_cache_reset(tmp);
-
-    return tmp;
+    return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-void
-G3d_cache_set_removeFun(G3D_cache * c, int (*eltRemoveFun) (),
-			void *eltRemoveFunData)
-{
-    c->eltRemoveFun = eltRemoveFun;
-    c->eltRemoveFunData = eltRemoveFunData;
-}
+/*
+   the map->index array is (ab)used to store the positions of the tiles in the 
+   file-cash. we can do this since we maintain the invariant for every tile 
+   that it is either in no file (index == -1) or in either the output-file
+   (index >= 0) or the cash-file (index <= -2). to convert the file-position in 
+   the cash-file into an index we use the following function:
 
-/*---------------------------------------------------------------------------*/
+   index = - (fileposition + 2)
 
-void
-G3d_cache_set_loadFun(G3D_cache * c, int (*eltLoadFun) (),
-		      void *eltLoadFunData)
-{
-    c->eltLoadFun = eltLoadFun;
-    c->eltLoadFunData = eltLoadFunData;
-}
+   symmetrically, we use
 
-/*---------------------------------------------------------------------------*/
+   fileposition = - (index + 2)
 
-void *G3d_cache_new_read(int nofElts, int sizeOfElts, int nofNames,
-			 read_fn * eltLoadFun, void *eltLoadFunData)
-{
-    return G3d_cache_new(nofElts, sizeOfElts, nofNames,
-			 cache_dummy_fun, NULL, eltLoadFun, eltLoadFunData);
-}
+   to convert from index to the fileposition.
+ */
 
 /*---------------------------------------------------------------------------*/
 
-static void cache_queue_dequeue(G3D_cache * c, int index)
+static int cacheWrite_readFun(int tileIndex, void *tileBuf, void *closure)
 {
-    if (IS_NOT_IN_QUEUE_ELT(index))
-	G3d_fatalError("cache_queue_dequeue: index not in queue");
+    G3D_Map *map = closure;
+    int index, nBytes;
+    long pos, offs, offsLast;
 
-    if (index == c->first)
-	c->first = c->next[index];
-    if (index == c->last)
-	c->last = c->prev[index];
+    pos = map->index[tileIndex];
 
-    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];
+    /* tile has already been flushed onto output file or does not exist yet */
+    if (pos >= -1) {		/* note, G3d_readTile takes care of the case pos == -1 */
+	G3d_readTile(map, tileIndex, tileBuf, map->typeIntern);
+	return 1;
+    }
 
-    c->next[index] = c->prev[index] = -1;
-}
+    /* tile is in cache file */
 
-/*---------------------------------------------------------------------------*/
+    pos = -pos - 2;		/* pos is shifted by 2 to avoid 0 and -1 */
 
-static void cache_queue_enqueue(G3D_cache * c, int left, int index)
-{
-    if (IS_IN_QUEUE_ELT(index))
-	G3d_fatalError("cache_queue_enqueue: index already in queue");
+    nBytes = map->tileSize * map->numLengthIntern;
+    offs = pos * (nBytes + sizeof(int));
 
-    if (c->first == -1) {
-	if (left != c->last)
-	    G3d_fatalError("cache_queue_enqueue: position out of range");
+    /* seek tile and read it into buffer */
 
-	c->first = c->last = index;
-	return;
+    if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
+	G3d_error("cacheWrite_readFun: can't position file");
+	return 0;
+    }
+    if (read(map->cacheFD, tileBuf, nBytes) != nBytes) {
+	G3d_error("cacheWrite_readFun: can't read file");
+	return 0;
     }
 
-    if (IS_NOT_IN_QUEUE_ELT(left))
-	G3d_fatalError("cache_queue_enqueue: position not in queue");
+    /* remove it from index */
 
+    map->index[tileIndex] = -1;
 
-    if (left == -1) {
-	c->next[index] = c->first;
-	c->prev[c->first] = index;
-	c->first = index;
+    /* if it is the last tile in the file we are done */
+    /* map->cachePosLast tells us the position of the last tile in the file */
 
-	return;
+    if (map->cachePosLast == pos) {
+	map->cachePosLast--;
+	return 1;
     }
 
-    c->prev[index] = left;
+    /* otherwise we move the last tile in the file into the position of */
+    /* the tile we just read and update the hash information */
 
-    if (c->next[left] == -1) {
-	c->next[left] = index;
-	c->last = index;
+    offsLast = map->cachePosLast * (nBytes + sizeof(int));
 
-	return;
+    if (lseek(map->cacheFD, offsLast, SEEK_SET) == -1) {
+	G3d_error("cacheWrite_readFun: can't position file");
+	return 0;
     }
-
-    c->prev[c->next[left]] = index;
-    c->next[index] = c->next[left];
-    c->next[left] = index;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int cache_queue_get_top(G3D_cache * c)
-{
-    int top;
-
-    top = c->first;
-
-    cache_queue_dequeue(c, c->first);
-
-    return top;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static void cache_queue_append(G3D_cache * c, int index)
-{
-    cache_queue_enqueue(c, c->last, index);
-}
-
-/*---------------------------------------------------------------------------*/
-
-static void cache_queue_preppend(G3D_cache * c, int index)
-{
-    cache_queue_enqueue(c, -1, index);
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-
-			/* EXPORTED FUNCTIONS */
-
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
-
-int G3d_cache_lock(G3D_cache * c, int name)
-{
-    int index;
-
-    index = G3d_cache_hash_name2index(c->hash, name);
-    if (index == -1) {
-	G3d_error("G3d_cache_lock: name not in cache");
+    if (read(map->cacheFD, xdr, nBytes + sizeof(int)) != nBytes + sizeof(int)) {
+	G3d_error("cacheWrite_readFun: can't read file");
 	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 G3d_cache_lock_intern(G3D_cache * c, int index)
-{
-    if (IS_LOCKED_ELT(index))
-	return;
-
-    cache_queue_dequeue(c, index);
-    LOCK_ELT(index);
-}
-
-/*---------------------------------------------------------------------------*/
-
-int G3d_cache_unlock(G3D_cache * c, int name)
-{
-    int index;
-
-    index = G3d_cache_hash_name2index(c->hash, name);
-    if (index == -1) {
-	G3d_error("G3d_cache_unlock: name not in cache");
+    if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
+	G3d_error("cacheWrite_readFun: can't position file");
+	return 0;
+    }
+    if (write(map->cacheFD, xdr, nBytes + sizeof(int)) !=
+	nBytes + sizeof(int)) {
+	G3d_error("cacheWrite_readFun: can't write file");
 	return 0;
     }
 
-    if (IS_UNLOCKED_ELT(index))
-	return 1;
+    index = *((int *)((unsigned char *)xdr + nBytes));
+    map->index[index] = -pos - 2;
 
-    cache_queue_append(c, index);
-    UNLOCK_ELT(index);
+    map->cachePosLast--;
 
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-int G3d_cache_unlock_all(G3D_cache * c)
+static int
+cacheWrite_writeFun(int tileIndex, const void *tileBuf, void *closure)
 {
-    int index;
+    G3D_Map *map = closure;
+    int nBytes;
+    long offs;
 
-    for (index = 0; index < c->nofElts; index++)
-	if (IS_LOCKED_ELT(index))
-	    if (!G3d_cache_unlock(c, c->names[index])) {
-		G3d_error("G3d_cache_unlock_all: error in G3d_cache_unlock");
-		return 0;
-	    }
+    if (map->index[tileIndex] != -1)
+	return 1;
 
-    return 1;
-}
+    map->cachePosLast++;
+    nBytes = map->tileSize * map->numLengthIntern;
+    offs = map->cachePosLast * (nBytes + sizeof(int));
 
-/*---------------------------------------------------------------------------*/
-
-int G3d_cache_lock_all(G3D_cache * c)
-{
-    int index;
+    if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
+	G3d_error("cacheWrite_writeFun: can't position file");
+	return 0;
+    }
+    if (write(map->cacheFD, tileBuf, nBytes) != nBytes) {
+	G3d_error("cacheWrite_writeFun: can't write file");
+	return 0;
+    }
+    if (write(map->cacheFD, &tileIndex, sizeof(int)) != sizeof(int)) {
+	G3d_error("cacheWrite_writeFun: can't write file");
+	return 0;
+    }
 
-    for (index = 0; index < c->nofElts; index++)
-	if (IS_UNLOCKED_ELT(index))
-	    G3d_cache_lock_intern(c, index);
+    map->index[tileIndex] = -map->cachePosLast - 2;
 
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-void G3d_cache_autolock_on(G3D_cache * c)
+static int disposeCacheWrite(G3D_Map * map)
 {
-    c->autoLock = 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-void G3d_cache_autolock_off(G3D_cache * c)
-{
-    c->autoLock = 0;
-}
-
-/*---------------------------------------------------------------------------*/
-
-void G3d_cache_set_minUnlock(G3D_cache * c, int nofMinUnLocked)
-{
-    c->minUnlocked = nofMinUnLocked;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int cache_remove_elt(G3D_cache * c, int name, int doFlush)
-{
-    int index;
-
-    index = G3d_cache_hash_name2index(c->hash, name);
-    if (index == -1) {
-	G3d_error("G3d_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)) {
-	    G3d_error("cache_remove_elt: error in c->eltRemoveFun");
+    if (map->cacheFD >= 0) {
+	if (close(map->cacheFD) != 0) {
+	    G3d_error("disposeCacheWrite: could not close file");
 	    return 0;
 	}
+	remove(map->cacheFileName);
+	G3d_free(map->cacheFileName);
+    }
 
-    cache_queue_preppend(c, index);
-    DEACTIVATE_ELT(index);
-
-    G3d_cache_hash_remove_name(c->hash, name);
+    G3d_cache_dispose(map->cache);
 
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-int G3d_cache_remove_elt(G3D_cache * c, int name)
+static int initCacheWrite(G3D_Map * map, int nCached)
 {
-    if (!cache_remove_elt(c, name, 0)) {
-	G3d_error("G3d_cache_remove_elt: error in cache_remove_elt");
+    map->cacheFileName = G_tempfile();
+    map->cacheFD = open(map->cacheFileName, O_RDWR | O_CREAT | O_TRUNC, 0666);
+
+    if (map->cacheFD < 0) {
+	G3d_error("initCacheWrite: could not open file");
 	return 0;
     }
 
-    return 1;
-}
+    map->cachePosLast = -1;
 
-/*---------------------------------------------------------------------------*/
+    map->cache = G3d_cache_new(nCached,
+			       map->tileSize * map->numLengthIntern,
+			       map->nTiles,
+			       cacheWrite_writeFun, map,
+			       cacheWrite_readFun, map);
 
-int G3d_cache_flush(G3D_cache * c, int name)
-{
-    if (!cache_remove_elt(c, name, 1)) {
-	G3d_error("G3d_cache_flush: error in cache_remove_elt");
+    if (map->cache == NULL) {
+	disposeCacheWrite(map);
+	G3d_error("initCacheWrite: error in G3d_cache_new");
 	return 0;
     }
 
@@ -425,272 +212,119 @@ int G3d_cache_flush(G3D_cache * c, int name)
 
 /*---------------------------------------------------------------------------*/
 
-int G3d_cache_remove_all(G3D_cache * c)
+int G3d_initCache(G3D_Map * map, int nCached)
 {
-    int index;
+    if (map->operation == G3D_READ_DATA) {
+	if (!initCacheRead(map, nCached)) {
+	    G3d_error("G3d_initCache: error in initCacheRead");
+	    return 0;
+	}
+	return 1;
+    }
 
-    for (index = 0; index < c->nofElts; index++)
-	if (IS_ACTIVE_ELT(index))
-	    if (!G3d_cache_remove_elt(c, c->names[index])) {
-		G3d_error
-		    ("G3d_cache_remove_all: error in G3d_cache_remove_elt");
-		return 0;
-	    }
+    if (!initCacheWrite(map, nCached)) {
+	G3d_error("G3d_initCache: error in initCacheWrite");
+	return 0;
+    }
 
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-int G3d_cache_flush_all(G3D_cache * c)
+static int disposeCacheRead(G3D_Map * map)
 {
-    int index;
-
-    for (index = 0; index < c->nofElts; index++)
-	if (IS_ACTIVE_ELT(index))
-	    if (!G3d_cache_flush(c, c->names[index])) {
-		G3d_error("G3d_cache_flush_all: error in G3d_cache_flush");
-		return 0;
-	    }
-
+    G3d_cache_dispose(map->cache);
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-void *G3d_cache_elt_ptr(G3D_cache * c, int name)
+int G3d_disposeCache(G3D_Map * map)
 {
-    int index, oldName, doUnlock;
-
-    index = G3d_cache_hash_name2index(c->hash, name);
-
-    if (index != -1) {
-	if (c->autoLock)
-	    if (IS_UNLOCKED_ELT(index) && (!ONE_UNLOCKED_ELT_ONLY) &&
-		(!ARE_MIN_UNLOCKED))
-		G3d_cache_lock_intern(c, index);
-
-	return c->elts + c->eltSize * index;
-    }
-
-    index = c->first;
-    if (IS_ACTIVE_ELT(index)) {
-	oldName = c->names[index];
-	G3d_cache_hash_remove_name(c->hash, oldName);
-	if (!c->eltRemoveFun(oldName, c->elts + c->eltSize * index,
-			     c->eltRemoveFunData)) {
-	    G3d_error("G3d_cache_elt_ptr: error in c->eltRemoveFun");
-	    return NULL;
-	}
-    }
-
-    G3d_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;
-    G3d_cache_lock_intern(c, index);
-
-    if (doUnlock)
-	if (!G3d_cache_unlock(c, name)) {
-	    G3d_error("G3d_cache_elt_ptr: error in G3d_cache_unlock");
-	    return NULL;
+    if (map->operation == G3D_READ_DATA) {
+	if (!disposeCacheRead(map)) {
+	    G3d_error("G3d_disposeCache: error in disposeCacheRead");
+	    return 0;
 	}
-
-    if (!c->eltLoadFun(name, c->elts + c->eltSize * index, c->eltLoadFunData)) {
-	G3d_error("G3d_cache_elt_ptr: error in c->eltLoadFun");
-	return NULL;
+	return 1;
     }
 
-    return c->elts + c->eltSize * index;
-}
-
-/*---------------------------------------------------------------------------*/
-
-int G3d_cache_load(G3D_cache * c, int name)
-{
-    if (G3d_cache_elt_ptr(c, name) == NULL) {
-	G3d_error("G3d_cache_load: error in G3d_cache_elt_ptr");
+    if (!disposeCacheWrite(map)) {
+	G3d_error("G3d_disposeCache: error in disposeCacheWrite");
 	return 0;
     }
 
     return 1;
 }
 
+
 /*---------------------------------------------------------------------------*/
 
-int G3d_cache_get_elt(G3D_cache * c, int name, void *dst)
+static int cacheFlushFun(int tileIndex, const void *tileBuf, void *closure)
 {
-    const void *elt;
+    G3D_Map *map = closure;
 
-    elt = G3d_cache_elt_ptr(c, name);
-    if (elt == NULL) {
-	G3d_error("G3d_cache_get_elt: error in G3d_cache_elt_ptr");
+    if (!G3d_writeTile(map, tileIndex, tileBuf, map->typeIntern)) {
+	G3d_error("cacheFlushFun: error in G3d_writeTile");
 	return 0;
     }
 
-    memcpy(dst, elt, c->eltSize);
-
     return 1;
 }
 
 /*---------------------------------------------------------------------------*/
 
-int G3d_cache_put_elt(G3D_cache * c, int name, const void *src)
+int G3d_flushAllTiles(G3D_Map * map)
 {
-    void *elt;
+    int tileIndex, nBytes;
+    long offs;
 
-    elt = G3d_cache_elt_ptr(c, name);
-    if (elt == NULL) {
-	G3d_error("G3d_cache_put_elt: error in G3d_cache_elt_ptr");
-	return 0;
+    if (map->operation == G3D_READ_DATA) {
+	if (!G3d_cache_remove_all(map->cache)) {
+	    G3d_error("G3d_flushAllTiles: error in G3d_cache_remove_all");
+	    return 0;
+	}
+	return 1;
     }
 
-    memcpy(elt, src, c->eltSize);
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*---------------------------------------------------------------------------*/
+    /* make cache write into output file instead of cache file */
+    G3d_cache_set_removeFun(map->cache, cacheFlushFun, map);
 
-			/* TEST FUNCTIONS */
+    /* first flush all the tiles which are in the file cache */
 
-/*---------------------------------------------------------------------------*/
+    nBytes = map->tileSize * map->numLengthIntern;
 
-/*---------------------------------------------------------------------------*/
+    while (map->cachePosLast >= 0) {
+	offs = map->cachePosLast * (nBytes + sizeof(int)) + nBytes;
 
-static void cache_test_print(G3D_cache * c)
-{
-    int i, al;
-    int *a;
-
-    al = c->autoLock;
-    G3d_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;
+	if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
+	    G3d_error("G3d_flushAllTiles: can't position file");
+	    return 0;
+	}
+	if (read(map->cacheFD, &tileIndex, sizeof(int)) != sizeof(int)) {
+	    G3d_error("G3d_flushAllTiles: can't read file");
+	    return 0;
 	}
 
-	a = (int *)G3d_cache_elt_ptr(c, c->names[i]);
-	/*G3d_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" : ""));
+	if (!G3d_cache_load(map->cache, tileIndex)) {
+	    G3d_error("G3d_flushAllTiles: error in G3d_cache_load");
+	    return 0;
+	}
+	if (!G3d_cache_flush(map->cache, tileIndex)) {
+	    G3d_error("G3d_flushAllTiles: error in G3d_cache_flush");
+	    return 0;
+	}
     }
-    printf("\n--------------------------------\n");
-
-    if (al)
-	G3d_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 = G3d_malloc(((G3D_cache *) c)->eltSize * sizeof(int));
-	firstTime = 0;
+    /* then flush all the tiles which remain in the non-file cache */
+    if (!G3d_cache_flush_all(map->cache)) {
+	G3d_error("G3d_flushAllTiles: error in G3d_cache_flush_all");
+	return 0;
     }
 
-    ctd.value[17] = val;
-    ctd.size = ((G3D_cache *) c)->eltSize;
+    /* now the cache should write into the cache file again */
+    G3d_cache_set_removeFun(map->cache, cacheWrite_writeFun, map);
 
-    G3d_cache_load(c, name);
-}
-
-/*---------------------------------------------------------------------------*/
-
-int MAIN()
-{
-    void *c;
-
-    c = G3d_cache_new(3, 76 * sizeof(int), 100000,
-		      cache_test_flush_fun, NULL, cache_test_load_fun, &ctd);
-
-    G3d_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);
-    G3d_cache_unlock_all(c);
-    cache_test_print(c);
-    G3d_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);
-    G3d_cache_flush(c, 9999);
-    cache_test_print(c);
-    G3d_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);
-    G3d_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;
+    return 1;
 }

+ 696 - 0
lib/raster3d/cache1.c

@@ -0,0 +1,696 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <grass/G3d.h>
+#include "G3d_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 G3d_cache_reset(G3D_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;
+
+    G3d_cache_hash_reset(c->hash);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int cache_dummy_fun(int tileIndex, const void *tileBuf, void *map)
+{
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void G3d_cache_dispose(G3D_cache * c)
+{
+    if (c == NULL)
+	return;
+
+    G3d_cache_hash_dispose(c->hash);
+
+    if (c->elts != NULL)
+	G3d_free(c->elts);
+    if (c->names != NULL)
+	G3d_free(c->names);
+    if (c->locks != NULL)
+	G3d_free(c->locks);
+    if (c->next != NULL)
+	G3d_free(c->next);
+    if (c->prev != NULL)
+	G3d_free(c->prev);
+
+    G3d_free(c);
+}
+
+/*---------------------------------------------------------------------------*/
+
+void *G3d_cache_new(int nofElts, int sizeOfElts, int nofNames,
+		    int (*eltRemoveFun) (), void *eltRemoveFunData,
+		    int (*eltLoadFun) (), void *eltLoadFunData)
+{
+    G3D_cache *tmp;
+
+    tmp = G3d_malloc(sizeof(G3D_cache));
+    if (tmp == NULL) {
+	G3d_error("G3d_cache_new: error in G3d_malloc");
+	return (void *)NULL;
+    }
+
+    tmp->hash = NULL;
+
+    tmp->nofElts = nofElts;
+    tmp->eltSize = sizeOfElts;
+    tmp->elts = G3d_malloc(tmp->eltSize * tmp->nofElts);
+    tmp->names = G3d_malloc(sizeof(int) * tmp->nofElts);
+    tmp->locks = G3d_malloc(tmp->nofElts);
+    tmp->next = G3d_malloc(sizeof(int) * tmp->nofElts);
+    tmp->prev = G3d_malloc(sizeof(int) * tmp->nofElts);
+
+    if ((tmp->elts == NULL) || (tmp->names == NULL) || (tmp->locks == NULL) ||
+	(tmp->next == NULL) || (tmp->prev == NULL)) {
+
+	G3d_cache_dispose(tmp);
+	G3d_error("G3d_cache_new: error in G3d_malloc");
+	return (void *)NULL;
+    }
+
+    tmp->eltRemoveFun = eltRemoveFun;
+    tmp->eltRemoveFunData = eltRemoveFunData;
+    tmp->eltLoadFun = eltLoadFun;
+    tmp->eltLoadFunData = eltLoadFunData;
+
+    tmp->hash = G3d_cache_hash_new(nofNames);
+    if (tmp->hash == NULL) {
+	G3d_cache_dispose(tmp);
+	G3d_error("G3d_cache_new: error in G3d_cache_hash_new");
+	return (void *)NULL;
+    }
+
+    G3d_cache_reset(tmp);
+
+    return tmp;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+G3d_cache_set_removeFun(G3D_cache * c, int (*eltRemoveFun) (),
+			void *eltRemoveFunData)
+{
+    c->eltRemoveFun = eltRemoveFun;
+    c->eltRemoveFunData = eltRemoveFunData;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void
+G3d_cache_set_loadFun(G3D_cache * c, int (*eltLoadFun) (),
+		      void *eltLoadFunData)
+{
+    c->eltLoadFun = eltLoadFun;
+    c->eltLoadFunData = eltLoadFunData;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void *G3d_cache_new_read(int nofElts, int sizeOfElts, int nofNames,
+			 read_fn * eltLoadFun, void *eltLoadFunData)
+{
+    return G3d_cache_new(nofElts, sizeOfElts, nofNames,
+			 cache_dummy_fun, NULL, eltLoadFun, eltLoadFunData);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void cache_queue_dequeue(G3D_cache * c, int index)
+{
+    if (IS_NOT_IN_QUEUE_ELT(index))
+	G3d_fatalError("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(G3D_cache * c, int left, int index)
+{
+    if (IS_IN_QUEUE_ELT(index))
+	G3d_fatalError("cache_queue_enqueue: index already in queue");
+
+    if (c->first == -1) {
+	if (left != c->last)
+	    G3d_fatalError("cache_queue_enqueue: position out of range");
+
+	c->first = c->last = index;
+	return;
+    }
+
+    if (IS_NOT_IN_QUEUE_ELT(left))
+	G3d_fatalError("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(G3D_cache * c)
+{
+    int top;
+
+    top = c->first;
+
+    cache_queue_dequeue(c, c->first);
+
+    return top;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void cache_queue_append(G3D_cache * c, int index)
+{
+    cache_queue_enqueue(c, c->last, index);
+}
+
+/*---------------------------------------------------------------------------*/
+
+static void cache_queue_preppend(G3D_cache * c, int index)
+{
+    cache_queue_enqueue(c, -1, index);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+
+			/* EXPORTED FUNCTIONS */
+
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_lock(G3D_cache * c, int name)
+{
+    int index;
+
+    index = G3d_cache_hash_name2index(c->hash, name);
+    if (index == -1) {
+	G3d_error("G3d_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 G3d_cache_lock_intern(G3D_cache * c, int index)
+{
+    if (IS_LOCKED_ELT(index))
+	return;
+
+    cache_queue_dequeue(c, index);
+    LOCK_ELT(index);
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_unlock(G3D_cache * c, int name)
+{
+    int index;
+
+    index = G3d_cache_hash_name2index(c->hash, name);
+    if (index == -1) {
+	G3d_error("G3d_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 G3d_cache_unlock_all(G3D_cache * c)
+{
+    int index;
+
+    for (index = 0; index < c->nofElts; index++)
+	if (IS_LOCKED_ELT(index))
+	    if (!G3d_cache_unlock(c, c->names[index])) {
+		G3d_error("G3d_cache_unlock_all: error in G3d_cache_unlock");
+		return 0;
+	    }
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_lock_all(G3D_cache * c)
+{
+    int index;
+
+    for (index = 0; index < c->nofElts; index++)
+	if (IS_UNLOCKED_ELT(index))
+	    G3d_cache_lock_intern(c, index);
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void G3d_cache_autolock_on(G3D_cache * c)
+{
+    c->autoLock = 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void G3d_cache_autolock_off(G3D_cache * c)
+{
+    c->autoLock = 0;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void G3d_cache_set_minUnlock(G3D_cache * c, int nofMinUnLocked)
+{
+    c->minUnlocked = nofMinUnLocked;
+}
+
+/*---------------------------------------------------------------------------*/
+
+static int cache_remove_elt(G3D_cache * c, int name, int doFlush)
+{
+    int index;
+
+    index = G3d_cache_hash_name2index(c->hash, name);
+    if (index == -1) {
+	G3d_error("G3d_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)) {
+	    G3d_error("cache_remove_elt: error in c->eltRemoveFun");
+	    return 0;
+	}
+
+    cache_queue_preppend(c, index);
+    DEACTIVATE_ELT(index);
+
+    G3d_cache_hash_remove_name(c->hash, name);
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_remove_elt(G3D_cache * c, int name)
+{
+    if (!cache_remove_elt(c, name, 0)) {
+	G3d_error("G3d_cache_remove_elt: error in cache_remove_elt");
+	return 0;
+    }
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_flush(G3D_cache * c, int name)
+{
+    if (!cache_remove_elt(c, name, 1)) {
+	G3d_error("G3d_cache_flush: error in cache_remove_elt");
+	return 0;
+    }
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_remove_all(G3D_cache * c)
+{
+    int index;
+
+    for (index = 0; index < c->nofElts; index++)
+	if (IS_ACTIVE_ELT(index))
+	    if (!G3d_cache_remove_elt(c, c->names[index])) {
+		G3d_error
+		    ("G3d_cache_remove_all: error in G3d_cache_remove_elt");
+		return 0;
+	    }
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_flush_all(G3D_cache * c)
+{
+    int index;
+
+    for (index = 0; index < c->nofElts; index++)
+	if (IS_ACTIVE_ELT(index))
+	    if (!G3d_cache_flush(c, c->names[index])) {
+		G3d_error("G3d_cache_flush_all: error in G3d_cache_flush");
+		return 0;
+	    }
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+void *G3d_cache_elt_ptr(G3D_cache * c, int name)
+{
+    int index, oldName, doUnlock;
+
+    index = G3d_cache_hash_name2index(c->hash, name);
+
+    if (index != -1) {
+	if (c->autoLock)
+	    if (IS_UNLOCKED_ELT(index) && (!ONE_UNLOCKED_ELT_ONLY) &&
+		(!ARE_MIN_UNLOCKED))
+		G3d_cache_lock_intern(c, index);
+
+	return c->elts + c->eltSize * index;
+    }
+
+    index = c->first;
+    if (IS_ACTIVE_ELT(index)) {
+	oldName = c->names[index];
+	G3d_cache_hash_remove_name(c->hash, oldName);
+	if (!c->eltRemoveFun(oldName, c->elts + c->eltSize * index,
+			     c->eltRemoveFunData)) {
+	    G3d_error("G3d_cache_elt_ptr: error in c->eltRemoveFun");
+	    return NULL;
+	}
+    }
+
+    G3d_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;
+    G3d_cache_lock_intern(c, index);
+
+    if (doUnlock)
+	if (!G3d_cache_unlock(c, name)) {
+	    G3d_error("G3d_cache_elt_ptr: error in G3d_cache_unlock");
+	    return NULL;
+	}
+
+    if (!c->eltLoadFun(name, c->elts + c->eltSize * index, c->eltLoadFunData)) {
+	G3d_error("G3d_cache_elt_ptr: error in c->eltLoadFun");
+	return NULL;
+    }
+
+    return c->elts + c->eltSize * index;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_load(G3D_cache * c, int name)
+{
+    if (G3d_cache_elt_ptr(c, name) == NULL) {
+	G3d_error("G3d_cache_load: error in G3d_cache_elt_ptr");
+	return 0;
+    }
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_get_elt(G3D_cache * c, int name, void *dst)
+{
+    const void *elt;
+
+    elt = G3d_cache_elt_ptr(c, name);
+    if (elt == NULL) {
+	G3d_error("G3d_cache_get_elt: error in G3d_cache_elt_ptr");
+	return 0;
+    }
+
+    memcpy(dst, elt, c->eltSize);
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+int G3d_cache_put_elt(G3D_cache * c, int name, const void *src)
+{
+    void *elt;
+
+    elt = G3d_cache_elt_ptr(c, name);
+    if (elt == NULL) {
+	G3d_error("G3d_cache_put_elt: error in G3d_cache_elt_ptr");
+	return 0;
+    }
+
+    memcpy(elt, src, c->eltSize);
+
+    return 1;
+}
+
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+
+			/* TEST FUNCTIONS */
+
+/*---------------------------------------------------------------------------*/
+
+/*---------------------------------------------------------------------------*/
+
+static void cache_test_print(G3D_cache * c)
+{
+    int i, al;
+    int *a;
+
+    al = c->autoLock;
+    G3d_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 *)G3d_cache_elt_ptr(c, c->names[i]);
+	/*G3d_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)
+	G3d_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 = G3d_malloc(((G3D_cache *) c)->eltSize * sizeof(int));
+	firstTime = 0;
+    }
+
+    ctd.value[17] = val;
+    ctd.size = ((G3D_cache *) c)->eltSize;
+
+    G3d_cache_load(c, name);
+}
+
+/*---------------------------------------------------------------------------*/
+
+int MAIN()
+{
+    void *c;
+
+    c = G3d_cache_new(3, 76 * sizeof(int), 100000,
+		      cache_test_flush_fun, NULL, cache_test_load_fun, &ctd);
+
+    G3d_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);
+    G3d_cache_unlock_all(c);
+    cache_test_print(c);
+    G3d_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);
+    G3d_cache_flush(c, 9999);
+    cache_test_print(c);
+    G3d_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);
+    G3d_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;
+}

lib/raster3d/g3dcats.c → lib/raster3d/cats.c


lib/raster3d/g3dclose.c → lib/raster3d/close.c


lib/raster3d/g3dcolor.c → lib/raster3d/color.c


lib/raster3d/g3ddefaults.c → lib/raster3d/defaults.c


lib/raster3d/g3ddoubleio.c → lib/raster3d/doubleio.c


lib/raster3d/g3derror.c → lib/raster3d/error.c


lib/raster3d/g3dfpxdr.c → lib/raster3d/fpxdr.c


+ 0 - 330
lib/raster3d/g3dcache.c

@@ -1,330 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "G3d_intern.h"
-
-/*---------------------------------------------------------------------------*/
-
-static int cacheRead_readFun(int tileIndex, void *tileBuf, void *closure)
-{
-    G3D_Map *map = closure;
-
-    if (!G3d_readTile(map, tileIndex, tileBuf, map->typeIntern)) {
-	G3d_error("cacheRead_readFun: error in G3d_readTile");
-	return 0;
-    }
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int initCacheRead(G3D_Map * map, int nCached)
-{
-    map->cache = G3d_cache_new_read(nCached,
-				    map->tileSize * map->numLengthIntern,
-				    map->nTiles, cacheRead_readFun, map);
-    if (map->cache == NULL) {
-	G3d_error("initCacheRead: error in G3d_cache_new_read");
-	return 0;
-    }
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-/*
-   the map->index array is (ab)used to store the positions of the tiles in the 
-   file-cash. we can do this since we maintain the invariant for every tile 
-   that it is either in no file (index == -1) or in either the output-file
-   (index >= 0) or the cash-file (index <= -2). to convert the file-position in 
-   the cash-file into an index we use the following function:
-
-   index = - (fileposition + 2)
-
-   symmetrically, we use
-
-   fileposition = - (index + 2)
-
-   to convert from index to the fileposition.
- */
-
-/*---------------------------------------------------------------------------*/
-
-static int cacheWrite_readFun(int tileIndex, void *tileBuf, void *closure)
-{
-    G3D_Map *map = closure;
-    int index, nBytes;
-    long pos, offs, offsLast;
-
-    pos = map->index[tileIndex];
-
-    /* tile has already been flushed onto output file or does not exist yet */
-    if (pos >= -1) {		/* note, G3d_readTile takes care of the case pos == -1 */
-	G3d_readTile(map, tileIndex, tileBuf, map->typeIntern);
-	return 1;
-    }
-
-    /* tile is in cache file */
-
-    pos = -pos - 2;		/* pos is shifted by 2 to avoid 0 and -1 */
-
-    nBytes = map->tileSize * map->numLengthIntern;
-    offs = pos * (nBytes + sizeof(int));
-
-    /* seek tile and read it into buffer */
-
-    if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
-	G3d_error("cacheWrite_readFun: can't position file");
-	return 0;
-    }
-    if (read(map->cacheFD, tileBuf, nBytes) != nBytes) {
-	G3d_error("cacheWrite_readFun: can't read file");
-	return 0;
-    }
-
-    /* remove it from index */
-
-    map->index[tileIndex] = -1;
-
-    /* if it is the last tile in the file we are done */
-    /* map->cachePosLast tells us the position of the last tile in the file */
-
-    if (map->cachePosLast == pos) {
-	map->cachePosLast--;
-	return 1;
-    }
-
-    /* otherwise we move the last tile in the file into the position of */
-    /* the tile we just read and update the hash information */
-
-    offsLast = map->cachePosLast * (nBytes + sizeof(int));
-
-    if (lseek(map->cacheFD, offsLast, SEEK_SET) == -1) {
-	G3d_error("cacheWrite_readFun: can't position file");
-	return 0;
-    }
-    if (read(map->cacheFD, xdr, nBytes + sizeof(int)) != nBytes + sizeof(int)) {
-	G3d_error("cacheWrite_readFun: can't read file");
-	return 0;
-    }
-
-    if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
-	G3d_error("cacheWrite_readFun: can't position file");
-	return 0;
-    }
-    if (write(map->cacheFD, xdr, nBytes + sizeof(int)) !=
-	nBytes + sizeof(int)) {
-	G3d_error("cacheWrite_readFun: can't write file");
-	return 0;
-    }
-
-    index = *((int *)((unsigned char *)xdr + nBytes));
-    map->index[index] = -pos - 2;
-
-    map->cachePosLast--;
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int
-cacheWrite_writeFun(int tileIndex, const void *tileBuf, void *closure)
-{
-    G3D_Map *map = closure;
-    int nBytes;
-    long offs;
-
-    if (map->index[tileIndex] != -1)
-	return 1;
-
-    map->cachePosLast++;
-    nBytes = map->tileSize * map->numLengthIntern;
-    offs = map->cachePosLast * (nBytes + sizeof(int));
-
-    if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
-	G3d_error("cacheWrite_writeFun: can't position file");
-	return 0;
-    }
-    if (write(map->cacheFD, tileBuf, nBytes) != nBytes) {
-	G3d_error("cacheWrite_writeFun: can't write file");
-	return 0;
-    }
-    if (write(map->cacheFD, &tileIndex, sizeof(int)) != sizeof(int)) {
-	G3d_error("cacheWrite_writeFun: can't write file");
-	return 0;
-    }
-
-    map->index[tileIndex] = -map->cachePosLast - 2;
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int disposeCacheWrite(G3D_Map * map)
-{
-    if (map->cacheFD >= 0) {
-	if (close(map->cacheFD) != 0) {
-	    G3d_error("disposeCacheWrite: could not close file");
-	    return 0;
-	}
-	remove(map->cacheFileName);
-	G3d_free(map->cacheFileName);
-    }
-
-    G3d_cache_dispose(map->cache);
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int initCacheWrite(G3D_Map * map, int nCached)
-{
-    map->cacheFileName = G_tempfile();
-    map->cacheFD = open(map->cacheFileName, O_RDWR | O_CREAT | O_TRUNC, 0666);
-
-    if (map->cacheFD < 0) {
-	G3d_error("initCacheWrite: could not open file");
-	return 0;
-    }
-
-    map->cachePosLast = -1;
-
-    map->cache = G3d_cache_new(nCached,
-			       map->tileSize * map->numLengthIntern,
-			       map->nTiles,
-			       cacheWrite_writeFun, map,
-			       cacheWrite_readFun, map);
-
-    if (map->cache == NULL) {
-	disposeCacheWrite(map);
-	G3d_error("initCacheWrite: error in G3d_cache_new");
-	return 0;
-    }
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-int G3d_initCache(G3D_Map * map, int nCached)
-{
-    if (map->operation == G3D_READ_DATA) {
-	if (!initCacheRead(map, nCached)) {
-	    G3d_error("G3d_initCache: error in initCacheRead");
-	    return 0;
-	}
-	return 1;
-    }
-
-    if (!initCacheWrite(map, nCached)) {
-	G3d_error("G3d_initCache: error in initCacheWrite");
-	return 0;
-    }
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-static int disposeCacheRead(G3D_Map * map)
-{
-    G3d_cache_dispose(map->cache);
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-int G3d_disposeCache(G3D_Map * map)
-{
-    if (map->operation == G3D_READ_DATA) {
-	if (!disposeCacheRead(map)) {
-	    G3d_error("G3d_disposeCache: error in disposeCacheRead");
-	    return 0;
-	}
-	return 1;
-    }
-
-    if (!disposeCacheWrite(map)) {
-	G3d_error("G3d_disposeCache: error in disposeCacheWrite");
-	return 0;
-    }
-
-    return 1;
-}
-
-
-/*---------------------------------------------------------------------------*/
-
-static int cacheFlushFun(int tileIndex, const void *tileBuf, void *closure)
-{
-    G3D_Map *map = closure;
-
-    if (!G3d_writeTile(map, tileIndex, tileBuf, map->typeIntern)) {
-	G3d_error("cacheFlushFun: error in G3d_writeTile");
-	return 0;
-    }
-
-    return 1;
-}
-
-/*---------------------------------------------------------------------------*/
-
-int G3d_flushAllTiles(G3D_Map * map)
-{
-    int tileIndex, nBytes;
-    long offs;
-
-    if (map->operation == G3D_READ_DATA) {
-	if (!G3d_cache_remove_all(map->cache)) {
-	    G3d_error("G3d_flushAllTiles: error in G3d_cache_remove_all");
-	    return 0;
-	}
-	return 1;
-    }
-
-    /* make cache write into output file instead of cache file */
-    G3d_cache_set_removeFun(map->cache, cacheFlushFun, map);
-
-    /* first flush all the tiles which are in the file cache */
-
-    nBytes = map->tileSize * map->numLengthIntern;
-
-    while (map->cachePosLast >= 0) {
-	offs = map->cachePosLast * (nBytes + sizeof(int)) + nBytes;
-
-	if (lseek(map->cacheFD, offs, SEEK_SET) == -1) {
-	    G3d_error("G3d_flushAllTiles: can't position file");
-	    return 0;
-	}
-	if (read(map->cacheFD, &tileIndex, sizeof(int)) != sizeof(int)) {
-	    G3d_error("G3d_flushAllTiles: can't read file");
-	    return 0;
-	}
-
-	if (!G3d_cache_load(map->cache, tileIndex)) {
-	    G3d_error("G3d_flushAllTiles: error in G3d_cache_load");
-	    return 0;
-	}
-	if (!G3d_cache_flush(map->cache, tileIndex)) {
-	    G3d_error("G3d_flushAllTiles: error in G3d_cache_flush");
-	    return 0;
-	}
-    }
-
-    /* then flush all the tiles which remain in the non-file cache */
-    if (!G3d_cache_flush_all(map->cache)) {
-	G3d_error("G3d_flushAllTiles: error in G3d_cache_flush_all");
-	return 0;
-    }
-
-    /* now the cache should write into the cache file again */
-    G3d_cache_set_removeFun(map->cache, cacheWrite_writeFun, map);
-
-    return 1;
-}

lib/raster3d/g3dgetvalue.c → lib/raster3d/getvalue.c


lib/raster3d/g3dhistory.c → lib/raster3d/history.c


lib/raster3d/g3dintio.c → lib/raster3d/intio.c


lib/raster3d/g3dkeys.c → lib/raster3d/keys.c


lib/raster3d/g3dlib.dox → lib/raster3d/lib.dox


lib/raster3d/g3dlong.c → lib/raster3d/long.c


lib/raster3d/g3dmapset.c → lib/raster3d/mapset.c


lib/raster3d/g3dmask.c → lib/raster3d/mask.c


lib/raster3d/g3dmisc.c → lib/raster3d/misc.c


lib/raster3d/g3dnull.c → lib/raster3d/null.c


lib/raster3d/g3dopen.c → lib/raster3d/open.c


lib/raster3d/g3dopen2.c → lib/raster3d/open2.c


lib/raster3d/g3dparam.c → lib/raster3d/param.c


lib/raster3d/g3dputvalue.c → lib/raster3d/putvalue.c


lib/raster3d/g3drange.c → lib/raster3d/range.c


lib/raster3d/g3dregion.c → lib/raster3d/region.c


lib/raster3d/g3dresample.c → lib/raster3d/resample.c


lib/raster3d/g3dvolume.c → lib/raster3d/volume.c


lib/raster3d/g3d_volume_layout.png → lib/raster3d/volume_layout.png


lib/raster3d/g3d_volume_layout.xcf → lib/raster3d/volume_layout.xcf


lib/raster3d/g3dwindow.c → lib/raster3d/window.c


lib/raster3d/g3dwindowio.c → lib/raster3d/windowio.c