ja.lingo.engine.mergedindex.ChannelMergedIndex.java Source code

Java tutorial

Introduction

Here is the source code for ja.lingo.engine.mergedindex.ChannelMergedIndex.java

Source

/*
 * JaLingo, http://jalingo.sourceforge.net/
 *
 * Copyright (c) 2002-2006 Oleksandr Shyshko
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package ja.lingo.engine.mergedindex;

import ja.centre.util.assertions.Arguments;
import ja.centre.util.assertions.States;
import ja.centre.util.io.intio.IIntReader;
import ja.centre.util.io.intio.IntBufferIntReader;
import ja.centre.util.io.nio.MappedByteBufferWrapper;
import ja.centre.util.io.Files;
import ja.lingo.engine.beans.IArticle;
import ja.lingo.engine.dictionaryindex.reader.IDictionaryIndex;
import ja.lingo.engine.util.slice.ByteBufferSliceReader;
import ja.lingo.engine.util.slice.ISliceReader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;

public class ChannelMergedIndex implements IMergedIndex {
    private static final Log LOG = LogFactory.getLog(ChannelMergedIndex.class);

    private static final int SLICE_READER_INT_ID_TO_READER_ID_MAP = 0;
    private static final int SLICE_GROUPS_INDEX_LENGTH_LIST = 1;
    private static final int SLICE_GROUPS_LIST = 2;

    private String fileName;

    private MappedByteBufferWrapper fisMappedByteBufferWrapper;

    private IIntReader groupsIndexLengthIntReader;
    private IIntReader groupsIntReader;

    private Map<Integer, IDictionaryIndex> readerIntIdToReaderMap;

    private boolean closed;

    public ChannelMergedIndex(String fileName, Map<String, IDictionaryIndex> indexFileNameToReaderMap)
            throws IOException {
        Arguments.assertNotNull("fileName", fileName);
        Arguments.assertNotNull("indexFileNameToReaderMap", indexFileNameToReaderMap);

        this.fileName = fileName;

        fisMappedByteBufferWrapper = new MappedByteBufferWrapper(fileName);

        ISliceReader sliceReader = new ByteBufferSliceReader(fisMappedByteBufferWrapper.getMappedByteBuffer());

        // read position + fill readerIntIdToReaderMap
        {
            ByteBuffer buffer = sliceReader.getSlice(SLICE_READER_INT_ID_TO_READER_ID_MAP);
            byte[] bytes = new byte[buffer.limit()];
            buffer.position(0);
            buffer.get(bytes);

            try {
                readerIntIdToReaderMap = _deserializeReaderIdToReaderMap(
                        new DataInputStream(new ByteArrayInputStream(bytes)), indexFileNameToReaderMap);
            } catch (IOException e) {
                Files.close(fisMappedByteBufferWrapper);
                throw e;
            }
        }

        groupsIndexLengthIntReader = new IntBufferIntReader(
                sliceReader.getSlice(SLICE_GROUPS_INDEX_LENGTH_LIST).asIntBuffer());
        groupsIntReader = new IntBufferIntReader(sliceReader.getSlice(SLICE_GROUPS_LIST).asIntBuffer());
    }

    public IArticle getArticle(int index) {
        assertNotClosed();

        int groupsIndex = groupsIndexLengthIntReader.get(index * 2);
        int groupsLength = groupsIndexLengthIntReader.get(index * 2 + 1);

        Article article = new Article(groupsLength);

        for (int i = 0; i < groupsLength; i++) {
            int readerId = groupsIntReader.get((i + groupsIndex) * 2);
            int inReaderIndex = groupsIntReader.get((i + groupsIndex) * 2 + 1);

            IDictionaryIndex reader = (IDictionaryIndex) readerIntIdToReaderMap.get(new Integer(readerId));

            if (reader == null) {
                States.doThrow("Could not retrieve reader for id=" + readerId);
            }

            article.set(i, reader, inReaderIndex);
        }

        return article;
    }

    public String getArticleTitle(int index) {
        assertNotClosed();

        int groupsIndex = groupsIndexLengthIntReader.get(index * 2);

        int readerId = groupsIntReader.get((0 + groupsIndex) * 2);
        int inReaderIndex = groupsIntReader.get((0 + groupsIndex) * 2 + 1);

        IDictionaryIndex reader = (IDictionaryIndex) readerIntIdToReaderMap.get(readerId);

        return reader.getTitle(inReaderIndex);
    }

    public int size() {
        assertNotClosed();

        return groupsIndexLengthIntReader.size() / 2;
    }

    public void close() throws IOException {
        assertNotClosed();

        LOG.info("Closing \"" + fileName + "\"...");
        fisMappedByteBufferWrapper.close();
        fisMappedByteBufferWrapper = null;

        closed = true;
    }

    private void assertNotClosed() {
        States.assertFalse(closed, "Expected to be not closed");
    }

    private static Map<Integer, IDictionaryIndex> _deserializeReaderIdToReaderMap(DataInputStream dis,
            Map<String, IDictionaryIndex> indexFileNameToReaderMap) throws IOException {
        Map<Integer, IDictionaryIndex> readerIdToReaderMap = new HashMap<Integer, IDictionaryIndex>();

        int readerCount = dis.readInt();

        for (int i = 0; i < readerCount; i++) {
            int readerId = dis.readInt();
            String indexFileName = dis.readUTF();

            IDictionaryIndex reader = indexFileNameToReaderMap.get(indexFileName);

            if (reader == null) {
                throw new IOException("Unable to retrieve reader with readerId=\"" + readerId
                        + "\" and indexFileName=\"" + indexFileName + "\"");
            }

            readerIdToReaderMap.put(readerId, reader);
        }

        return readerIdToReaderMap;
    }
}