All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jparams.store.AbstractStore Maven / Gradle / Ivy

There is a newer version: 3.1.4
Show newest version
package com.jparams.store;

import java.util.AbstractCollection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import com.jparams.store.index.Index;
import com.jparams.store.index.IndexDefinition;
import com.jparams.store.index.IndexException;
import com.jparams.store.index.IndexManager;
import com.jparams.store.query.IndexMatch;
import com.jparams.store.query.Operator;
import com.jparams.store.query.Query;
import com.jparams.store.query.QueryDefinition;
import com.jparams.store.reference.Reference;
import com.jparams.store.reference.ReferenceManager;

public abstract class AbstractStore extends AbstractCollection implements Store
{
    private final ReferenceManager referenceManager;
    private final IndexManager indexManager;

    protected AbstractStore(final ReferenceManager referenceManager, final IndexManager indexManager)
    {
        this.referenceManager = referenceManager;
        this.indexManager = indexManager;
    }

    @Override
    public List get(final Query query, final Integer limit)
    {
        final QueryDefinition definition = query.build();
        final List indexMatches = definition.getIndexMatches();
        final Operator operator = definition.getOperator();
        final Set> results = new LinkedHashSet<>();

        boolean firstMatch = true;

        for (final IndexMatch indexMatch : indexMatches)
        {
            final Set> references = Optional.ofNullable(indexManager.getIndex(indexMatch.getIndexName()))
                                                         .map(index -> index.getReferences(indexMatch.getKey()))
                                                         .orElse(Collections.emptySet());

            if (firstMatch || operator == Operator.OR)
            {
                results.addAll(references);
                firstMatch = false;
            }
            else
            {
                results.retainAll(references);
            }
        }

        return results.stream()
                      .map(Reference::get)
                      .limit(limit == null ? Long.MAX_VALUE : limit)
                      .collect(Collectors.toList());
    }

    @Override
    public  Index index(final String indexName, final IndexDefinition indexDefinition) throws IndexException
    {
        return indexManager.createIndex(indexName, indexDefinition, referenceManager.getReferences());
    }

    @Override
    public Index getIndex(final String indexName)
    {
        return indexManager.getIndex(indexName);
    }

    @Override
    public Collection> getIndexes()
    {
        return indexManager.getIndexes();
    }

    @Override
    public boolean removeIndex(final Index index)
    {
        return indexManager.removeIndex(index);
    }

    @Override
    public boolean removeIndex(final String indexName)
    {
        return indexManager.removeIndex(indexName);
    }

    @Override
    public void reindex()
    {
        indexManager.reindex(referenceManager.getReferences());
    }

    @Override
    public void reindex(final V item)
    {
        reindex(Collections.singleton(item));
    }

    @Override
    public void reindex(final Collection items)
    {
        final List> references = items.stream()
                                                   .map(referenceManager::findReference)
                                                   .filter(Optional::isPresent)
                                                   .map(Optional::get)
                                                   .collect(Collectors.toList());

        indexManager.reindex(references);
    }

    @Override
    public int size()
    {
        return referenceManager.size();
    }

    @Override
    public boolean isEmpty()
    {
        return size() == 0;
    }

    @Override
    public boolean contains(final Object obj)
    {
        return referenceManager.findReference(obj).isPresent();
    }

    @Override
    public Iterator iterator()
    {
        return new StoreIterator(referenceManager.getReferences().iterator());
    }

    @Override
    public boolean addAll(final Collection collection)
    {
        final List> references = new ArrayList<>();
        boolean changed = false;

        for (final V item : collection)
        {
            final Optional> existingReference = referenceManager.findReference(item);

            if (existingReference.isPresent())
            {
                references.add(existingReference.get());
                continue;
            }

            references.add(referenceManager.add(item));
            changed = true;
        }

        indexManager.reindex(references);
        return changed;
    }

    @Override
    public boolean add(final V item)
    {
        return addAll(Collections.singleton(item));
    }

    @Override
    public boolean remove(final Object obj)
    {
        final Reference reference = referenceManager.remove(obj);

        if (reference != null)
        {
            indexManager.removeReference(reference);
            return true;
        }

        return false;
    }

    @Override
    public void clear()
    {
        referenceManager.clear();
        indexManager.clear();
    }

    @Override
    public Store copy()
    {
        return createCopy(referenceManager, indexManager);
    }

    protected abstract Store createCopy(final ReferenceManager referenceManager, final IndexManager indexManager);

    protected ReferenceManager getReferenceManager()
    {
        return referenceManager;
    }

    private class StoreIterator implements Iterator
    {
        private final Iterator> iterator;
        private Reference previous;

        StoreIterator(final Iterator> iterator)
        {
            this.iterator = iterator;
        }

        @Override
        public boolean hasNext()
        {
            return iterator.hasNext();
        }

        @Override
        public V next()
        {
            previous = iterator.next();
            return previous.get();
        }

        @Override
        public void remove()
        {
            iterator.remove();
            indexManager.removeReference(previous);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy