emacs-elpa-diffs
[Top][All Lists]
Advanced

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

[nongnu] elpa/hyperdrive e73e941ecc 4/5: Change: Use full metadata direc


From: ELPA Syncer
Subject: [nongnu] elpa/hyperdrive e73e941ecc 4/5: Change: Use full metadata directory listings for faster directory UI
Date: Wed, 15 May 2024 01:01:22 -0400 (EDT)

branch: elpa/hyperdrive
commit e73e941eccba946511a13a1bed16e874897e18e3
Author: Joseph Turner <joseph@ushin.org>
Commit: Joseph Turner <joseph@ushin.org>

    Change: Use full metadata directory listings for faster directory UI
---
 hyperdrive-dir.el | 124 +++++++++++++++++++++---------------------------------
 hyperdrive-lib.el |  22 ++++++++++
 2 files changed, 69 insertions(+), 77 deletions(-)

diff --git a/hyperdrive-dir.el b/hyperdrive-dir.el
index ff1d2ba73e..226edd4c02 100644
--- a/hyperdrive-dir.el
+++ b/hyperdrive-dir.el
@@ -38,86 +38,56 @@
   "Show DIRECTORY-ENTRY.
 If THEN, call it in the directory buffer with no arguments."
   ;; NOTE: ENTRY is not necessarily "filled" yet.
