Package org.elasticsearch.common.lucene.search

Source Code of org.elasticsearch.common.lucene.search.XBooleanFilter

/*
* Licensed to Elastic Search and Shay Banon under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. Elastic Search licenses this
* file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*    http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

package org.elasticsearch.common.lucene.search;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.*;
import org.apache.lucene.util.OpenBitSet;
import org.apache.lucene.util.OpenBitSetDISI;
import org.elasticsearch.common.lucene.docset.DocSet;
import org.elasticsearch.common.lucene.docset.OpenBitDocSet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* @author kimchy (shay.banon)
*/
// LUCENE MONITOR: added to take into account DocSet that wraps OpenBitSet when optimizing or/and/...
public class XBooleanFilter extends Filter {
    ArrayList<Filter> shouldFilters = null;
    ArrayList<Filter> notFilters = null;
    ArrayList<Filter> mustFilters = null;

    private DocIdSetIterator getDISI(ArrayList<Filter> filters, int index, IndexReader reader)
            throws IOException {
        DocIdSet docIdSet = filters.get(index).getDocIdSet(reader);
        if (docIdSet == null) {
            return DocIdSet.EMPTY_DOCIDSET.iterator();
        }
        DocIdSetIterator iterator = docIdSet.iterator();
        if (iterator == null) {
            return DocIdSet.EMPTY_DOCIDSET.iterator();
        }
        return iterator;
    }

    public List<Filter> getShouldFilters() {
        return this.shouldFilters;
    }

    public List<Filter> getMustFilters() {
        return this.mustFilters;
    }

    public List<Filter> getNotFilters() {
        return this.notFilters;
    }

    /**
     * Returns the a DocIdSetIterator representing the Boolean composition
     * of the filters that have been added.
     */
    @Override
    public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
        OpenBitSetDISI res = null;

        if (shouldFilters != null) {
            for (int i = 0; i < shouldFilters.size(); i++) {
                if (res == null) {
                    res = new OpenBitSetDISI(getDISI(shouldFilters, i, reader), reader.maxDoc());
                } else {
                    DocIdSet dis = shouldFilters.get(i).getDocIdSet(reader);
                    if (dis instanceof OpenBitSet) {
                        // optimized case for OpenBitSets
                        res.or((OpenBitSet) dis);
                    } else if (dis instanceof OpenBitDocSet) {
                        res.or(((OpenBitDocSet) dis).set());
                    } else {
                        res.inPlaceOr(getDISI(shouldFilters, i, reader));
                    }
                }
            }
        }

        if (notFilters != null) {
            for (int i = 0; i < notFilters.size(); i++) {
                if (res == null) {
                    res = new OpenBitSetDISI(getDISI(notFilters, i, reader), reader.maxDoc());
                    res.flip(0, reader.maxDoc()); // NOTE: may set bits on deleted docs
                } else {
                    DocIdSet dis = notFilters.get(i).getDocIdSet(reader);
                    if (dis instanceof OpenBitSet) {
                        // optimized case for OpenBitSets
                        res.andNot((OpenBitSet) dis);
                    } else if (dis instanceof OpenBitDocSet) {
                        res.andNot(((OpenBitDocSet) dis).set());
                    } else {
                        res.inPlaceNot(getDISI(notFilters, i, reader));
                    }
                }
            }
        }

        if (mustFilters != null) {
            for (int i = 0; i < mustFilters.size(); i++) {
                if (res == null) {
                    res = new OpenBitSetDISI(getDISI(mustFilters, i, reader), reader.maxDoc());
                } else {
                    DocIdSet dis = mustFilters.get(i).getDocIdSet(reader);
                    if (dis instanceof OpenBitSet) {
                        // optimized case for OpenBitSets
                        res.and((OpenBitSet) dis);
                    } else if (dis instanceof OpenBitDocSet) {
                        res.and(((OpenBitDocSet) dis).set());
                    } else {
                        res.inPlaceAnd(getDISI(mustFilters, i, reader));
                    }
                }
            }
        }

        if (res != null)
            return new OpenBitDocSet(res);

        return DocSet.EMPTY_DOC_SET;
    }

    /**
     * Provide a SortedVIntList when it is definitely smaller
     * than an OpenBitSet.
     *
     * @deprecated Either use CachingWrapperFilter, or
     *             switch to a different DocIdSet implementation yourself.
     *             This method will be removed in Lucene 4.0
     */
    protected final DocIdSet finalResult(OpenBitSetDISI result, int maxDocs) {
        return result;
    }

    /**
     * Adds a new FilterClause to the Boolean Filter container
     *
     * @param filterClause A FilterClause object containing a Filter and an Occur parameter
     */

    public void add(FilterClause filterClause) {
        if (filterClause.getOccur().equals(BooleanClause.Occur.MUST)) {
            if (mustFilters == null) {
                mustFilters = new ArrayList<Filter>();
            }
            mustFilters.add(filterClause.getFilter());
        }
        if (filterClause.getOccur().equals(BooleanClause.Occur.SHOULD)) {
            if (shouldFilters == null) {
                shouldFilters = new ArrayList<Filter>();
            }
            shouldFilters.add(filterClause.getFilter());
        }
        if (filterClause.getOccur().equals(BooleanClause.Occur.MUST_NOT)) {
            if (notFilters == null) {
                notFilters = new ArrayList<Filter>();
            }
            notFilters.add(filterClause.getFilter());
        }
    }

    private boolean equalFilters(ArrayList<Filter> filters1, ArrayList<Filter> filters2) {
        return (filters1 == filters2) ||
                ((filters1 != null) && filters1.equals(filters2));
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;

        XBooleanFilter other = (XBooleanFilter) obj;
        return equalFilters(notFilters, other.notFilters)
                && equalFilters(mustFilters, other.mustFilters)
                && equalFilters(shouldFilters, other.shouldFilters);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + (null == mustFilters ? 0 : mustFilters.hashCode());
        hash = 31 * hash + (null == notFilters ? 0 : notFilters.hashCode());
        hash = 31 * hash + (null == shouldFilters ? 0 : shouldFilters.hashCode());
        return hash;
    }

    /**
     * Prints a user-readable version of this query.
     */
    @Override
    public String toString() {
        StringBuilder buffer = new StringBuilder();
        buffer.append("BooleanFilter(");
        appendFilters(shouldFilters, "", buffer);
        appendFilters(mustFilters, "+", buffer);
        appendFilters(notFilters, "-", buffer);
        buffer.append(")");
        return buffer.toString();
    }

    private void appendFilters(ArrayList<Filter> filters, String occurString, StringBuilder buffer) {
        if (filters != null) {
            for (int i = 0; i < filters.size(); i++) {
                buffer.append(' ');
                buffer.append(occurString);
                buffer.append(filters.get(i).toString());
            }
        }
    }
}
TOP

Related Classes of org.elasticsearch.common.lucene.search.XBooleanFilter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.