[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[E-devel] [PATCH] eet: mmap + cache



Hi,

  The attached patch introduce two functionnalities :
	- mmap for loading and manipulating eet file with introducion of 
eet_read_direct.
	- replace caching system by enabling it and using stat syscall to know if 
file need to be reloaded. It also remove eet_cacheburst by eet_clearcache and 
remove all reference to cacheburst (This introduce an API incompability with 
previous eet version).

Cedric

PS: I needed to refactor some part of the code in order to better understood 
what was it's purpose and the idea behind it, it will explain some of the 
change also.
Index: src/lib/Eet.h
===================================================================
RCS file: /var/cvs/e/e17/libs/eet/src/lib/Eet.h,v
retrieving revision 1.33
diff -u -r1.33 Eet.h
--- src/lib/Eet.h	31 May 2006 19:13:51 -0000	1.33
+++ src/lib/Eet.h	11 Jun 2006 17:22:48 -0000
@@ -126,18 +126,13 @@
    EAPI int eet_shutdown(void);
 
    /**
-    * Turn cacheburst on/off
+    * Clear eet cache
     *
-    * @param on Set this to 1 to turn on, 0 to turn off.
-    * 
-    * This enables cacheburst mode. This is where eet will not free items from
-    * its internal share cache even when their references hit 0. This is
-    * intended to be enabled during bursts where eet may open several eet
-    * files over and over and over again (eg in initialization of an app) and
-    * thius this will avoid repeated openings. It will NOT respect changes
-    * on disk and if you open a LOT of files may use a lot of memory.
+    * Eet didn't free items by default. If you are under memory presure, just
+    * call this function to recall all memory that are not yet referenced anymore.
+    * The cache take care of modification on disk.
     */
-   EAPI void eet_cacheburst(int on);
+   EAPI void eet_clearcache();
 
    /**
     * Open an eet file on disk, and returns a handle to it.
@@ -236,6 +231,26 @@
    EAPI void *eet_read(Eet_File *ef, const char *name, int *size_ret);
 
    /**
+
+        * Read a specified entry from an eet file and return data
+    * @param ef A valid eet file handle opened for reading.
+    * @param name Name of the entry. eg: "/base/file_i_want".
+    * @param size_ret Number of bytes read from entry and returned.
+    * @return The data stored in that entry in the eet file.
+    *
+    * This function finds an entry in the eet file that is stored under the
+    * name specified, and returns that data if not compressed and successful.
+    * NULL is returned if the lookup fails or if memory errors are
+    * encountered or if the data is comrpessed. The calling program must never
+    * call free() on the returned data. The number of bytes in the returned
+    * data chunk are placed in size_ret.
+    *
+    * If the eet file handle is not valid NULL is returned and size_ret is
+    * filled with 0.
+    */
+   EAPI void	 *eet_read_direct  (Eet_File *ef, const char *name, int *size_ret);
+
+   /**
     * Write a specified entry to an eet file handle
     * @param ef A valid eet file handle opened for writing.
     * @param name Name of the entry. eg: "/base/file_i_want".
Index: src/lib/Eet_private.h
===================================================================
RCS file: /var/cvs/e/e17/libs/eet/src/lib/Eet_private.h,v
retrieving revision 1.11
diff -u -r1.11 Eet_private.h
--- src/lib/Eet_private.h	20 May 2006 02:44:24 -0000	1.11
+++ src/lib/Eet_private.h	11 Jun 2006 17:22:48 -0000
@@ -46,4 +46,40 @@
 #define PATH_MAX 4096
 #endif
 
+/* caluclate hash table entry valu with bitmask size of hash_size */
+static int
+eet_hash_gen(const char *key, int hash_size)
+{
+   int			hash_num = 0;
+   int			value, i;
+   unsigned char	*ptr;
+ 
+   const int masks[9] =
+     {
+	0x00,
+	0x01,
+	0x03,
+	0x07,
+	0x0f,
+	0x1f,
+	0x3f,
+	0x7f,
+	0xff
+     };
+ 
+   /* no string - index 0 */
+   if (!key) return 0;
+ 
+   /* calc hash num */
+   for (i = 0, ptr = (unsigned char *)key, value = (int)(*ptr);
+	value;
+	ptr++, i++, value = (int)(*ptr))
+     hash_num ^= (value | (value << 8)) >> (i & 0x7);
+
+   /* mask it */
+   hash_num &= masks[hash_size];
+   /* return it */
+   return hash_num;
+}
+
 #endif
Index: src/lib/eet_data.c
===================================================================
RCS file: /var/cvs/e/e17/libs/eet/src/lib/eet_data.c,v
retrieving revision 1.37
diff -u -r1.37 eet_data.c
--- src/lib/eet_data.c	4 Mar 2006 02:46:24 -0000	1.37
+++ src/lib/eet_data.c	11 Jun 2006 17:22:48 -0000
@@ -567,7 +567,7 @@
 {
    int *size;
    int s;
-   int size_ret;
+   int size_ret = 0;
 
    if (!chnk->data) return;
    /* chunk head */
@@ -588,37 +588,6 @@
 
 /*---*/
 
-static int
-_eet_descriptor_hash_gen(char *key, int hash_size)
-{
-   int hash_num = 0, i;
-   unsigned char *ptr;
-   const int masks[9] =
-     {
-	0x00,
-	  0x01,
-	  0x03,
-	  0x07,
-	  0x0f,
-	  0x1f,
-	  0x3f,
-	  0x7f,
-	  0xff
-     };
-   
-   /* no string - index 0 */
-   if (!key) return 0;
-
-   /* calc hash num */
-   for (i = 0, ptr = (unsigned char *)key; *ptr; ptr++, i++)
-     hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8);
-
-   /* mask it */
-   hash_num &= masks[hash_size];
-   /* return it */
-   return hash_num;
-}
-
 static void
 _eet_descriptor_hash_new(Eet_Data_Descriptor *edd)
 {
@@ -632,7 +601,7 @@
 	int hash;
 	
 	ede = &(edd->elements.set[i]);
-	hash = _eet_descriptor_hash_gen((char *) ede->name, 6);
+	hash = eet_hash_gen ((char *) ede->name, 6);
 	if (!edd->elements.hash.buckets[hash].element)
 	  edd->elements.hash.buckets[hash].element = ede;
 	else
@@ -673,7 +642,7 @@
    int hash;
    Eet_Data_Descriptor_Hash *bucket;
    
-   hash = _eet_descriptor_hash_gen(name, 6);
+   hash = eet_hash_gen(name, 6);
    if (!edd->elements.hash.buckets[hash].element) return NULL;
    if (!strcmp(edd->elements.hash.buckets[hash].element->name, name))
      return edd->elements.hash.buckets[hash].element;
@@ -858,12 +827,20 @@
 {
    void *data_dec;
    void *data;
-   int size;
+   int	size;
+   int	required_free = 0;
 
-   data = eet_read(ef, name, &size);
-   if (!data) return NULL;
+   data = eet_read_direct (ef, name, &size);
+   if (!data)
+     {
+	required_free = 1;
+	data = eet_read(ef, name, &size);
+	if (!data) return NULL;
+     }
    data_dec = eet_data_descriptor_decode(edd, data, size);
-   free(data);
+   if (required_free)
+     free(data);
+
    return data_dec;
 }
 
Index: src/lib/eet_image.c
===================================================================
RCS file: /var/cvs/e/e17/libs/eet/src/lib/eet_image.c,v
retrieving revision 1.8
diff -u -r1.8 eet_image.c
--- src/lib/eet_image.c	4 Mar 2006 02:46:24 -0000	1.8
+++ src/lib/eet_image.c	11 Jun 2006 17:22:49 -0000
@@ -716,14 +716,24 @@
 		    unsigned int *w, unsigned int *h, int *alpha,
 		    int *compress, int *quality, int *lossy)
 {
-   void *data;
-   int size;
+   void		*data;
+   int		size;
    unsigned int *d = NULL;
+   int		free_data = 0;
+
+   data = eet_read_direct (ef, name, &size);
+   if (!data)
+     {
+	data = eet_read(ef, name, &size);
+	free_data = 1;
+     }
 
-   data = eet_read(ef, name, &size);
    if (!data) return NULL;
    d = eet_data_image_decode(data, size, w, h, alpha, compress, quality, lossy);
-   free(data);
+
+   if (free_data)
+     free(data);
+
    return d;
 }
 
@@ -732,14 +742,23 @@
 			   unsigned int *w, unsigned int *h, int *alpha,
 			   int *compress, int *quality, int *lossy)
 {
-   void *data;
-   int size;
-   int d;
+   void	*data = NULL;
+   int	size = 0;
+   int	d;
+   int	free_data = 0;
+
+   data = eet_read_direct (ef, name, &size);
+   if (!data)
+     {
+	data = eet_read(ef, name, &size);
+	free_data = 1;
+     }
 
-   data = eet_read(ef, name, &size);
    if (!data) return 0;
    d = eet_data_image_header_decode(data, size, w, h, alpha, compress, quality, lossy);
-   free(data);
+   if (free_data)
+     free(data);
+
    return d;
 }
 
