org.apache.vxquery.runtime.functions.index.indexCentralizer.IndexCentralizerUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.vxquery.runtime.functions.index.indexCentralizer.IndexCentralizerUtil.java

Source

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.apache.vxquery.runtime.functions.index.indexCentralizer;

import java.io.DataOutput;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.io.FileUtils;
import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
import org.apache.vxquery.datamodel.builders.atomic.StringValueBuilder;
import org.apache.vxquery.datamodel.builders.sequence.SequenceBuilder;
import org.apache.vxquery.datamodel.values.ValueTag;

/**
 * Class for maintaining the centralized index information file.
 * Index centralization procedure.
 * User can specify the collection directory in VXQuery.java, ncConfig.ioDevices = < index_directory > .
 * Then all the indexes will be created in that particular directory in sub-folders corresponding to collections.
 * There will be a single xml file, located in the directory specified in local.xml, which contains all information
 * about the existing indexes.
 * This class can be used to read, add, delete, modify the entries and write the file back to the disk.
 */
public class IndexCentralizerUtil {

    private final String FILE_NAME = "VXQuery-Index-Directory.xml";
    private final List<String> collections = new ArrayList<>();
    private final Logger LOGGER = Logger.getLogger("IndexCentralizerUtil");
    private File XML_FILE;
    private String INDEX_LOCATION;
    private static ConcurrentHashMap<String, IndexLocator> indexCollectionMap = new ConcurrentHashMap<>();

    public IndexCentralizerUtil(File index) {
        this.INDEX_LOCATION = index.getPath();
        if (!index.exists()) {
            try {
                FileUtils.forceMkdir(index);
            } catch (IOException e) {
                LOGGER.log(Level.SEVERE,
                        "Could not create the index directory for path: " + INDEX_LOCATION + " " + e);
            }
        }
        XML_FILE = new File(index.getPath() + "/" + FILE_NAME);
    }

    /**
     * Get the index directory containing index of the given collection
     *
     * @param collection : Collection folder
     * @return Index folder.
     */
    public String getIndexForCollection(String collection) {
        return indexCollectionMap.get(collection).getIndex();
    }

    /**
     * Put the index location corresponding to given collection.
     * Index location is created by using the last 100 characters of collection.
     *
     * @param collection : Collection directory
     * @return index
     */
    public String putIndexForCollection(String collection) {
        int length = collection.replaceAll("/", "").length();
        String index = collection.replaceAll("/", "");
        index = INDEX_LOCATION + "/" + (length > 100 ? index.substring(length - 100) : index);
        IndexLocator il = new IndexLocator();
        il.setCollection(collection);
        il.setIndex(index);
        if (indexCollectionMap.get(collection) != null) {
            return index;
        }
        indexCollectionMap.put(collection, il);
        return index;
    }

    /**
     * Remove the entry for given collection directory.
     *
     * @param collection : Collection directory
     */
    public void deleteEntryForCollection(String collection) {
        indexCollectionMap.remove(collection);
    }

    /**
     * Prints all collections which have an index created.
     * @param sb : The output is stored in a sequence
     * @throws IOException : If writing the dataOutput generates {@link IOException}
     */
    public void getAllCollections(SequenceBuilder sb) throws IOException {
        for (String s : collections) {
            StringValueBuilder svb = new StringValueBuilder();
            ArrayBackedValueStorage abvs = new ArrayBackedValueStorage();
            DataOutput output = abvs.getDataOutput();
            output.write(ValueTag.XS_STRING_TAG);
            svb.write(s, output);
            sb.addItem(abvs);
        }
    }

    /**
     * Read the collection, index directory file and populate the HashMap.
     */
    public void readIndexDirectory() {
        if (this.XML_FILE.exists()) {
            try {
                JAXBContext jaxbContext = JAXBContext.newInstance(IndexDirectory.class);
                Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
                IndexDirectory indexDirectory = (IndexDirectory) jaxbUnmarshaller.unmarshal(this.XML_FILE);

                for (IndexLocator il : indexDirectory.getDirectory()) {
                    indexCollectionMap.put(il.getCollection(), il);
                    this.collections.add(il.getCollection());
                }
            } catch (JAXBException e) {
                LOGGER.log(Level.SEVERE, "Could not read the XML file due to " + e);
            }
        }

    }

    /**
     * Write back the contents of the HashMap to the file.
     */
    public void writeIndexDirectory() {
        IndexDirectory id = new IndexDirectory();
        List<IndexLocator> indexLocators = new ArrayList<>(indexCollectionMap.values());
        id.setDirectory(indexLocators);
        try {
            FileOutputStream fileOutputStream = new FileOutputStream(this.XML_FILE);
            JAXBContext context = JAXBContext.newInstance(IndexDirectory.class);
            Marshaller jaxbMarshaller = context.createMarshaller();
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.marshal(id, fileOutputStream);
        } catch (JAXBException | FileNotFoundException e) {
            LOGGER.log(Level.SEVERE, "Could not read the XML file due to " + e);
        }
    }
}