This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository efm2.

View the commit online.

commit d63929b3f7b395a3e40e4a7a740a2dbadd15426a
Author: Carsten Haitzler (Rasterman) <[email protected]>
AuthorDate: Wed May 13 17:19:00 2026 +0100

    dir stash - a quick faster way to aoid stats on a filesystem
    
    dir stast stashes a dir listing (of the meta .efm dir in the dir) to
    avoid statting of even trying to open files we are pretty sure are not
    there.
    
    use from meta code and open code checking for rename files for rename
    mode
---
 src/backends/default/meson.build |   6 ++
 src/backends/default/meta.c      |  11 ++--
 src/backends/default/open.c      |  14 +++--
 src/backends/default/stash.c     | 130 +++++++++++++++++++++++++++++++++++++++
 src/backends/default/stash.h     |   9 +++
 5 files changed, 161 insertions(+), 9 deletions(-)

diff --git a/src/backends/default/meson.build b/src/backends/default/meson.build
index 6bd0af2..a940223 100644
--- a/src/backends/default/meson.build
+++ b/src/backends/default/meson.build
@@ -18,6 +18,7 @@ executable('open', [
     'fs.c',
     'status.c',
     'typebuf.c',
+    'stash.c',
   ],
   include_directories: inc,
   dependencies: deps,
@@ -48,6 +49,7 @@ executable('mv', [
     'fs.c',
     'mv.c',
     'meta.c',
+    'stash.c',
     'status.c'
   ],
   include_directories: inc,
@@ -61,6 +63,7 @@ executable('cp', [
     'fs.c',
     'cp.c',
     'meta.c',
+    'stash.c',
     'status.c'
   ],
   include_directories: inc,
@@ -74,6 +77,7 @@ executable('ln', [
     'fs.c',
     'ln.c',
     'meta.c',
+    'stash.c',
     'status.c'
   ],
   include_directories: inc,
@@ -87,6 +91,7 @@ executable('rm', [
     'fs.c',
     'rm.c',
     'meta.c',
+    'stash.c',
     'status.c'
   ],
   include_directories: inc,
@@ -100,6 +105,7 @@ executable('trash', [
     'fs.c',
     'trash.c',
     'meta.c',
+    'stash.c',
     'status.c'
   ],
   include_directories: inc,
diff --git a/src/backends/default/meta.c b/src/backends/default/meta.c
index 614ad29..23f0bf8 100644
--- a/src/backends/default/meta.c
+++ b/src/backends/default/meta.c
@@ -8,6 +8,7 @@
 #include "sha.h"
 #include "meta.h"
 #include "util.h"
+#include "stash.h"
 
 // This is a metadata store to store added metadata for any given file path.
 // For example store the x,y location of a file, added comments, flags a user
@@ -354,7 +355,7 @@ _meta_file_find(const char *path)
 {
   Util_Modtime  mt;
   Meta_File    *mf;
-  Efreet_Ini   *ini;
+  Efreet_Ini   *ini = NULL;
   char         *meta_path;
 
   // find existing in memory meta file data and return that
@@ -371,14 +372,14 @@ _meta_file_find(const char *path)
   meta_path = _meta_file_get(mf);
   if (!meta_path) goto err;
 
-  ini = efreet_ini_new(meta_path);
+  if (stash_file_exists(meta_path)) ini = efreet_ini_new(meta_path);
   if (ini)
     {
       if ((ini->data) && (efreet_ini_section_set(ini, "Efm Meta")))
         eina_hash_foreach(ini->section, _cb_meta_desktop_x_foreach, mf);
       efreet_ini_free(ini);
+      mf->modtime = util_file_modtime_get(meta_path);
     }
-  mf->modtime = util_file_modtime_get(meta_path);
   free(meta_path);
 
   // load overlayed user metdata and modify meta file content based on it
@@ -437,10 +438,10 @@ static void
 _meta_file_sync(Meta_File *mf)
 {
   char *meta_path = _meta_file_get(mf);
-  Efreet_Ini *ini;
+  Efreet_Ini *ini = NULL;
 
   if (!meta_path) return;
-  ini = efreet_ini_new(meta_path);
+  if (stash_file_exists(meta_path)) ini = efreet_ini_new(meta_path);
   if (ini)
     {
       if ((ini->data) && (efreet_ini_section_set(ini, "Efm Meta")))
diff --git a/src/backends/default/open.c b/src/backends/default/open.c
index 2c33388..51fe229 100644
--- a/src/backends/default/open.c
+++ b/src/backends/default/open.c
@@ -7,6 +7,7 @@
 // itself at all and do everything via fs handlers for open, delete, rename
 // copy, import, export etc.
 #include "open.h"
+#include "stash.h"
 
 typedef struct
 {
@@ -1187,10 +1188,10 @@ _file_add(const char *path)
 
       if ((strbuf2) && (dir) && (fname))
         {
-          eina_strbuf_append_printf(strbuf2,
-                                    "%s/" EFM_DIR "/%s." EFM_RENAME_ME_EXT, dir,
-                                    fname);
-          if (ecore_file_exists(eina_strbuf_string_get(strbuf2)))
+          eina_strbuf_append_printf(
+            strbuf2, "%s/" EFM_DIR "/%s." EFM_RENAME_ME_EXT, dir, fname);
+          if ((stash_file_exists(eina_strbuf_string_get(strbuf2)))
+              && (ecore_file_exists(eina_strbuf_string_get(strbuf2))))
             {
               fprintf(stderr, "JJJ: [%s] exists...\n",
                       eina_strbuf_string_get(strbuf2));
@@ -1329,6 +1330,10 @@ _monitor(const char *path)
   strbuf = cmd_strbuf_new("list-begin");
   cmd_strbuf_print_consume(strbuf);
 
+  strbuf = eina_strbuf_new();
+  eina_strbuf_append(strbuf, path);
+  eina_strbuf_append(strbuf, EFM_DIR);
+  stash_dir_add(eina_strbuf_string_get(strbuf));
   _order_load(path);
   mon = ecore_file_monitor_add(path, _cb_mon, NULL);
   it  = eina_file_direct_ls(path);
@@ -1339,6 +1344,7 @@ _monitor(const char *path)
     }
   EINA_ITERATOR_FOREACH(it, info) _file_add(info->path);
   eina_iterator_free(it);
+  stash_dir_del(eina_strbuf_string_get(strbuf));
 err:
   // tell the front end our listing is done
   strbuf = cmd_strbuf_new("list-end");
diff --git a/src/backends/default/stash.c b/src/backends/default/stash.c
new file mode 100644
index 0000000..063c2d4
--- /dev/null
+++ b/src/backends/default/stash.c
@@ -0,0 +1,130 @@
+#include <Eina.h>
+#include <Ecore_File.h>
+#include "stash.h"
+
+// this is a "cache" of a file listing of dirs to temporarily store to know
+// if a file is known to exists or not in the listing. it is not necessarily
+// true as it's a cache, so if it says it does exist a following open or file
+// access may fail. this is intended to be used by the meta and other .efm dir
+// to speed up i/o by doing less of it for cases where the filesystem may
+// be slow (eg fuse remote like sshfs). so pre-cache a dir of files when
+// beginning a file listing then delete it when listing is done. during
+// listing of the dir check the stash cache to see if a file does exist or
+// not int he listing. if it doesn't then probably avoid the following attempts
+// to open/load the file as it didn't exist when the stash dir was added and
+// it listed the dir.
+
+typedef struct _Stash
+{
+  Eina_Stringshare *dir;
+  Eina_Hash *files;
+} Stash;
+
+static Eina_Hash *_stash_dirs = NULL;
+
+static void
+_stash_free(Stash *stash)
+{
+  if (stash->dir) eina_stringshare_del(stash->dir);
+  if (stash->files) eina_hash_free(stash->files);
+  free(stash);
+}
+
+// add a dir and itslisting to our stash - if it's there already, update
+// the listing at this point
+void
+stash_dir_add(const char *dir)
+{
+  Eina_Iterator *it;
+  Eina_File_Direct_Info *info;
+  Stash *stash;
+
+  it = eina_file_direct_ls(dir);
+  if (!it) return;
+  stash = eina_hash_find(_stash_dirs, dir);
+  if (!stash)
+    { // doesn't exist yet - create it
+      stash = calloc(1, sizeof(Stash));
+      if (!stash) goto done; // stash alloc failed
+      stash->dir = eina_stringshare_add(dir);
+      if (!stash->dir)
+        { // couldnt store dir path
+          _stash_free(stash);
+          goto done;
+        }
+      stash->files = eina_hash_string_superfast_new(NULL);
+      if (!stash->files)
+        { // couldnt create hash of filenames in dir
+          _stash_free(stash);
+          goto done;
+        }
+      if (!_stash_dirs) _stash_dirs = eina_hash_string_superfast_new(NULL);
+      if (!_stash_dirs)
+        {
+          _stash_free(stash);
+          goto done;
+        }
+      if (!eina_hash_add(_stash_dirs, dir, stash))
+        { // couldnt register stash with our dir hash
+          _stash_free(stash);
+          goto done;
+        }
+    }
+  else
+    { // exists - update it - nuke hash/listing and add back
+      if (stash->files) eina_hash_free(stash->files);
+      stash->files = eina_hash_string_superfast_new(NULL);
+      if (!stash->files)
+        { // couldnt create new empty hash - remove stash
+          eina_hash_del(_stash_dirs, dir, stash);
+          _stash_free(stash);
+          goto done;
+        }
+    }
+  EINA_ITERATOR_FOREACH(it, info)
+  { // walk over dir and add entries per file found
+    const char *file = info->path + info->name_start;
+
+    // just flag the file as existing with a ptr of the stash itself
+    eina_hash_add(stash->files, file, stash);
+  }
+  done:
+  eina_iterator_free(it);
+}
+
+void
+stash_dir_del(const char *dir)
+{
+  Stash *stash;
+
+  if (!_stash_dirs) return;
+  stash = eina_hash_find(_stash_dirs, dir);
+  if (!stash) return; // couldnt find it - return
+  eina_hash_del(_stash_dirs, dir, stash);
+  _stash_free(stash);
+  if (eina_hash_population(_stash_dirs) == 0)
+    {
+      eina_hash_free(_stash_dirs);
+      _stash_dirs = NULL;
+    }
+}
+
+Eina_Bool
+stash_file_exists(const char *path)
+{ // does a file path exist in a stash
+  char *dir = ecore_file_dir_get(path);
+  Stash *stash;
+
+  // conservative - assume it exists if dir alloc fails
+  if (!dir) goto yes;
+  // do we have a stash for this dir?
+  stash = eina_hash_find(_stash_dirs, dir);
+  free(dir); // don't need dir anymore
+  if (!stash) goto yes; // no stash found for dir - conservative ret
+  // so we've found a stash where it SHOULD live. if it doesn't then return
+  // false - but if found - conservatively assume it does
+  if (eina_hash_find(stash->files, ecore_file_file_get(path))) goto yes;
+  return EINA_FALSE;
+  yes:
+  return EINA_TRUE;
+}
diff --git a/src/backends/default/stash.h b/src/backends/default/stash.h
new file mode 100644
index 0000000..86ba1eb
--- /dev/null
+++ b/src/backends/default/stash.h
@@ -0,0 +1,9 @@
+#ifndef STASH_H
+#define STASH_H
+#include <Eina.h>
+
+void      stash_dir_add(const char *dir);
+void      stash_dir_del(const char *dir);
+Eina_Bool stash_file_exists(const char *path);
+
+#endif
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to