Index: src/lib/eet_lib.c
===================================================================
RCS file: /var/cvs/e/e17/libs/eet/src/lib/eet_lib.c,v
retrieving revision 1.62
diff -u -r1.62 eet_lib.c
--- src/lib/eet_lib.c	31 May 2006 19:13:51 -0000	1.62
+++ src/lib/eet_lib.c	11 Jun 2006 17:22:49 -0000
@@ -2,6 +2,8 @@
  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
  */
 
+#include <sys/mman.h>
+
 #include "Eet.h"
 #include "Eet_private.h"
 
@@ -30,6 +32,10 @@
    unsigned char    delete_me_now : 1;
 
    Eet_File_Header *header;
+
+   uint8_t	   *data;
+   int		    data_size;
+   time_t	    mtime;
 };
 
 struct _Eet_File_Header
@@ -46,11 +52,14 @@
 
 struct _Eet_File_Node
 {
-   char          *name;
+   unsigned char  free_name : 1;
+   unsigned char  compression : 1;
+
    int            offset;
-   int            compression;
    int            size;
    int            data_size;
+
+   char          *name;
    void          *data;
    Eet_File_Node *next; /* FIXME: make buckets linked lists */
 };
@@ -74,14 +83,13 @@
 #endif
 
 /* prototypes of internal calls */
-static Eet_File *eet_cache_find(const char *path, Eet_File **cache, int cache_num);
-static void      eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc);
-static void      eet_cache_del(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc);
-static int       eet_string_match(const char *s1, const char *s2);
-static int       eet_hash_gen(const char *key, int hash_size);
-static Eet_Error eet_flush(Eet_File *ef);
-static Eet_File_Node *find_node_by_name (Eet_File *ef, const char *name);
-static int read_data_from_disk(Eet_File *ef, Eet_File_Node *efn, void *buf, int len);
+static Eet_File		*eet_cache_find (const char *path, Eet_File **cache, int cache_num);
+static void		eet_cache_add (Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc);
+static void		eet_cache_del (Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc);
+static int		eet_string_match (const char *s1, const char *s2);
+static Eet_Error	eet_flush (Eet_File *ef);
+static Eet_File_Node	*find_node_by_name (Eet_File *ef, const char *name);
+static int		read_data_from_disk (Eet_File *ef, Eet_File_Node *efn, void *buf, int len);
 
 /* cache. i don't expect this to ever be large, so arrays will do */
 static int        eet_writers_num     = 0;
@@ -91,7 +99,36 @@
 static int        eet_readers_alloc   = 0;
 static Eet_File **eet_readers         = NULL;
 static int        eet_initcount       = 0;
-static int        eet_cacheburst_mode = 0;
+
+/* Check to see its' an eet file pointer */
+static inline int
+eet_check_pointer (const Eet_File *ef)
+{
+  if ((!ef) || (ef->magic != EET_MAGIC_FILE))
+    return 1;
+  return 0;
+}
+
+static inline int
+eet_check_header (const Eet_File *ef)
+{
+   if (!ef->header)
+     return 1;
+   if (!ef->header->directory)
+     return 1;
+   return 0;
+}
+
+static inline int
+eet_test_close (int test, Eet_File *ef)
+{
+   if (test)
+     {
+	ef->delete_me_now = 1;
+	eet_close (ef);
+     }
+   return test;
+}
 
 /* find an eet file in the currently in use cache */
 static Eet_File *
@@ -101,13 +138,11 @@
 
    /* walk list */
    for (i = 0; i < cache_num; i++)
-     {
-	/* if matches real path - return it */
-	if (eet_string_match(cache[i]->path, path))
-	  {
-	     if (!cache[i]->delete_me_now) return cache[i];
-	  }
-     }
+     /* if matches real path - return it */
+     if (eet_string_match(cache[i]->path, path))
+       if (!cache[i]->delete_me_now)
+	 return cache[i];
+
    /* not found */
    return NULL;
 }
