Package com.foundationdb.server.service.text

Source Code of com.foundationdb.server.service.text.FullTextIndexInfo

/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package com.foundationdb.server.service.text;

import com.foundationdb.ais.model.AkibanInformationSchema;
import com.foundationdb.ais.model.Column;
import com.foundationdb.ais.model.FullTextIndex;
import com.foundationdb.ais.model.Group;
import com.foundationdb.ais.model.IndexColumn;
import com.foundationdb.ais.model.IndexName;
import com.foundationdb.ais.model.Table;
import com.foundationdb.qp.operator.API;
import com.foundationdb.qp.operator.Operator;
import com.foundationdb.qp.rowtype.*;
import com.foundationdb.qp.rowtype.TableRowType;
import com.foundationdb.qp.util.SchemaCache;
import com.foundationdb.server.error.NoSuchIndexException;
import com.foundationdb.server.error.NoSuchTableException;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.queryparser.flexible.standard.StandardQueryParser;

import java.io.File;
import java.io.IOException;
import java.util.*;

public class FullTextIndexInfo
{
    private final FullTextIndexShared shared;
    private FullTextIndex index;
    private Schema schema;
    private TableRowType indexedRowType;
    private HKeyRowType hKeyRowType;
    private Map<Column,IndexedField> fieldsByColumn;
    private Map<RowType,List<IndexedField>> fieldsByRowType;
    private String defaultFieldName;
    private Operator plan;
   
    public FullTextIndexInfo(FullTextIndexShared shared) {
        this.shared = shared;
    }

    public void init(AkibanInformationSchema ais) {
        IndexName name = shared.getName();
        Table table = ais.getTable(name.getFullTableName());
        if (table == null) {
            throw new NoSuchTableException(name.getFullTableName());
        }
        index = table.getFullTextIndex(name.getName());
        if (index == null) {
            NoSuchIndexException ret =  new NoSuchIndexException(name.getName());
            ret.printStackTrace();
            throw ret;
        }
        schema = SchemaCache.globalSchema(ais);
        indexedRowType = schema.tableRowType(table);
        hKeyRowType = schema.newHKeyRowType(table.hKey());
        fieldsByColumn = new HashMap<>(index.getKeyColumns().size());
        for (IndexColumn indexColumn : index.getKeyColumns()) {
            Column column = indexColumn.getColumn();
            IndexedField indexedField = new IndexedField(column);
            fieldsByColumn.put(column, indexedField);
            if (defaultFieldName == null) {
                defaultFieldName = indexedField.getName();
            }
        }
        fieldsByRowType = new HashMap<>();
        for (Map.Entry<Column,IndexedField> entry : fieldsByColumn.entrySet()) {
            TableRowType rowType = schema.tableRowType(entry.getKey().getTable());
            List<IndexedField> fields = fieldsByRowType.get(rowType);
            if (fields == null) {
                fields = new ArrayList<>();
                fieldsByRowType.put(rowType, fields);
            }
            fields.add(entry.getValue());
        }
       
        plan = computePlan();
    }

    public FullTextIndex getIndex() {
        return index;
    }

    public Schema getSchema() {
        return schema;
    }

    public TableRowType getIndexedRowType() {
        return indexedRowType;
    }

    public HKeyRowType getHKeyRowType() {
        return hKeyRowType;
    }

    public Map<Column,IndexedField> getFieldsByColumn() {
        return fieldsByColumn;
    }

    public Map<RowType,List<IndexedField>> getFieldsByRowType() {
        return fieldsByRowType;
    }

    public Set<String> getCasePreservingFieldNames() {
        Set<String> result = new HashSet<>();
        for (IndexedField field : fieldsByColumn.values()) {
            if (field.isCasePreserving()) {
                result.add(field.getName());
            }
        }
        return result;
    }

    public String getDefaultFieldName() {
        return defaultFieldName;
    }

    public Set<RowType> getRowTypes() {
        Set<RowType> rowTypes = new HashSet<>(fieldsByRowType.keySet());
        rowTypes.add(indexedRowType);
        return rowTypes;
    }

