001package de.monochromata.anaphors.cog.memory;
002
003import static java.util.stream.Collectors.toList;
004
005import java.util.Collection;
006import java.util.LinkedHashSet;
007
008import de.monochromata.anaphors.cog.activation.ActivationFormula;
009
010/**
011 * TODO: The size of the list should be limited
012 *
013 * @param <T> The type of objects that the chunks in this memory can represents.
014 * @since 1.1.0
015 */
016public class SortedListMemory<T> implements Memory<T>, ModifiableMemory<T> {
017
018    private final ActivationFormula activationFormula;
019    private final LinkedHashSet<Chunk<T>> chunks;
020
021    /**
022     * Used in contract testing.
023     */
024    @SuppressWarnings("unused")
025    protected SortedListMemory() {
026        this(null, null);
027    }
028
029    /**
030     * Create a sorted set memory that sorts values based on the activation at the
031     * time when {@link #getChunks(long, int)} is invoked.
032     *
033     * @see ActivationFormula#comparatorForActivationAt(long)
034     */
035    public SortedListMemory(final ActivationFormula activationFormula) {
036        this(activationFormula, new LinkedHashSet<>());
037    }
038
039    public SortedListMemory(final ActivationFormula activationFormula, final LinkedHashSet<Chunk<T>> chunks) {
040        this.activationFormula = activationFormula;
041        this.chunks = chunks;
042    }
043
044    @Override
045    public void add(final long timestamp, final Chunk<T> chunk) {
046        // compute initial activation
047        chunk.getEstimatedActivationValue(timestamp);
048        this.chunks.add(chunk);
049    }
050
051    @Override
052    public void addAll(final long timestamp, final Collection<Chunk<T>> chunks) {
053        chunks.forEach(chunk -> add(timestamp, chunk));
054    }
055
056    @Override
057    public Collection<Chunk<T>> getChunks(final long timestamp, final int maximumCount) {
058        return chunks.stream().sorted(activationFormula.comparatorForActivationAt(timestamp)).limit(maximumCount)
059                .collect(toList());
060    }
061
062}