@@ -116,31 +151,31 @@
 static void
 eet_cache_add(Eet_File *ef, Eet_File ***cache, int *cache_num, int *cache_alloc)
 {
-   Eet_File **new_cache;
-   int new_cache_num, new_cache_alloc;
+   Eet_File	**new_cache;
+   int		new_cache_num;
+   int		new_cache_alloc;
 
    new_cache_num = *cache_num;
    if (new_cache_num > 128) /* avoid fd overruns - limit to 128 (most recent) in the cache */
      {
-	Eet_File *del_ef = NULL;
-	int i;
+	Eet_File	*del_ef = NULL;
+	int		i;
 	
 	new_cache = *cache;
 	for (i = 0; i < new_cache_num; i++)
-	  {
-	     if (new_cache[i]->references == 0)
-	       {
-		  del_ef = new_cache[i];
-		  break;
-	       }
-	  }
+	  if (new_cache[i]->references == 0)
+	    {
+	       del_ef = new_cache[i];
+	       break;
+	    }
+
 	if (del_ef)
 	  {
-	     eet_cacheburst_mode = 0;
+	     del_ef->delete_me_now = 1;
 	     eet_close(del_ef);
-	     eet_cacheburst_mode = 1;
 	  }
      }
+
    new_cache = *cache;
    new_cache_num = *cache_num;
    new_cache_alloc = *cache_alloc;
@@ -169,24 +204,23 @@
    int new_cache_num, new_cache_alloc;
    int i, j;
 
-   if (eet_cacheburst_mode) return;
    new_cache = *cache;
    new_cache_num = *cache_num;
    new_cache_alloc = *cache_alloc;
    if (new_cache_num <= 0)
-     {
-	return;
-     }
+     return;
+
    for (i = 0; i < new_cache_num; i++)
-     {
-	if (new_cache[i] == ef) break;
-     }
+     if (new_cache[i] == ef)
+       break;
+
    if (i >= new_cache_num)
-     {
-	return;
-     }
+     return;
+
    new_cache_num--;
-   for (j = i; j < new_cache_num; j++) new_cache[j] = new_cache[j + 1];
+   for (j = i; j < new_cache_num; j++)
+     new_cache[j] = new_cache[j + 1];
+
    if (new_cache_num < (new_cache_alloc - 64))
      {
 	new_cache_alloc -= 64;
@@ -220,163 +254,104 @@
    return (!strcmp(s1, s2));
 }
 
-/* caluclate hash table entry valu with bitmask size of hash_size */
-static int
-eet_hash_gen(const char *key, int hash_size)
-{
-   int hash_num = 0, i;
-   unsigned char *ptr;
-   const int masks[9] =
-     {
-	0x00,
-	0x01,
-	0x03,
-	0x07,
-	0x0f,
-	0x1f,
-	0x3f,
-	0x7f,
-	0xff
-     };
-
-   /* no string - index 0 */
-   if (!key) return 0;
-
-   /* calc hash num */
-   for (i = 0, ptr = (unsigned char *)key; *ptr; ptr++, i++)
-     hash_num ^= ((int)(*ptr) | ((int)(*ptr) << 8)) >> (i % 8);
-
-   /* mask it */
-   hash_num &= masks[hash_size];
-   /* return it */
-   return hash_num;
-}
-
 /* flush out writes to an eet file */
 static Eet_Error
 eet_flush(Eet_File *ef)
 {
-   int i, count, size, num, offset;
-   int head[3];
-   unsigned long int i1, i2;
-   Eet_File_Node *efn;
+   Eet_File_Node	*efn;
+   int			head[3];
+   int			count = 0;
+   int			size = 0;
+   int			offset = 0;
+   int			i;
+   int			num;
 
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE))
+   if (eet_check_pointer (ef))
      return EET_ERROR_BAD_OBJECT;
-   if (!ef->header) return EET_ERROR_EMPTY;
-   if (!ef->header->directory) return EET_ERROR_EMPTY;
-   if ((ef->mode != EET_FILE_MODE_WRITE) && (ef->mode != EET_FILE_MODE_READ_WRITE)) return EET_ERROR_NOT_WRITABLE;
-   if (!ef->writes_pending) return EET_ERROR_NONE;
+   if (eet_check_header (ef))
+     return EET_ERROR_EMPTY;
+   if ((ef->mode != EET_FILE_MODE_WRITE) && (ef->mode != EET_FILE_MODE_READ_WRITE))
+     return EET_ERROR_NOT_WRITABLE;
+   if (!ef->writes_pending)
+     return EET_ERROR_NONE;
 
    /* calculate total size in bytes of directory block */
-   size = 0;
-   count = 0;
    num = (1 << ef->header->directory->size);
    for (i = 0; i < num; i++)
-     {
-	for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
-	  {
-	     if (efn->compression >= 0)
-	       {
-		  size += 20 + strlen(efn->name);
-		  count++;
-	       }
-	  }
-     }
-   /* caluclate offsets per entry */
+     for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+       if (efn->compression >= 0)
+	 {
+	    size += 20 + strlen(efn->name) + 1;
+	    count++;
+	 }
+
+   /* calculate offsets per entry */
    offset = 0;
    for (i = 0; i < num; i++)
-     {
-	for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
-	  {
-	     if (efn->compression >= 0)
-	       {
-		  efn->offset = 12 + size + offset;
-		  offset += efn->size;
-	       }
-	  }
-     }
+     for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+       if (efn->compression >= 0)
+	 {
+	    efn->offset = 12 + size + offset;
+	    offset += efn->size;
+	 }
+
    /* go thru and write the header */
-   i1 = (unsigned long int)EET_MAGIC_FILE;
-   i2 = htonl(i1);
-   head[0] = (int)i2;
-   i1 = (unsigned long int)count;
-   i2 = htonl(i1);
-   head[1] = (int)i2;
-   i1 = (unsigned long int)size;
-   i2 = htonl(i1);
-   head[2] = (int)i2;
+   head[0] = (int) htonl ((uint32_t) EET_MAGIC_FILE);
+   head[1] = (int) htonl ((uint32_t) count);
+   head[2] = (int) htonl ((uint32_t) size);
+
    fseek(ef->fp, 0, SEEK_SET);
-   if (fwrite(head, 12, 1, ef->fp) != 1) goto write_error;
-   offset = 12;
+   if (fwrite(head, 12, 1, ef->fp) != 1)
+     goto write_error;
+
    for (i = 0; i < num; i++)
-     {
-	for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
-	  {
-	     if (efn->compression >= 0)
-	       {
-		  unsigned char *buf;
-		  int buf_size;
-		  int name_size;
-
-		  name_size = strlen(efn->name);
-		  buf_size = 20 + name_size;
-		  buf = alloca(buf_size);
-		  if (!buf) return EET_ERROR_OUT_OF_MEMORY;
-		  i1 = (unsigned long int)efn->offset;
-		  i2 = htonl(i1);
-		  *((int *)(buf + 0)) = (int)i2;
-		  i1 = (unsigned long int)efn->compression;
-		  i2 = htonl(i1);
-		  *((int *)(buf + 4)) = (int)i2;
-		  i1 = (unsigned long int)efn->size;
-		  i2 = htonl(i1);
-		  *((int *)(buf + 8)) = (int)i2;
-		  i1 = (unsigned long int)efn->data_size;
-		  i2 = htonl(i1);
-		  *((int *)(buf + 12)) = (int)i2;
-		  i1 = (unsigned long int)name_size;
-		  i2 = htonl(i1);
-		  *((int *)(buf + 16)) = (int)i2;
-		  memcpy(buf + 20, efn->name, name_size);
-		  if (fwrite(buf, buf_size, 1, ef->fp) != 1)
-		    {
-		       write_error:
-		       switch (ferror(ef->fp))
-			 {
-			  case EFBIG:
-			    return EET_ERROR_WRITE_ERROR_FILE_TOO_BIG;
-			  case EIO:
-			    return EET_ERROR_WRITE_ERROR_IO_ERROR;
-			  case ENOSPC:
-			    return EET_ERROR_WRITE_ERROR_OUT_OF_SPACE;
-			  case EPIPE:
-			    return EET_ERROR_WRITE_ERROR_FILE_CLOSED;
-			  default:
-			    return EET_ERROR_WRITE_ERROR;
-			 }
-		       return EET_ERROR_WRITE_ERROR;
-		    }
-		  offset += buf_size;
-	       }
-	  }
-     }
+     for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+       if (efn->compression >= 0)
+	 {
+	    uint32_t	ibuf[5];
+	    int		name_size;
+	    
+	    name_size = strlen(efn->name) + 1;
+	    
+	    ibuf[0] = (int) htonl ((uint32_t) efn->offset);
+	    ibuf[1] = (int) htonl ((uint32_t) efn->compression);
+	    ibuf[2] = (int) htonl ((uint32_t) efn->size);
+	    ibuf[3] = (int) htonl ((uint32_t) efn->data_size);
+	    ibuf[4] = (int) htonl ((uint32_t) name_size);
+	    
+	    if (fwrite(ibuf, sizeof (ibuf), 1, ef->fp) != 1)
+	      goto write_error;
+	    if (fwrite(efn->name, name_size, 1, ef->fp) != 1)
+	      goto write_error;
+	 }
+   
    /* write data */
    for (i = 0; i < num; i++)