-  (pcase-let* (((cl-struct hyperdrive-entry hyperdrive path version) 
directory-entry)
-               (url (he/url directory-entry))
-               ((cl-struct plz-response headers body)
-                ;; SOMEDAY: Consider updating plz to optionally not stringify 
the body.
-                (h/api 'get url :as 'response :noquery t))
-               (entry-names (json-read-from-string body))
-               (entries (mapcar (lambda (entry-name)
-                                  (he/create
-                                   :hyperdrive hyperdrive
-                                   :path (concat path entry-name)
-                                   :version version))
-                                entry-names))
-               (parent-entry (h/parent directory-entry))
-               (header (progn
-                         ;; Fill metadata first to get the current nickname.
-                         ;; TODO: Consider filling metadata earlier, outside
-                         ;; of this function (e.g. so it will be available if
-                         ;; the user loads a non-directory file directly).
-                         (h/fill-metadata hyperdrive)
-                         (h/dir-column-headers
-                          (h//format-entry directory-entry))))
-               (num-entries (length entries)) (num-filled 0)
-              ;; (debug-start-time (current-time))
-               (metadata-queue) (ewoc) (prev-entry) (prev-point))
+  (pcase-let*
+      (((cl-struct hyperdrive-entry hyperdrive path version) directory-entry)
+       (url (he/url directory-entry))
+       (header (progn
+                 ;; Fill metadata first to get the current nickname.
+                 ;; TODO: Consider filling metadata earlier, outside
+                 ;; of this function (e.g.  so it will be available if
+                 ;; the user loads a non-directory file directly).
+                 (h/fill-metadata hyperdrive)
+                 (h/dir-column-headers
+                  (h//format-entry directory-entry))))
+       (prev-entry) (prev-point))
+    (with-current-buffer (h//get-buffer-create directory-entry)
+      (h/dir-mode)
+      (with-silent-modifications
+        (unless h/ewoc
+          (setf h/ewoc (ewoc-create #'h/dir-pp)))
+        (setf prev-entry (h/dir--entry-at-point))
+        (setf prev-point (point))
+        (ewoc-filter h/ewoc #'ignore)
+        (ewoc-set-hf h/ewoc header "Loading...")))
     (cl-labels ((goto-entry (entry ewoc)
                   (when-let ((node (h/ewoc-find-node ewoc entry
                                      :predicate #'he/equal-p)))
-                    (goto-char (ewoc-location node))))
-                (update-footer (num-filled num-of)
-                  (when (zerop (mod num-filled 5))
-                    (ewoc-set-hf ewoc header
-                                 (propertize
-                                  (format "Loading (%s/%s)..." num-filled 
num-of)
-                                 'face 'font-lock-comment-face)))))
-      (setf directory-entry (h//fill directory-entry headers))
-      (when parent-entry
-        (setf (alist-get 'display-name (he/etc parent-entry))  "../")
-        (push parent-entry entries))
-      (with-current-buffer (h//get-buffer-create directory-entry)
-        (h/dir-mode)
-        (with-silent-modifications
-          (setf ewoc (or h/ewoc ; Bind this for lambdas.
-                         (setf h/ewoc (ewoc-create #'h/dir-pp))))
-          (setf metadata-queue
-                (make-plz-queue
-                ;; Experimentation seems to show that a
-                ;; queue size of about 20 performs best.
-                 :limit h/queue-limit
-                 :finally (lambda ()
-                            (with-current-buffer (ewoc-buffer ewoc)
-                              (with-silent-modifications
-                                ;; `with-silent-modifications' increases 
performance,
-                                ;; but we still need `set-buffer-modified-p' 
below.
-                                (ewoc-set-hf ewoc header "")
-                                (setf entries (h/sort-entries entries))
-                                (dolist (entry entries)
-                                  (ewoc-enter-last ewoc entry))
-                                (or (when prev-entry
-                                      (goto-entry prev-entry ewoc))
-                                    (goto-char prev-point)))
-                              (set-buffer-modified-p nil))
-                            ;; TODO: Remove this and the commented out 
`debug-start-time'
-                            ;; binding when we're done experimenting.
-                            ;; (message "Elapsed: %s"
-                            ;;          (float-time (time-subtract
-                            ;;                       (current-time)
-                            ;;                       debug-start-time)))
-                            )))
-          (setf prev-entry (and-let* ((node (ewoc-locate h/ewoc)))
-                             (ewoc-data node)))
-          (setf prev-point (point))
-          (ewoc-filter h/ewoc #'ignore)
-          (update-footer num-filled num-entries)
-          (dolist (entry entries)
-            (h/fill entry :queue metadata-queue
-              :then (lambda (&rest _)
-                      (update-footer (cl-incf num-filled) num-entries))))
-          (plz-run metadata-queue)
-          (when then
-            (funcall then)))))))
+                    (goto-char (ewoc-location node)))))
+      (h/api 'get url :as 'response :noquery t
+        ;; Get "full" listing with metadata
+        :headers `(("Accept" . "application/json; metadata=full"))
+        :then (lambda (response)
+                (pcase-let* (((cl-struct plz-response headers body) response)
+                             (entries (h//fill-listing-entries
+                                       ;; SOMEDAY: Consider updating plz to 
optionally not stringify the body.
+                                       (json-read-from-string body)
+                                       hyperdrive version))
+                             (parent-entry (h/parent directory-entry)))
+                  (setf directory-entry (h//fill directory-entry headers))
+                  (when parent-entry
+                    (setf (alist-get 'display-name (he/etc parent-entry)) 
"../")
+                    (push parent-entry entries))
+                  (with-current-buffer (h//get-buffer-create directory-entry)
+                    (with-silent-modifications
+                      (ewoc-set-hf h/ewoc header "")
+                      (setf entries (h/sort-entries entries))
+                      (dolist (entry entries)
+                        (ewoc-enter-last h/ewoc entry))
+                      (or (when prev-entry
+                            (goto-entry prev-entry h/ewoc))
+                          (goto-char prev-point)))
+                    (when then
+                      (funcall then)))))))))
 
 (defun h/dir-column-headers (prefix)
   "Return column headers as a string with PREFIX.
diff --git a/hyperdrive-lib.el b/hyperdrive-lib.el
index e23e036c9a..a2c50dc0c0 100644
--- a/hyperdrive-lib.el
+++ b/hyperdrive-lib.el
@@ -701,6 +701,28 @@ Returns filled ENTRY."
       (h/update-existent-version-range entry (string-to-number etag)))
     entry))
 
+(defun h//fill-listing-entries (listing hyperdrive version)
+  "Return entries list with metadata from LISTING.
+Accepts HYPERDRIVE and VERSION of parent entry as arguments.
+LISTING should be an alist based on the JSON retrieved in, e.g.,
+`hyperdrive-dir-handler'.  Fills existent version ranges for each
+entry as a side-effect."
+  (mapcar
+   (pcase-lambda ((map seq key value metadata))
+     (let* ((mtime (map-elt (map-elt value 'metadata) 'mtime))
+            (size (map-elt (map-elt value 'blob) 'byteLength))
+            (entry (he/create
+                    :hyperdrive hyperdrive :path key :version version)))
+       (when mtime ; mtime is milliseconds since epoch
+         (setf (he/mtime entry) (seconds-to-time (/ mtime 1000.0))))
+       (when size
+         (setf (he/size entry) size))
+       (when seq
+         ;; seq is the hyperdrive version *before* the entry was added/modified
+         (hyperdrive-update-existent-version-range entry (1+ seq)))
+       entry))
+   listing))
+
 (defun h/fill-latest-version (hyperdrive)
   "Synchronously fill the latest version slot in HYPERDRIVE.
 Returns the latest version number."



reply via email to

[Prev in Thread] Current Thread [Next in Thread]