    public Operator fullScan() {
        Operator plan = API.groupScan_Default(indexedRowType.table().getGroup());
        Set<RowType> rowTypes = getRowTypes();
        plan = API.filter_Default(plan, rowTypes);
        return plan;
    }
   
   
   
    private Operator computePlan()
    {
        Operator ret = null;

        Group group = indexedRowType.table().getGroup();
        Set<TableRowType> ancestors = new HashSet<>();
        boolean hasDesc = false;

        for (IndexColumn ic : index.getKeyColumns())
        {
            Table colTable = ic.getColumn().getTable();

            if (!hasDesc && !colTable.equals(indexedRowType.table()))
                // if any column in the index def belongs to a table
                // that is a descendant of this indexed row's table
                // (meaning this indexed row has descendant(s))
                hasDesc = colTable.isDescendantOf(indexedRowType.table());
           
            // if the indexed table is a child of this column's table
            // (meaning this indexed row has parent(s))
            // collect all ancestor's rowtype
            if (indexedRowType.table().isDescendantOf(colTable))
                ancestors.add(schema.tableRowType(colTable));
        }

        if (hasDesc)
        {
            ancestors.remove(indexedRowType);

            ret = API.branchLookup_Nested(group,
                                           hKeyRowType,
                                           indexedRowType,
                                           API.InputPreservationOption.DISCARD_INPUT,
                                           0);
            if (!ancestors.isEmpty())
            {
               
                ret = API.groupLookup_Default(ret,
                                              group,
                                              indexedRowType,
                                              ancestors,
                                              API.InputPreservationOption.KEEP_INPUT,
                                              1);
            }
        }
        else
        {
            // has at least one ancestor (which is itself)
            ancestors.add(indexedRowType);
            ret = API.ancestorLookup_Nested(group,
                                            hKeyRowType,
                                            ancestors,
                                            0, 1);
        }
         
        return ret;
    }
    /**
     * @return the operator plan to get to every row related to this index row
     */
    public Operator getOperator()
    {
        return plan;
    }

    public Analyzer getAnalyzer() {
        Analyzer analyzer;
        synchronized (shared) {
            analyzer = shared.getAnalyzer();
            if (analyzer == null) {
                analyzer = new SelectiveCaseAnalyzer(shared.getCasePreservingFieldNames());
            }
        }
        return analyzer;
    }

    public StandardQueryParser getParser() {
        StandardQueryParser parser;
        synchronized (shared) {
            parser = shared.getParser();
            if (parser == null) {
                parser = new StandardQueryParser(getAnalyzer());
            }
            shared.setParser(parser);
        }
        return parser;
    }

    protected Searcher getSearcher() throws IOException {
        Searcher searcher;
        synchronized (shared) {
            searcher = shared.getSearcher();
            if (searcher == null) {
                searcher = new Searcher(shared, getAnalyzer());
            }
            shared.setSearcher(searcher);
        }
        return searcher;
    }

    public Indexer getIndexer() throws IOException {
        Indexer indexer;
        synchronized (shared) {
            indexer = shared.getIndexer();
            if (indexer == null) {
                indexer = new Indexer(shared, getAnalyzer());
                shared.setIndexer(indexer);
            }
        }
        return indexer;
    }

    public void deletePath() {
        File path = shared.getPath();
        // no doc to delete
        if (!path.exists() || path.listFiles() == null)
            return;
        for (File f : path.listFiles()) {
            f.delete();
        }
        path.delete();
    }

    public void commitIndexer() throws IOException {
        shared.getIndexer().getWriter().commit();
    }

    public void rollbackIndexer() throws IOException {
        synchronized (shared) {
            Indexer indexer = shared.getIndexer();
            if(indexer != null) {
                try {
                    indexer.getWriter().rollback();
                } finally {
                    // Rollback causes the writer to be closed. Always get rid of it.
                    shared.setIndexer(null);
                }
            }
        }
    }

    public void close() throws IOException {
        shared.close();
    }
}
TOP

Related Classes of com.foundationdb.server.service.text.FullTextIndexInfo

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.