001/*
002 * JDrupes Builder
003 * Copyright (C) 2025 Michael N. Lipp
004 * 
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.builder.core;
020
021import java.util.Map;
022import java.util.concurrent.ConcurrentHashMap;
023import java.util.function.Function;
024import org.jdrupes.builder.api.Resource;
025import org.jdrupes.builder.api.ResourceProvider;
026
027/// An implementation of a cache for [FutureStream]s.
028///
029public class FutureStreamCache {
030
031    private final Map<ProviderInvocation<? extends Resource>,
032            FutureStream<? extends Resource>> cache = new ConcurrentHashMap<>();
033
034    /// Instantiates a new future stream cache.
035    ///
036    /* default */ FutureStreamCache() {
037        // Make javadoc happy
038    }
039
040    /// Compute if absent.
041    ///
042    /// @param <T> the generic type
043    /// @param key the key
044    /// @param supplier the supplier
045    /// @return the future stream
046    ///
047    @SuppressWarnings("unchecked")
048    public <T extends Resource> FutureStream<T> computeIfAbsent(ProviderInvocation<T> key,
049            Function<ProviderInvocation<T>, FutureStream<T>> supplier) {
050        // This is actually type-safe, because the methods for entering
051        // key value pairs allow only values typed according to the casts
052        return (FutureStream<T>) cache.computeIfAbsent(key,
053            (Function<ProviderInvocation<? extends Resource>,
054                    FutureStream<? extends Resource>>) (Object) supplier);
055    }
056
057    /// Purge all values for the given [ResourceProvider].
058    ///
059    /// @param provider the provider
060    ///
061    public void purge(ResourceProvider provider) {
062        cache.forEach((k, _) -> {
063            if (k.provider().equals(provider)) {
064                cache.remove(k);
065            }
066        });
067    }
068
069}