001package org.nasdanika.ai;
002
003import reactor.core.publisher.Mono;
004
005/**
006 * Caches image embeddings in a map which can be loaded and saved between runs
007 * Uses image digest as caching key
008 */
009public abstract class CachingEmbeddingGenerator<S,E,K> implements EmbeddingGenerator<S,E> {
010        
011        protected EmbeddingGenerator<S,E> target;
012        
013        /**
014         * Computes caching key from source.
015         * @param source
016         * @return
017         */
018        protected abstract K computeKey(S source);
019        
020        protected abstract E get(K key);
021        
022        protected abstract void put(K key, E value);
023
024        protected CachingEmbeddingGenerator(EmbeddingGenerator<S, E> target) {
025                this.target = target;
026        }
027
028        @Override
029        public Mono<E> generateAsync(S input) {
030                K key = computeKey(input);
031                return Mono
032                        .fromSupplier(() -> get(key))
033                        .switchIfEmpty(target.generateAsync(input).doOnNext(result -> put(key, result)));
034        }
035        
036}