Bug 794804 - part 1 - minimize chrome/worker communication when expiring thumbnails; r=yoric
authorTim Taubert <ttaubert@mozilla.com>
Fri, 28 Sep 2012 10:42:13 +0200
changeset 108500 da72409eda0eb702c82e443abf6906e2b5024fb3
parent 108499 f6a071d71458722174576917416953e926034bbb
child 108501 dd150b8dc4dc864e504887d542be9e9543b1b29b
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersyoric
bugs794804
milestone18.0a1
Bug 794804 - part 1 - minimize chrome/worker communication when expiring thumbnails; r=yoric
browser/components/thumbnails/PageThumbs.jsm
browser/components/thumbnails/PageThumbsWorker.js
--- a/browser/components/thumbnails/PageThumbs.jsm
+++ b/browser/components/thumbnails/PageThumbs.jsm
@@ -441,35 +441,21 @@ let PageThumbsExpiration = {
       if (typeof filter == "function")
         filter(filterCallback)
       else
         filter.filterForThumbnailExpiration(filterCallback);
     }
   },
 
   expireThumbnails: function Expiration_expireThumbnails(aURLsToKeep) {
-    let keep = {};
-
-    // Transform all these URLs into file names.
-    for (let url of aURLsToKeep) {
-      keep[PageThumbsStorage.getLeafNameForURL(url)] = true;
-    }
-
-    let numFilesRemoved = 0;
-    let dir = PageThumbsStorage.getDirectory().path;
-    let msg = {type: "getFilesInDirectory", path: dir};
-
-    PageThumbsWorker.postMessage(msg, function (aData) {
-      let files = [file for (file of aData.result) if (!(file in keep))];
-      let maxFilesToRemove = Math.max(EXPIRATION_MIN_CHUNK_SIZE,
-                                      Math.round(files.length / 2));
-
-      let fileNames = files.slice(0, maxFilesToRemove);
-      let filePaths = [dir + "/" + fileName for (fileName of fileNames)];
-      PageThumbsWorker.postMessage({type: "removeFiles", paths: filePaths});
+    PageThumbsWorker.postMessage({
+      type: "expireFilesInDirectory",
+      minChunkSize: EXPIRATION_MIN_CHUNK_SIZE,
+      path: PageThumbsStorage.getDirectory().path,
+      filesToKeep: [PageThumbsStorage.getLeafNameForURL(url) for (url of aURLsToKeep)]
     });
   }
 };
 
 /**
  * Interface to a dedicated thread handling I/O
  */
 let PageThumbsWorker = {
--- a/browser/components/thumbnails/PageThumbsWorker.js
+++ b/browser/components/thumbnails/PageThumbsWorker.js
@@ -17,60 +17,57 @@ let PageThumbsWorker = {
   handleMessage: function Worker_handleMessage(aEvent) {
     let msg = aEvent.data;
     let data = {result: null, data: null};
 
     switch (msg.type) {
       case "removeFile":
         data.result = this.removeFile(msg);
         break;
-      case "removeFiles":
-        data.result = this.removeFiles(msg);
-        break;
-      case "getFilesInDirectory":
-        data.result = this.getFilesInDirectory(msg);
+      case "expireFilesInDirectory":
+        data.result = this.expireFilesInDirectory(msg);
         break;
       default:
         data.result = false;
         data.detail = "message not understood";
         break;
     }
 
     self.postMessage(data);
   },
 
-  getFilesInDirectory: function Worker_getFilesInDirectory(msg) {
-    let iter = new OS.File.DirectoryIterator(msg.path);
-    let entries = [];
-
-    for (let entry in iter) {
-      if (!entry.isDir && !entry.isSymLink) {
-        entries.push(entry.name);
-      }
-    }
-
-    iter.close();
-    return entries;
-  },
-
   removeFile: function Worker_removeFile(msg) {
     try {
       OS.File.remove(msg.path);
       return true;
     } catch (e) {
       return false;
     }
   },
 
-  removeFiles: function Worker_removeFiles(msg) {
-    for (let file of msg.paths) {
-      try {
-        OS.File.remove(file);
-      } catch (e) {
-        // We couldn't remove the file for some reason.
-        // Let's just continue with the next one.
+  expireFilesInDirectory: function Worker_expireFilesInDirectory(msg) {
+    let entries = this.getFileEntriesInDirectory(msg.path, msg.filesToKeep);
+    let limit = Math.max(msg.minChunkSize, Math.round(entries.length / 2));
+
+    for (let entry of entries) {
+      this.removeFile(entry);
+
+      // Check if we reached the limit of files to remove.
+      if (--limit <= 0) {
+        break;
       }
     }
+
     return true;
+  },
+
+  getFileEntriesInDirectory:
+  function Worker_getFileEntriesInDirectory(aPath, aSkipFiles) {
+    let skip = new Set(aSkipFiles);
+    let iter = new OS.File.DirectoryIterator(aPath);
+
+    return [entry
+            for (entry in iter)
+            if (!entry.isDir && !entry.isSymLink && !skip.has(entry.name))];
   }
 };
 
 self.onmessage = PageThumbsWorker.handleMessage.bind(PageThumbsWorker);