perf(catalog): precompute search blob and tag count at build (P2)
ober
78aca23d3edd93215836ea3ea5c9c3b4803769a2
--- a/src/imagesite/catalog.ss +++ b/src/imagesite/catalog.ss @@ -37,6 +37,17 @@ (reverse out) (loop (cdr rest) (- n 1) (cons (car rest) out))))) +;; Downcased search haystack for a media item, computed once at build time so +;; searching does not rebuild and downcase it per media per query. +(def (build-search-blob title caption rel-path tags) + (string-downcase-safe + (string-append + title " " caption " " rel-path " " + (let loop ((tags tags) (out "")) + (if (null? tags) + out + (loop (cdr tags) (string-append out " " (car tags)))))))) + (def (walk-media-root root hidden-media proc) (secure-walk-media-root root @@ -97,7 +108,9 @@ (cons "width" #f) (cons "height" #f) (cons "taken_at" #f) - (cons "favorite" 0))))) + (cons "favorite" 0) + (cons "search_blob" + (build-search-blob (media-title rel) caption rel tags)))))) (set! next-id (+ next-id 1)) (hash-put! album-counts album-path (+ 1 (if (hash-key? album-counts album-path) @@ -148,10 +161,11 @@ (cons "media_by_id" media-by-id) (cons "media_by_path" media-by-path) (cons "media_by_album" media-by-album) - (cons "media_count" (length media-list)) - (cons "album_count" (length albums))))))) + (cons "media_count" (length media-list)) + (cons "tag_count" (count-distinct-tags media-list)) + (cons "album_count" (length albums))))))) -(def (tag-count catalog) +(def (count-distinct-tags media-list) (let ((seen (make-hash-table))) (for-each (lambda (media) @@ -160,9 +174,12 @@ (when (string? tag) (hash-put! seen (string-downcase-safe tag) #t))) (h media "tags" '()))) - (h catalog "media" '())) + media-list) (hash-length seen))) +(def (tag-count catalog) + (h catalog "tag_count" 0)) + (def (catalog-counts catalog) (object (list @@ -199,16 +216,7 @@ (and by-path (hash-key? by-path rel-path) (hash-get by-path rel-path)))) (def (catalog-match? media needle) - (let ((haystack (string-downcase-safe - (string-append - (h media "title" "") " " - (h media "caption" "") " " - (h media "rel_path" "") " " - (let loop ((tags (h media "tags" '())) (out "")) - (if (null? tags) - out - (loop (cdr tags) (string-append out " " (car tags))))))))) - (string-contains? haystack needle))) + (string-contains? (h media "search_blob" "") needle)) (def (media-tag-match? media needle) (let loop ((tags (h media "tags" '())))