aboutsummaryrefslogtreecommitdiffhomepage
path: root/org
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2026-08-26 22:53:30 -0400
committerRalph Amissah <ralph.amissah@gmail.com>2026-08-28 10:02:05 -0400
commita4ef474cabc4113c3dca72bf08bc477c452c624c (patch)
tree0252d8156789e55c63dfb0b210d5da52552d766d /org
parent.ssp digest: add image file's own pixel dimensions (diff)
image digest: single read, cache file read & hash
For image digests cache file read & hash, one read per image file Fix issue: images referenced from several objects were read and hashed once per reference. [as an example in the sisu-manual sm_tux.png accounts for 6 of the document's image records (12 across the sample set), each of them a fresh read of the same bytes, and source_pod.d hashes the file again for digests.txt.] Memoise on the full path within safeComputeHashAndSize. static is thread-local in D, so documents processed in parallel each get their own cache and no synchronisation is involved. Files are not expected to change during a run. Output is unchanged: identical .ssp output. (An image that is missing or unreadable now warns once to stdout rather than once per reference). (assisted by Claude-Code)
Diffstat (limited to 'org')
-rw-r--r--org/ocda_functions.org12
-rw-r--r--org/out_src_abstraction_ocda_ssp.org1
2 files changed, 11 insertions, 2 deletions
diff --git a/org/ocda_functions.org b/org/ocda_functions.org
index 71d1b97..0e42cfb 100644
--- a/org/ocda_functions.org
+++ b/org/ocda_functions.org
@@ -3430,7 +3430,16 @@ SHA_256_Hashes_ obj_digest(M)(
M manifested,
) {
ST_file_name_hash_size_ safeComputeHashAndSize(N,P)(N filename, P file_path) @trusted {
- auto file_with_path = file_path ~ filename;
+ string file_with_path = (file_path ~ filename).to!string;
+ /+ ↓ read & hash each image file once: an image referenced from several
+ objects (or from several documents sharing an image directory) was
+ otherwise re-read and re-hashed for every reference. static is
+ thread-local in D, so the cache needs no synchronisation
+ +/
+ static ST_file_name_hash_size_[string] _image_file_info_cache;
+ if (auto _cached = file_with_path in _image_file_info_cache) {
+ return *_cached;
+ }
ST_file_name_hash_size_ _file_info;
_file_info.fileName = filename;
/+ ↓ a referenced image that is absent or unreadable is recorded as
@@ -3466,6 +3475,7 @@ SHA_256_Hashes_ obj_digest(M)(
}
}
}
+ _image_file_info_cache[file_with_path] = _file_info;
return _file_info;
}
obj.metainfo.sha256.text = obj.text.sha256Of;
diff --git a/org/out_src_abstraction_ocda_ssp.org b/org/out_src_abstraction_ocda_ssp.org
index 64af5cc..a14773e 100644
--- a/org/out_src_abstraction_ocda_ssp.org
+++ b/org/out_src_abstraction_ocda_ssp.org
@@ -283,7 +283,6 @@ template spineAbstractionTxt() {
~ " missing:true"
: ".image: " ~ i.fileName
~ " sha256:" ~ i.fileHash_sha256.toHexString.to!string
- ~ " sha256:" ~ i.fileHash_sha256.toHexString.to!string
~ " bytes:" ~ i.fileSize.to!string
~ ((i.imageWidth > 0 && i.imageHeight > 0)
? " px:" ~ i.imageWidth.to!string