file sorting use case. hard coded paths. little bit of good stuff needs splitting...
[ede] / libede / src / FileSystemCache.ec
index 03920bd..34ec228 100644 (file)
@@ -94,6 +94,8 @@ private:
 class FileSystemCacheBits
 {
    bool indexInodes:1;
+   bool indexByName:1;
+   bool indexBySize:1;
 }
 
 public class DummyFileSystemCacheWindow : Window
@@ -110,9 +112,16 @@ public:
    Array<FSCacheObject> normalParentStack;
    Map<uint, FileSystemDeviceCache> deviceCaches { };
 
+   Map<String, Array<FSCacheObject>> nameIndex { };
+   Map<String, bool> nonSingleNames { };
+   Map<FileSize, Array<FSCacheObject>> sizeIndex { };
+   Map<FileSize, bool> nonSingleSizes { };
+
    property bool indexInodes { set { bits.indexInodes = value; } get { return bits.indexInodes; } };
+   property bool indexByName { set { bits.indexByName = value; } get { return bits.indexByName; } };
+   property bool indexBySize { set { bits.indexBySize = value; } get { return bits.indexBySize; } };
 
-   void/*FileSystemCache*/ ::Cache(char * path, bool indexInodes, DummyFileSystemCacheWindow dummyWindow)
+   void/*FileSystemCache*/ ::Cache(char * path, bool indexInodes, bool indexByName, bool indexBySize, DummyFileSystemCacheWindow dummyWindow)
    {
       FileSystemCache cache = dummyWindow.cache;
       // TOIMP: for now we will assume the cache includes files from a single domain (partition/share)
@@ -122,6 +131,8 @@ public:
       {
          cache = dummyWindow.cache;// = { };
          cache.indexInodes = indexInodes;
+         cache.indexByName = indexByName;
+         cache.indexBySize = indexBySize;
          cache.normalParentStack = { };
          //cache.domainParentStack = { };
          if(pathAttribs.isDirectory)
@@ -136,8 +147,8 @@ public:
                {
                   bool result = true;
                   FileSystemCache cache = this.cache;
-                  uint dev = stats.dev;
-                  uint inode = stats.inode;
+                  uint dev = 0;//stats.dev;
+                  uint inode = 0;//stats.inode;
                   char * p;
                   FSCacheObject parent = isRootObject ? null : cache.normalParentStack.lastIterator.data;
                   FSCacheObject o { parent, name = CopyString(isRootObject ? path : name), stats = stats };
@@ -165,6 +176,7 @@ public:
 #if _DEBUG
                   if(cache.objects.count % 1000 == 0)
                      PrintLn(path, " ----- ", cache.objects.count / 1000, " --------- ", dev);
+#if 0
                   FileGetStatsLink(path, s);
                   if(s.inode != inode)
                   {
@@ -189,19 +201,31 @@ public:
                   }
                   delete p;
 #endif
-                  if(dev && inode && cache.bits.indexInodes)
+#endif
+                  if(!stats.attribs.isDirectory)
                   {
-                     FileSystemDeviceCache devCache = cache.deviceCaches[dev];
-                     if(!devCache)
-                        cache.deviceCaches[dev] = devCache = { };
+                     if(dev && inode && cache.bits.indexInodes)
                      {
-                        Array<FSCacheObject> inodes = devCache.inodes[inode];
-                        if(!inodes)
-                           devCache.inodes[inode] = inodes = { };
-                        else if(inodes.count == 1)
-                           devCache.nonSingleLinks[inode] = true;
-                        inodes.Add(o);
+                        FileSystemDeviceCache devCache = cache.deviceCaches[dev];
+                        if(!devCache)
+                           cache.deviceCaches[dev] = devCache = { };
+                        {
+                           Array<FSCacheObject> files = devCache.inodes[inode];
+                           if(!files)
+                           {
+                              devCache.inodes[inode] = files = { };
+                              if(cache.bits.indexBySize)
+                                 CacheAddFileToIndexBySize(cache, o, stats.size);
+                           }
+                           else if(files.count == 1)
+                              devCache.nonSingleLinks[inode] = true;
+                           files.Add(o);
+                        }
                      }
+                     else if(cache.bits.indexBySize)
+                        CacheAddFileToIndexBySize(cache, o, stats.size);
+                     if(cache.bits.indexByName)
+                        CacheAddFileToIndexByName(cache, o, name);
                   }
                   return result;
                }
@@ -307,6 +331,7 @@ public:
 
    Map<uint, Map<uint, bool>> devsInodesDone { };
    Map<String, bool> linksPaths { };
+#if 0
    void Special(char * path/*, Map<String, bool> linksPaths*//*Map<uint, Map<uint, bool>> devsInodesDone*/, DummyFileSystemCacheWindow dummyWindow)
    {
       FileSystemCacheIterator fsci { owner = dummyWindow, cache = this, iterateStartPath = true;
@@ -364,10 +389,41 @@ public:
       MapNode<String, bool> mn;
       PrintLn(" -------------------------------------------- Special -------------------------------------------- ");
       PrintLn(" ------------------------------------------------------------------------------------------------- ");
-      for(mn = linksPaths.root.minimum; mn; mn = mn.next)
+      if(linksPaths.count)
+      {
+         for(mn = linksPaths.root.minimum; mn; mn = mn.next)
+         {
+            PrintLn(mn.key);
+         }
+      }
+      else
+         PrintLn("   no hard linked files");
+      PrintLn(" ------------------------------------------------------------------------------------------------- ");
+   }
+#endif
+   void Special(char * path/*, Map<String, bool> linksPaths*//*Map<uint, Map<uint, bool>> devsInodesDone*/, DummyFileSystemCacheWindow dummyWindow)
+   {
+   }
+   void SpecialPrint()
+   {
+      MapNode<FileSize, bool> mn;
+      PrintLn(" -------------------------------------------- Special -------------------------------------------- ");
+      PrintLn(" ------------------------------------------------------------------------------------------------- ");
+      if(nonSingleSizes.count)
       {
-         PrintLn(mn.key);
+         for(mn = nonSingleSizes.root.minimum; mn; mn = mn.next)
+         {
+            Array<FSCacheObject> files = sizeIndex[mn.key];
+            PrintLn("     size: ", mn.value, "# of files: ", files.count);
+            for(o : files)
+            {
+               char * p = o.GetPath();
+               PrintLn(p);
+               delete p;
+            }
+         }
       }
+      PrintLn(" ------------------------------------------------------------------------------------------------- ");
    }
 
 private:
@@ -378,8 +434,30 @@ private:
       objects.Free();
       delete objects;
    }
+
+}
+
+static inline void CacheAddFileToIndexBySize(FileSystemCache cache, FSCacheObject o, FileSize size)
+{
+   Array<FSCacheObject> files = cache.sizeIndex[size];
+   if(!files)
+      cache.sizeIndex[size] = files = { };
+   else if(files.count == 1)
+      cache.nonSingleSizes[size] = true;
+   files.Add(o);
 }
 
+static inline void CacheAddFileToIndexByName(FileSystemCache cache, FSCacheObject o, char * name)
+{
+   Array<FSCacheObject> files = cache.nameIndex[name];
+   if(!files)
+      cache.nameIndex[name] = files = { };
+   else if(files.count == 1)
+      cache.nonSingleNames[name] = true;
+   files.Add(o);
+}
+
+
 public class FileSystemDeviceCache : struct
 {
 public: