package p.studio.compiler.source.tables;

import p.studio.compiler.source.identifiers.SourceIdentifier;

import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;

public abstract class InternTable<IDENTIFIER extends SourceIdentifier, VALUE>
        extends DenseTable<IDENTIFIER, VALUE>
        implements InternTableReader<IDENTIFIER, VALUE> {

    private final Map<VALUE, IDENTIFIER> identifierByValue = new HashMap<>();

    public InternTable(final Function<Integer, IDENTIFIER> identifierGenerator) {
        super(identifierGenerator);
    }

    @Override
    public IDENTIFIER register(final VALUE value) {
        return identifierByValue.computeIfAbsent(value, super::register);
    }

    @Override
    public void clear() {
        super.clear();
        identifierByValue.clear();
    }

    @Override
    public Optional<IDENTIFIER> optional(final VALUE value) {
        return Optional.ofNullable(identifierByValue.get(value));
    }

    @Override
    public boolean containsKey(final VALUE value) {
        return identifierByValue.containsKey(value);
    }
}
