loop/scripts/build-index-from-fs.lisp

61 lines
3.5 KiB
Common Lisp

#-quicklisp
(let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
(user-homedir-pathname))))
(when (probe-file quicklisp-init)
(load quicklisp-init)))
(ql:quickload :loop :silent t)
(in-package #:loop)
(defun index-from-fs! ()
(loop for path in (in-groups (directory "**/*"))
do (let* ((g (str:trim (first (last (pathname-directory path)))))
(i (str:trim (pathname-name path)))
(m (ignore-errors (str:trim (extract-mid (fetch-article g i))))))
(when (and m (> (length m) 0))
(let* ((hash (index-hash m))
(idx-path (index-path hash)))
(ensure-index-directories! hash)
;; If index file exists, verify if it shares our inode. If not, force-link it.
(cond
((probe-file idx-path)
(unless (= (handler-case (sb-posix:stat-ino (sb-posix:stat (uiop:native-namestring path)))
(sb-posix:syscall-error () 0))
(handler-case (sb-posix:stat-ino (sb-posix:stat (uiop:native-namestring idx-path)))
(sb-posix:syscall-error () -1)))
;; Overwrite stale/mismatched index entry with the correct hard link
(ignore-errors (delete-file idx-path))
(sb-posix:link (uiop:native-namestring path) idx-path)
(format t "article ~a/~a force-linked to index ~a~%" g i hash)))
(t
(handler-case
(progn
(sb-posix:link (uiop:native-namestring path) idx-path)
(format t "article ~a/~a indexed by ~a hash ~a~%" g i m hash))
(sb-posix:syscall-error (c)
(if (= (sb-posix:syscall-errno c) sb-posix:eexist)
(format t "article ~a/~a already indexed concurrently.~%" g i)
(error c)))))))))))
(defun index-from-fs!-old ()
(loop for path in (in-groups (directory "**/*"))
do (let* ((g (str:trim (first (last (pathname-directory path)))))
(i (str:trim (pathname-name path)))
(m (ignore-errors (str:trim (extract-mid (fetch-article g i))))))
(when (and m (> (length m) 0))
(let* ((hash (index-hash m))
(idx-path (index-path hash)))
(if (probe-file idx-path) ;; article exists in index: unify inodes by re-linking group file to index
(unless (= (get-file-inode path) (get-file-inode idx-path))
(delete-file path)
(sb-posix:link (uiop:native-namestring idx-path) (uiop:native-namestring path))
(format t "article ~a/~a relinked-to-existing-index ~a~%" g i hash))
(progn
(ensure-index-directories! hash)
(handler-case
(progn
(sb-posix:link (uiop:native-namestring path) idx-path)
(format t "article ~a/~a mid ~a hashes-to ~a~%" g i m hash))
(sb-posix:syscall-error (c)
(if (= (sb-posix:syscall-errno c) sb-posix:eexist)
(format t "article ~a/~a indexed due to a cross-post? EEXIST.~%" g i)
(error c)))))))))))
(index-from-fs!)