-     {
-	for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
-	  {
-	     if (efn->compression >= 0)
-	       {
-		  if (fwrite(efn->data, efn->size, 1, ef->fp) != 1)
-		    goto write_error;
-	       }
-	  }
-     }
+     for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+       if (efn->compression >= 0)
+	 if (fwrite(efn->data, efn->size, 1, ef->fp) != 1)
+	   goto write_error;
+
    /* no more writes pending */
    ef->writes_pending = 0;
    return EET_ERROR_NONE;
+   
+write_error:
+   switch (ferror(ef->fp))
+     {
+     case EFBIG:
+	return EET_ERROR_WRITE_ERROR_FILE_TOO_BIG;
+     case EIO:
+	return EET_ERROR_WRITE_ERROR_IO_ERROR;
+     case ENOSPC:
+	return EET_ERROR_WRITE_ERROR_OUT_OF_SPACE;
+     case EPIPE:
+	return EET_ERROR_WRITE_ERROR_FILE_CLOSED;
+     default:
+	return EET_ERROR_WRITE_ERROR;
+     }
+   return EET_ERROR_WRITE_ERROR;
 }
 
 EAPI int
@@ -389,66 +364,63 @@
 eet_shutdown(void)
 {
    if (--eet_initcount == 0)
-     {
-	eet_cacheburst(0);
-	_eet_memfile_shutdown();
-     }
+     _eet_memfile_shutdown();
 
    return eet_initcount;
 }
 
 EAPI void
-eet_cacheburst(int on)
+eet_clearcache()
 {
-   if (eet_cacheburst_mode == on) return;
-   eet_cacheburst_mode = on;
-   if (!eet_cacheburst_mode)
+   int	num = 0;
+   int	i;
+   
+   /*
+     We need to compute the list of eet file to close separately from the cache,
+     due to eet_close removing them from the cache after each call.
+   */
+   for (i = 0; i < eet_writers_num; i++)
+     if (eet_writers[i]->references == 0)
+       num++;
+   
+   for (i = 0; i < eet_readers_num; i++)
+     if (eet_readers[i]->references == 0)
+       num++;
+
+   if (num > 0)
      {
-	int i;
-	int num;
+	Eet_File **closelist = NULL;
 	
+	closelist = alloca(num * sizeof(Eet_File *));
 	num = 0;
 	for (i = 0; i < eet_writers_num; i++)
-	  {
-	     if (eet_writers[i]->references == 0) num++;
-	  }
+	  if (eet_writers[i]->references == 0)
+	    {
+	       closelist[num] = eet_writers[i];
+	       num++;
+	    }
+	
 	for (i = 0; i < eet_readers_num; i++)
-	  {
-	     if (eet_readers[i]->references == 0) num++;
-	  }
-	if (num > 0)
-	  {
-	     Eet_File **closelist = NULL;
-	     
-	     closelist = alloca(num * sizeof(Eet_File *));
-	     num = 0;
-	     for (i = 0; i < eet_writers_num; i++)
-	       {
-		  if (eet_writers[i]->references == 0)
-		    {
-		       closelist[num] = eet_writers[i];
-		       num++;
-		    }
-	       }
-	     for (i = 0; i < eet_readers_num; i++)
-	       {
-		  if (eet_readers[i]->references == 0)
-		    {
-		       closelist[num] = eet_readers[i];
-		       num++;
-		    }
-	       }
-	     for (i = 0; i < num; i++) eet_close(closelist[i]);
-	  }
+	  if (eet_readers[i]->references == 0)
+	    {
+	       closelist[num] = eet_readers[i];
+	       num++;
+	    }
+	
+	for (i = 0; i < num; i++)
+	  eet_close(closelist[i]);
      }
 }
 
 EAPI Eet_File *
 eet_open(const char *file, Eet_File_Mode mode)
 {
-   Eet_File *ef;
+   Eet_File	*ef;
+   struct stat	file_stat;
+   
+   if (!file)
+     return NULL;
 
-   if (!file) return NULL;
    /* find the current file handle in cache*/
    ef = NULL;
    if (mode == EET_FILE_MODE_READ)
@@ -458,16 +430,37 @@
 	  {
 	     eet_flush(ef);
 	     ef->delete_me_now = 1;
+	     eet_close (ef);
 	  }
 	ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
      }
    else if ((mode == EET_FILE_MODE_WRITE) || (mode == EET_FILE_MODE_READ_WRITE))
      {
 	ef = eet_cache_find((char *)file, eet_readers, eet_readers_num);
-	if (ef) ef->delete_me_now = 1;
+	if (ef)
+	  {
+	     ef->delete_me_now = 1;
+	     eet_close (ef);
+	  }
 	ef = eet_cache_find((char *)file, eet_writers, eet_writers_num);
      }
-   /* we found one */
+
+   if (stat (file, &file_stat))
+     {
+	if (mode == EET_FILE_MODE_WRITE)
+	  memset (&file_stat, 0, sizeof (file_stat));
+	else
+	  return NULL;
+     }
+
+   /* We found one */
+   if (ef && file_stat.st_mtime != ef->mtime)
+     {
+	ef->delete_me_now = 1;
+	eet_close (ef);
+	ef = NULL;
+     }
+   
    if (ef)
      {
 	/* reference it up and return it */
@@ -475,9 +468,10 @@
 	return ef;
      }
 
-   /* allocate struct for eet file and have it zero'd out */
-   ef = calloc(1, sizeof(Eet_File) + strlen(file) + 1);
-   if (!ef) return NULL;
+   /* Allocate struct for eet file and have it zero'd out */
+   ef = malloc (sizeof(Eet_File) + strlen(file) + 1);
+   if (!ef)
+     return NULL;
 
    /* fill some of the members */
    ef->path = ((char *)ef) + sizeof(Eet_File);
@@ -485,199 +479,170 @@
    ef->magic = EET_MAGIC_FILE;
    ef->references = 1;
    ef->mode = mode;
+   ef->header = NULL;
+   ef->mtime = file_stat.st_mtime;
+   ef->delete_me_now = 0;
 
    /* try open the file based on mode */
    if ((ef->mode == EET_FILE_MODE_READ) || (ef->mode == EET_FILE_MODE_READ_WRITE))
      ef->fp = fopen(ef->path, "rb");
-   else if (ef->mode == EET_FILE_MODE_WRITE)
-     {
-	/* opening for write - delete old copy of file right away */
-	unlink(ef->path);
-	ef->fp = fopen(ef->path, "wb");
-     }
    else
-     {
-	ef->delete_me_now = 1;
-	eet_close(ef);
-	return NULL;
-     }
+     if (eet_test_close (ef->mode != EET_FILE_MODE_WRITE, ef))
+       return NULL;
+     else
+       {
+	  /* opening for write - delete old copy of file right away */
+	  unlink(ef->path);
+	  ef->fp = fopen(ef->path, "wb");
+       }
 
    /* if we can't open - bail out */
-   if (!ef->fp)
-     {
-	ef->delete_me_now = 1;
-	eet_close(ef);
-	return NULL;
-     }
+   if (eet_test_close (!ef->fp, ef))
+     return NULL;
+
+   ef->data = NULL;
+   ef->data_size = 0;
 
    /* if we opened for read or read-write */
-//   printf("OPEN!\n");
    if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
      {
-	unsigned char buf[12];
-	unsigned char *dyn_buf, *p;
-	unsigned long int i1, i2;
-	int num_entries, byte_entries, i;
-	size_t count;
+	unsigned char		*dyn_buf = NULL;
+	unsigned char		*p = NULL;
+	int			index = 0;
+	int			num_entries;
+	int			byte_entries;
+	int			i;
+
+	ef->data_size = file_stat.st_size;
+	ef->data = mmap(NULL, ef->data_size, PROT_READ, MAP_SHARED, fileno(ef->fp), 0);
+
+	if (eet_test_close (ef->data == (void*) -1 || ef->data == NULL, ef))
+	  return NULL;
 
 	/* build header table if read mode */
 	/* geat header */
-	count = fread(buf, 12, 1, ef->fp);
-	if (count != 1)
-	  {
-	     eet_close(ef);
-	     return NULL;
-	  }
-	/* get magic no */
-	memcpy(&i1, buf + 0, sizeof(int));
-	i2 = ntohl(i1);
-	if (i2 != EET_MAGIC_FILE)
-	  {
-	     eet_close(ef);
-	     return NULL;
-	  }
+	index += sizeof (int);
+	if (eet_test_close ((int) ntohl (*((int*) ef->data)) != EET_MAGIC_FILE, ef))
+	  return NULL;
+
+#define	EXTRACT_INT(Value, Pointer, Index) \
+	Value = ntohl (*((int*)(Pointer + Index))); \
+	Index += sizeof (int);
+
 	/* get entries count and byte count */
-	memcpy(&i1, buf + 4, sizeof(int));
-	i2 = ntohl(i1);
-	num_entries = (int)i2;
-	memcpy(&i1, buf + 8, sizeof(int));
-	i2 = ntohl(i1);
-	byte_entries = (int)i2;
+	EXTRACT_INT(num_entries, ef->data, index);
+	EXTRACT_INT(byte_entries, ef->data, index);
+
 	/* we cant have <= 0 values here - invalid */
-	if ((num_entries <= 0) || (byte_entries <= 0))
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
+	if (eet_test_close ((num_entries <= 0) || (byte_entries <= 0), ef))
+	  return NULL;
+
 	/* we can't have more entires than minimum bytes for those! invalid! */
-	if ((num_entries * 20) > byte_entries)
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
-	/* allocate dynamic buffer for entire directory block */
-	dyn_buf = alloca(byte_entries);
-	if (!dyn_buf)
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
+	if (eet_test_close ((num_entries * 20) > byte_entries, ef))
+	  return NULL;
+
 	/* allocate header */
 	ef->header = calloc(1, sizeof(Eet_File_Header));
-	if (!ef->header)
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
+	if (eet_test_close (!ef->header, ef))
+	  return NULL;
+
 	ef->header->magic = EET_MAGIC_FILE_HEADER;
+
 	/* allocate directory block in ram */
 	ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
-	if (!ef->header->directory)
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
+	if (eet_test_close (!ef->header->directory, ef))
+	  return NULL;
+
 	/* 8 bit hash table (256 buckets) */
 	ef->header->directory->size = 8;
 	/* allocate base hash table */
 	ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
-	if (!ef->header->directory->nodes)
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
+	if (eet_test_close (!ef->header->directory->nodes, ef))
+	  return NULL;
+
 	/* actually read the directory block - all of it, into ram */
-	count = fread(dyn_buf, byte_entries, 1, ef->fp);
-	if (count != 1)
-	  {
-	     ef->delete_me_now = 1;
-	     eet_close(ef);
-	     return NULL;
-	  }
+	dyn_buf = ef->data + index;
+
 	/* parse directory block */
 	p = dyn_buf;
-//	printf("entries: %i\n", num_entries);
+
 	for (i = 0; i < num_entries; i++)
 	  {
-	     int offset;
-	     int flags;
-	     int size;
-	     int data_size;
-	     int name_size;
-	     int hash;
-	     Eet_File_Node *efn;
-	     void *data = NULL;
+	     Eet_File_Node	*efn;
+	     void		*data = NULL;
+	     int		indexn = 0;
+	     int		name_size;
+	     int		hash;
+	     int		k;
+
+#define HEADER_SIZE sizeof (uint32_t) * 5
 
 	     /* out directory block is inconsistent - we have oveerun our */
 	     /* dynamic block buffer before we finished scanning dir entries */
-	     if (p >= (dyn_buf + byte_entries))
-	       {
-		  ef->delete_me_now = 1;
-		  eet_close(ef);
-		  return NULL;
-	       }
+	     if (eet_test_close (p + HEADER_SIZE >= (dyn_buf + byte_entries), ef))
+	       return NULL;
+
+	     /* allocate all the ram needed for this stored node accounting */
+	     efn = malloc (sizeof(Eet_File_Node));
+	     if (eet_test_close (!efn, ef))
+	       return NULL;
+
 	     /* get entrie header */
-	     memcpy(&i1, p + 0, sizeof(int));
-	     i2 = ntohl(i1);
-	     offset = (int)i2;
-	     memcpy(&i1, p + 4, sizeof(int));
-	     i2 = ntohl(i1);
-	     flags = (int)i2;
-	     memcpy(&i1, p + 8, sizeof(int));
-	     i2 = ntohl(i1);
-	     size = (int)i2;
-	     memcpy(&i1, p + 12, sizeof(int));
-	     i2 = ntohl(i1);
-	     data_size = (int)i2;
-	     memcpy(&i1, p + 16, sizeof(int));
-	     i2 = ntohl(i1);
-	     name_size = (int)i2;
+	     EXTRACT_INT(efn->offset, p, indexn);
+	     EXTRACT_INT(efn->compression, p, indexn);
+	     EXTRACT_INT(efn->size, p, indexn);
+	     EXTRACT_INT(efn->data_size, p, indexn);
+	     EXTRACT_INT(name_size, p, indexn);
+
 	     /* invalid size */
-	     if (size <= 0)
+	     if (eet_test_close (efn->size <= 0, ef))
 	       {
-		  eet_close(ef);
+		  free (efn);
 		  return NULL;
 	       }
+
 	     /* invalid name_size */
-	     if (name_size <= 0)
+	     if (eet_test_close (name_size <= 0, ef))
 	       {
-		  ef->delete_me_now = 1;
-		  eet_close(ef);
+		  free (efn);
 		  return NULL;
 	       }
+	     
 	     /* reading name would mean falling off end of dyn_buf - invalid */
-	     if ((p + 16 + name_size) > (dyn_buf + byte_entries))
+	     if (eet_test_close ((p + 16 + name_size) > (dyn_buf + byte_entries), ef))
 	       {
-		  ef->delete_me_now = 1;
-		  eet_close(ef);
+		  free (efn);
 		  return NULL;
 	       }
-	     /* allocate all the ram needed for this stored node accounting */
-	     efn = malloc(sizeof(Eet_File_Node) + name_size + 1);
-	     if (!efn)
+
+	     /* This code is useless if we dont want backward compatibility */
+	     for (k = name_size; k > 0 && ((uint8_t)*(p + HEADER_SIZE + k)) != 0; --k)
+	       ;
+
+	     efn->free_name = ((uint8_t)*(p + HEADER_SIZE + k)) != 0;
+
+	     if (efn->free_name)
 	       {
-		  ef->delete_me_now = 1;
-		  eet_close(ef);
-		  return NULL;
+		  efn->name = malloc (sizeof (char) * name_size + 1);
+		  if (eet_test_close (efn->name == NULL, ef))
+		    {
+		       free (efn);
+		       return NULL;
+		    }
+
+		  strncpy(efn->name, (char *)p + HEADER_SIZE, name_size);
+		  efn->name[name_size] = 0;
+
+		  printf("File: %s is not up to date for key %s\n", ef->path, efn->name);
 	       }
-	     efn->name = ((char *)efn) + sizeof(Eet_File_Node);
-	     /* copy name in and terminate it */
-	     strncpy(efn->name, (char *)p + 20, name_size);
-	     efn->name[name_size] = 0;
-	     /* get hask bucket it should go in */
+	     else
+	       /* The only really usefull peace of code for efn->name (no backward compatibility) */
+	       efn->name = (char*) ((uint8_t*)(p + HEADER_SIZE));
+
+	     /* get hash bucket it should go in */
 	     hash = eet_hash_gen(efn->name, ef->header->directory->size);
 	     efn->next = ef->header->directory->nodes[hash];
 	     ef->header->directory->nodes[hash] = efn;
-	     efn->offset = offset;
-	     efn->compression = flags;
-	     efn->size = size;
-	     efn->data_size = data_size;
 
 	     /* read-only mode, so currently we have no data loaded */
 	     if (mode == EET_FILE_MODE_READ)
@@ -685,28 +650,13 @@
 	     /* read-write mode - read everything into ram */
 	     else
 	       {
-		  data = malloc(size);
+		  data = malloc(efn->size);
 		  if (data)
-		    {
-		       if (fseek(ef->fp, efn->offset, SEEK_SET) < 0)
-			 {
-			    free(data);
-			    data = NULL;
-			    /* XXX die gracefully somehow */
-			    break;
-			 }
-		       if (fread(data, size, 1, ef->fp) != 1)
-			 {
-			    free(data);
-			    data = NULL;
-			    /* XXX die gracefully somehow */
-			    break;
-			 }
-		    }
+		    memcpy (data, ef->data + efn->offset, efn->size);
                   efn->data = data;
 	       }
 	     /* advance */
-	     p += 20 + name_size;
+	     p += HEADER_SIZE + name_size;
 	  }
      }
 
@@ -723,9 +673,11 @@
      {
 	if (ef->mode == EET_FILE_MODE_READ)
 	  eet_cache_add(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
-	else if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE))
-	  eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
+	else
+	  if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE))
+	    eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
      }
+
    return ef;
 }
 
@@ -745,27 +697,27 @@
    Eet_Error err;
    
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE))
+   if (eet_check_pointer (ef))
      return EET_ERROR_BAD_OBJECT;
    /* deref */
    ef->references--;
    /* if its still referenced - dont go any further */
    if (ef->references > 0) return EET_ERROR_NONE;
-   /* if we are in cacheburst mode - dont free it - leave it in cache */
-   if (eet_cacheburst_mode)
-     {
-	if (!ef->delete_me_now) return EET_ERROR_NONE;
-     }
+   /* flush any writes */
+   err = eet_flush(ef);
+
+   /* if not urgent to delete it - dont free it - leave it in cache */
+   if (!ef->delete_me_now)
+     return EET_ERROR_NONE;
    /* remove from cache */
    if (ef->mode == EET_FILE_MODE_READ)
      eet_cache_del(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
    else if ((ef->mode == EET_FILE_MODE_WRITE) || (ef->mode == EET_FILE_MODE_READ_WRITE))
      eet_cache_del(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
-   /* flush any writes */
-   err = eet_flush(ef);
 
    /* free up members */
-   if (ef->fp) fclose(ef->fp);
+   if (ef->fp)
+     fclose(ef->fp);
 
    /* free up data */
    if (ef->header)
@@ -775,7 +727,7 @@
 	     if (ef->header->directory->nodes)
 	       {
 		  int i, num;
-
+	       
 		  num = (1 << ef->header->directory->size);
 		  for (i = 0; i < num; i++)
 		    {
@@ -783,8 +735,14 @@
 		       
 		       while ((efn = ef->header->directory->nodes[i]))
 			 {
-			    if (efn->data) free(efn->data);
+			    if (efn->data)
+			      free(efn->data);
+
 			    ef->header->directory->nodes[i] = efn->next;
+
+			    if (efn->free_name)
+			      free(efn->name);
+
 			    free(efn);
 			 }
 		    }
@@ -794,6 +752,8 @@
 	  }
 	free(ef->header);
      }
+   if (ef->data)
+     munmap (ef->data, ef->data_size);
 
    /* zero out ram for struct - caution tactic against stale memory use */
    memset(ef, 0, sizeof(Eet_File));
@@ -805,34 +765,38 @@
 EAPI void *
 eet_read(Eet_File *ef, const char *name, int *size_ret)
 {
-   void *data = NULL;
-   int size = 0;
-   Eet_File_Node *efn;
-   
-   if (size_ret) *size_ret = 0;
+   void			*data = NULL;
+   int			size = 0;
+   Eet_File_Node	*efn;
+
+   if (size_ret)
+     *size_ret = 0;
 
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) ||
-       ((ef->mode != EET_FILE_MODE_READ) &&
-        (ef->mode != EET_FILE_MODE_READ_WRITE)))
-     {
-	return NULL;
-     }
+   if (eet_check_pointer (ef))
+     return NULL;
+   if (!name)
+     return NULL;
+   if ((ef->mode != EET_FILE_MODE_READ) &&
+       (ef->mode != EET_FILE_MODE_READ_WRITE))
+     return NULL;
+
    /* no header, return NULL */
-   if (!ef->header) return NULL;
-   /* no directory, return NULL */
-   if (!ef->header->directory) return NULL;
+   if (eet_check_header (ef))
+     return NULL;
 
    /* hunt hash bucket */
    efn = find_node_by_name(ef, name);
-   if (!efn) return NULL;
+   if (!efn)
+     return NULL;
 
    /* get size (uncompressed, if compressed at all) */
    size = efn->data_size;
 
    /* allocate data */
    data = malloc(size);
-   if (!data) return NULL;
+   if (!data)
+     return NULL;
 
    /* uncompressed data */
    if (efn->compression == 0)
@@ -840,18 +804,20 @@
 	/* if we alreayd have the data in ram... copy that */
 	if (efn->data)
 	  memcpy(data, efn->data, efn->size);
-	else if (!read_data_from_disk(ef, efn, data, size))
-	  {
-	     free(data);
-	     return NULL;
-	  }
+	else
+	  if (!read_data_from_disk(ef, efn, data, size))
+	    {
+	       free(data);
+	       return NULL;
+	    }
      }
    /* compressed data */
    else
      {
-	void *tmp_data;
-	int free_tmp = 0, compr_size = efn->size;
-	uLongf dlen;
+	void	*tmp_data;
+	int	free_tmp = 0;
+	int	compr_size = efn->size;
+	uLongf	dlen;
 
 	/* if we already have the data in ram... copy that */
 	if (efn->data)
@@ -869,6 +835,7 @@
 
 	     if (!read_data_from_disk(ef, efn, tmp_data, compr_size))
 	       {
+		  free(tmp_data);
 		  free(data);
 		  return NULL;
 	       }
@@ -883,56 +850,109 @@
 	     return NULL;
 	  }
 
-	if (free_tmp) free(tmp_data);
+	if (free_tmp)
+	  free(tmp_data);
      }
 
    /* fill in return values */
-   if (size_ret) *size_ret = size;
+   if (size_ret)
+     *size_ret = size;
+
+   return data;
+}
+
+EAPI void *
+eet_read_direct(Eet_File *ef, const char *name, int *size_ret)
+{
+   void *data = NULL;
+   int size = 0;
+   Eet_File_Node *efn;
+   
+   if (size_ret)
+     *size_ret = 0;
+
+   /* check to see its' an eet file pointer */
+   if (eet_check_pointer (ef))
+     return NULL;
+   if (!name)
+     return NULL;
+   if ((ef->mode != EET_FILE_MODE_READ) &&
+       (ef->mode != EET_FILE_MODE_READ_WRITE))
+     return NULL;
+
+   /* no header, return NULL */
+   if (eet_check_header (ef))
+     return NULL;
+
+   /* hunt hash bucket */
+   efn = find_node_by_name(ef, name);
+   if (!efn)
+     return NULL;
+
+   /* get size (uncompressed, if compressed at all) */
+   size = efn->data_size;
+
+   /* uncompressed data */
+   if (efn->compression == 0)
+     data = efn->data ? efn->data : ef->data + efn->offset;
+   /* compressed data */
+   else
+     data = NULL;
+
+   /* fill in return values */
+   if (size_ret)
+     *size_ret = size;
+
    return data;
 }
 
 EAPI int
 eet_write(Eet_File *ef, const char *name, const void *data, int size, int compress)
 {
-   int data_size;
-   int hash;
-   Eet_File_Node *efn;
-   void *data2;
-   int exists_already = 0;
+   Eet_File_Node	*efn;
+   void			*data2;
+   int			exists_already = 0;
+   int			data_size;
+   int			hash;
 
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name) || (!data) || 
-       (size <= 0) || ((ef->mode != EET_FILE_MODE_WRITE) &&
-		       (ef->mode != EET_FILE_MODE_READ_WRITE)))
+   if (eet_check_pointer (ef))
+     return 0;
+   if ((!name) || (!data) || (size <= 0))
+     return 0;
+   if ((ef->mode != EET_FILE_MODE_WRITE) &&
+       (ef->mode != EET_FILE_MODE_READ_WRITE))
      return 0;
 
    if (!ef->header)
      {
 	/* allocate header */
 	ef->header = calloc(1, sizeof(Eet_File_Header));
-	if (!ef->header) return 0;
+	if (!ef->header)
+	  return 0;
+
 	ef->header->magic = EET_MAGIC_FILE_HEADER;
 	/* allocate directory block in ram */
 	ef->header->directory = calloc(1, sizeof(Eet_File_Directory));
-	if (!ef->header->directory) return 0;
+	if (!ef->header->directory)
+	  return 0;
+
 	/* 8 bit hash table (256 buckets) */
 	ef->header->directory->size = 8;
 	/* allocate base hash table */
 	ef->header->directory->nodes = calloc(1, sizeof(Eet_File_Node *) * (1 << ef->header->directory->size));
-	if (!ef->header->directory->nodes) return 0;
+	if (!ef->header->directory->nodes)
+	  return 0;
      }
 
    /* figure hash bucket */
    hash = eet_hash_gen(name, ef->header->directory->size);
 
-   /* dup data */
-   data_size = size;
-
-   /* have bigger buffer for compress */
-   if (compress) data_size = 12 + ((size * 101) / 100);
+   data_size = compress ? 12 + ((size * 101) / 100) : size;
 
    data2 = malloc(data_size);
-   if (!data2) return 0;
+   if (!data2)
+     return 0;
 
    /* if we want to compress */
    if (compress)
@@ -959,7 +979,8 @@
 	     void *data3;
 
 	     data3 = realloc(data2, data_size);
-	     if (data3) data2 = data3;
+	     if (data3)
+	       data2 = data3;
 	  }
      }
    if (!compress)
@@ -985,14 +1006,14 @@
      }
    if (!exists_already)
      {
-	efn = malloc(sizeof(Eet_File_Node) + strlen(name) + 1);
+	efn = malloc(sizeof(Eet_File_Node));
 	if (!efn)
 	  {
 	     free(data2);
 	     return 0;
 	  }
-	efn->name = (char *)efn + sizeof(Eet_File_Node);
-	strcpy(efn->name, name);
+	efn->name = strdup(name);
+	efn->free_name = 1;
 	efn->next = ef->header->directory->nodes[hash];
 	ef->header->directory->nodes[hash] = efn;
 	efn->offset = 0;
@@ -1010,29 +1031,38 @@
 EAPI int
 eet_delete(Eet_File *ef, const char *name)
 {
-   int hash;
-   int exists_already = 0;
-   Eet_File_Node *efn, *pefn;
+   Eet_File_Node	*efn;
+   Eet_File_Node	*pefn;
+   int			hash;
+   int			exists_already = 0;
    
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!name))
+   if (eet_check_pointer (ef))
+     return 0;
+   if (!name)
      return 0;
 
    /* deleting keys is only possible in RW or WRITE mode */
-   if (ef->mode == EET_FILE_MODE_READ) return 0;
+   if (ef->mode == EET_FILE_MODE_READ)
+     return 0;
 
-   if (!ef->header) return 0;
+   if (eet_check_header (ef))
+     return 0;
 
    /* figure hash bucket */
    hash = eet_hash_gen(name, ef->header->directory->size);
 
    /* Does this node already exist? */
-   for (pefn = NULL, efn = ef->header->directory->nodes[hash]; efn; pefn = efn, efn = efn->next)
+   for (pefn = NULL, efn = ef->header->directory->nodes[hash];
+	efn;
+	pefn = efn, efn = efn->next)
      {
 	/* if it matches */
 	if (eet_string_match(efn->name, name))
 	  {
-	     if (efn->data) free(efn->data);
+	     if (efn->data)
+	       free(efn->data);
+
 	     if (efn == ef->header->directory->nodes[hash])
 	       ef->header->directory->nodes[hash] = efn->next;
 	     else
@@ -1043,7 +1073,9 @@
 	  }
      }
    /* flags that writes are pending */
-   if (exists_already) ef->writes_pending = 1;
+   if (exists_already)
+     ef->writes_pending = 1;
+
    /* update access time */
    return exists_already;
 }
@@ -1051,57 +1083,64 @@
 EAPI char **
 eet_list(Eet_File *ef, const char *glob, int *count_ret)
 {
-   char **list_ret = NULL;
-   int list_count = 0;
-   int list_count_alloc = 0;
-   int i, num;
-   Eet_File_Node *efn;
+   Eet_File_Node	*efn;
+   char			**list_ret = NULL;
+   int			list_count = 0;
+   int			list_count_alloc = 0;
+   int			i, num;
 
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE) || (!glob) ||
-       (!ef->header) || (!ef->header->directory) ||
+   if (eet_check_pointer (ef) || eet_check_header (ef) ||
+       (!glob) ||
        ((ef->mode != EET_FILE_MODE_READ) &&
         (ef->mode != EET_FILE_MODE_READ_WRITE)))
      {
-	if (count_ret) *count_ret = 0;
+	if (count_ret)
+	  *count_ret = 0;
+
 	return NULL;
      }
+
    /* loop through all entries */
    num = (1 << ef->header->directory->size);
    for (i = 0; i < num; i++)
-     {
-	for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
-	  {
-	     /* if the entry matches the input glob
-	      * check for * explicitly, because on some systems, * isn't well
-	      * supported
-	      */
-	     if ((!strcmp (glob, "*")) || !fnmatch(glob, efn->name, 0))
-	       {
-		  char **new_list;
+     for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+       /* if the entry matches the input glob
+	* check for * explicitly, because on some systems, * isn't well
+	* supported
+	*/
+       if ((!strcmp (glob, "*")) || !fnmatch(glob, efn->name, 0))
+	 {
+	    /* add it to our list */
+	    list_count++;
+
+	    /* only realloc in 32 entry chunks */
+	    if (list_count > list_count_alloc)
+	      {
+		 char	**new_list = NULL;
+	    
+		 list_count_alloc += 64;
+		 new_list = realloc(list_ret, list_count_alloc * (sizeof(char *)));
+		 if (!new_list)
+		   {
+		      free(list_ret);
+
+		      if (count_ret)
+			*count_ret = 0;
+		      
+		      return NULL;
+		   }
+		 list_ret = new_list;
+	      }
+
+	    /* put pointer of name string in */
+	    list_ret[list_count - 1] = efn->name;
+	 }
 
-		  /* add it to our list */
-		  list_count++;
-		  /* only realloc in 32 entry chunks */
-		  if (list_count > list_count_alloc)
-		    {
-		       list_count_alloc += 64;
-		       new_list = realloc(list_ret, list_count_alloc * (sizeof(char *)));
-		       if (!new_list)
-			 {
-			    free(list_ret);
-			    if (count_ret) *count_ret = 0;
-			    return NULL;
-			 }
-		       list_ret = new_list;
-		    }
-		  /* put pointer of name string in */
-		  list_ret[list_count - 1] = efn->name;
-	       }
-	  }
-     }
    /* return count and list */
-   if (count_ret) *count_ret = list_count;
+   if (count_ret)
+     *count_ret = list_count;
+
    return list_ret;
 }
 
@@ -1112,23 +1151,16 @@
    Eet_File_Node *efn;
 
    /* check to see its' an eet file pointer */
-   if ((!ef) || (ef->magic != EET_MAGIC_FILE) ||
-       (!ef->header) || (!ef->header->directory) ||
+   if (eet_check_pointer (ef) || eet_check_header (ef) ||
        ((ef->mode != EET_FILE_MODE_READ) &&
         (ef->mode != EET_FILE_MODE_READ_WRITE)))
-     {
-	return -1;
-     }
+     return -1;
 
    /* loop through all entries */
    num = (1 << ef->header->directory->size);
    for (i = 0; i < num; i++)
-     {
-	for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
-	  {
-	     ret++;
-	  }
-     }
+     for (efn = ef->header->directory->nodes[i]; efn; efn = efn->next)
+       ret++;
 
    return ret;
 }
@@ -1143,7 +1175,8 @@
    hash = eet_hash_gen(name, ef->header->directory->size);
 
    for (efn = ef->header->directory->nodes[hash]; efn; efn = efn->next)
-     if (eet_string_match(efn->name, name)) return efn;
+     if (eet_string_match(efn->name, name))
+       return efn;
 
    return NULL;
 }
@@ -1151,9 +1184,16 @@
 static int
 read_data_from_disk(Eet_File *ef, Eet_File_Node *efn, void *buf, int len)
 {
-   /* seek to data location */
-   if (fseek(ef->fp, efn->offset, SEEK_SET) < 0) return 0;
-
-   /* read it */
-   return (fread(buf, len, 1, ef->fp) == 1);
+   if (ef->data)
+     memcpy (buf, ef->data + efn->offset, len);
+   else
+     {
+	/* seek to data location */
+	if (fseek(ef->fp, efn->offset, SEEK_SET) < 0)
+	  return 0;
+	
+	/* read it */
+	len = fread(buf, len, 1, ef->fp);
+     }
+   return len;
 }
Index: src/bin/e_thumb.c
===================================================================
RCS file: /var/cvs/e/e17/apps/e/src/bin/e_thumb.c,v
retrieving revision 1.25
diff -u -r1.25 e_thumb.c
--- src/bin/e_thumb.c	2 Mar 2006 12:03:48 -0000	1.25
+++ src/bin/e_thumb.c	31 May 2006 20:34:47 -0000
@@ -557,7 +557,7 @@
 	t = thumb_files->data;
 	if (!e_thumb_exists(t->path))
 	  e_thumb_create(t->path, t->w, t->h);
-	eet_cacheburst(0);
+	eet_clearcache();
 	exit(0);
      }   
 }