Package com.persistit

Source Code of com.persistit.StreamLoader$ImportHandler

/**
* Copyright © 2005-2012 Akiban Technologies, Inc.  All rights reserved.
*
* This program and the accompanying materials are made available
* under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* This program may also be available under different license terms.
* For more information, see www.akiban.com or contact licensing@akiban.com.
*
* Contributors:
* Akiban Technologies, Inc.
*/

package com.persistit;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.persistit.CLI.Arg;
import com.persistit.CLI.Cmd;
import com.persistit.exception.CorruptImportStreamException;
import com.persistit.exception.PersistitException;
import com.persistit.policy.SplitPolicy;
import com.persistit.util.Util;

/**
* Loads Persistit records from a file or other stream in a format generated by
* a {@link StreamSaver}.
*
* @version 1.0
*/
public class StreamLoader extends Task {

    /**
     * Default for BufferedInputStream buffer size.
     */
    public final static int DEFAULT_BUFFER_SIZE = 65536;
    protected String _filePath;
    protected DataInputStream _dis;

    protected Key _key = new Key((Persistit) null);
    protected Value _value = new Value((Persistit) null);
    protected Volume _lastVolume;
    protected Tree _lastTree;
    protected int _dataRecordCount = 0;
    protected int _otherRecordCount = 0;
    protected boolean _stop;
    protected Exception _lastException;

    protected TreeSelector _treeSelector;
    protected boolean _createMissingVolumes;
    protected boolean _createMissingTrees;
    protected ImportHandler _handler;

    @Cmd("load")
    static Task createStreamLoader(@Arg("file|string:|Load from file path") final String file,
            @Arg("trees|string:|Tree selector - specify Volumes/Trees/Keys to save") final String treeSelectorString,
            @Arg("_flag|r|Use regular expressions in tree selector") final boolean regex,
            @Arg("_flag|n|Don't create missing Volumes (Default is to create them)") final boolean dontCreateVolumes,
            @Arg("_flag|t|Don't create missing Trees (Default is to create them)") final boolean dontCreateTrees,
            @Arg("_flag|v|verbose") final boolean verbose) throws Exception {

        final StreamLoader task = new StreamLoader();
        task._filePath = file;
        task._treeSelector = TreeSelector.parseSelector(treeSelectorString, regex, '\\');
        task._createMissingVolumes = !dontCreateVolumes;
        task._createMissingTrees = !dontCreateTrees;
        task.setMessageLogVerbosity(verbose ? LOG_VERBOSE : LOG_NORMAL);
        return task;
    }

    /**
     * Package-private constructor for use in a {@link Task}.
     *
     */
    StreamLoader() {
    }

    public StreamLoader(final Persistit persistit, final DataInputStream dis) {
        super(persistit);
        _dis = dis;
    }

    public StreamLoader(final Persistit persistit, final File file) throws IOException {
        this(persistit, new DataInputStream(new BufferedInputStream(new FileInputStream(file))));
    }

    public StreamLoader(final Persistit persistit, final String fileName) throws IOException {
        this(persistit, new DataInputStream(new BufferedInputStream(new FileInputStream(fileName))));
    }

    public void close() throws IOException {
        _dis.close();
    }

    public void load() throws IOException, PersistitException {
        load(new TreeSelector(), true, true);
    }

    public void load(final TreeSelector treeSelector, final boolean createMissingVolumes,
            final boolean createMissingTrees) throws IOException, PersistitException {
        _handler = new ImportHandler(_persistit, treeSelector, createMissingVolumes, createMissingTrees);
        load(_handler);
        close();
    }

    public void load(final ImportHandler handler) throws IOException, PersistitException {
        while (next(handler)) {
        }
        postMessage(String.format("DONE - processed %,d data records and %,d other records", _dataRecordCount,
                _otherRecordCount), Task.LOG_NORMAL);
    }

    public boolean next(final ImportHandler handler) throws IOException, PersistitException {
        final int b1 = _dis.read();
        if (b1 == -1) {
            return false;
        }
        final int b2 = _dis.read();
        final int recordType = ((b1 & 0xFF) << 8) + (b2 & 0xFF);

        switch (recordType) {
        case StreamSaver.RECORD_TYPE_FILL: {
            handler.handleFillRecord();
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_DATA: {
            final int keySize = _dis.readShort();
            final int elisionCount = _dis.readShort();
            final int valueSize = _dis.readInt();
            _value.ensureFit(valueSize);
            _dis.read(_key.getEncodedBytes(), elisionCount, keySize - elisionCount);
            _key.setEncodedSize(keySize);
            _dis.read(_value.getEncodedBytes(), 0, valueSize);
            _value.setEncodedSize(valueSize);
            handler.handleDataRecord(_key, _value);
            _dataRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_KEY_FILTER: {
            final String filterString = _dis.readUTF();
            handler.handleKeyFilterRecord(filterString);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_VOLUME_ID: {
            final long id = _dis.readLong();
            final long initialPages = _dis.readLong();
            final long extensionPages = _dis.readLong();
            final long maximumPages = _dis.readLong();
            final int bufferSize = _dis.readInt();
            final String path = _dis.readUTF();
            handler._volumeName = _dis.readUTF();
            handler.handleVolumeIdRecord(id, initialPages, extensionPages, maximumPages, bufferSize, path,
                    handler._volumeName);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_TREE_ID: {
            handler._treeName = _dis.readUTF();
            handler.handleTreeIdRecord(handler._treeName);
            _otherRecordCount++;
            postMessage("Loading Tree " + handler._treeName, Task.LOG_VERBOSE);
            break;
        }
        case StreamSaver.RECORD_TYPE_HOSTNAME: {
            final String hostName = _dis.readUTF();
            handler.handleHostNameRecord(hostName);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_USER: {
            final String hostName = _dis.readUTF();
            handler.handleUserRecord(hostName);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_COMMENT: {
            final String comment = _dis.readUTF();
            handler.handleCommentRecord(comment);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_COUNT: {
            final long dataRecordCount = _dis.readLong();
            final long otherRecordCount = _dis.readLong();
            handler.handleCountRecord(dataRecordCount, otherRecordCount);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_START: {
            handler.handleStartRecord();
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_END: {
            handler.handleEndRecord();
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_TIMESTAMP: {
            final long timeStamp = _dis.readLong();
            handler.handleTimeStampRecord(timeStamp);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_EXCEPTION: {
            final String exceptionString = _dis.readUTF();
            handler.handleExceptionRecord(exceptionString);
            _otherRecordCount++;
            break;
        }
        case StreamSaver.RECORD_TYPE_COMPLETION: {
            handler.handleCompletionRecord();
            _otherRecordCount++;
            break;
        }
        default: {
            throw new CorruptImportStreamException("Invalid record type " + recordType + " ("
                    + Util.bytesToHex(new byte[] { (byte) (recordType >>> 8), (byte) recordType }) + " after reading "
                    + _dataRecordCount + " data records" + " and " + _otherRecordCount + " other records");
        }
        }
        return true;
    }

    /**
     * Handler for various record types in stream being loaded.
     *
     * @author peter
     *
     */

    protected static class ImportHandler {
        protected Persistit _persistit;
        protected TreeSelector _treeSelector;
        protected Exchange _exchange;
        protected Volume _volume;
        protected Tree _tree;
        protected KeyFilter _keyFilter;
        protected boolean _createMissingVolumes;
        protected boolean _createMissingTrees;
        protected String _volumeName = null;
        protected String _treeName = null;

        protected ImportHandler(final Persistit persistit) {
            this(persistit, new TreeSelector(), true, true);
        }

        protected ImportHandler(final Persistit persistit, final TreeSelector treeSelector,
                final boolean createMissingVolumes, final boolean createMissingTrees) {
            _persistit = persistit;
            _treeSelector = treeSelector == null ? new TreeSelector() : treeSelector;
            _createMissingTrees = createMissingTrees;
            _createMissingVolumes = createMissingVolumes;
        }

        protected void handleFillRecord() throws PersistitException {
        }

        protected void handleDataRecord(final Key key, final Value value) throws PersistitException {
            if (_keyFilter == null || _keyFilter.selected(key)) {
                if (_volume == null || _tree == null)
                    return;
                if (_exchange == null) {
                    _exchange = _persistit.getExchange(_volume, _tree.getName(), false);
                }
                key.copyTo(_exchange.getKey());
                _exchange.setSplitPolicy(SplitPolicy.PACK_BIAS);
                // Using this package-private method avoids copying
                // the value field.
                _exchange.store(_exchange.getKey(), value);
            }
        }

        protected void handleKeyFilterRecord(final String keyFilterString) throws PersistitException {
        }

        protected void handleVolumeIdRecord(final long volumeId, final long initialPages, final long extensionPages,
                final long maximumPages, final int bufferSize, final String path, final String name)
                throws PersistitException {
            final Exchange oldExchange = _exchange;
            _exchange = null;
            _volume = null;
            _tree = null;

            if (!_treeSelector.isVolumeNameSelected(name)) {
                return;
            }

            _volume = _persistit.getVolume(name);
            if (_volume != null) {
                _volume.verifyId(volumeId);
            } else if (_createMissingVolumes) {
                _volume = new Volume(new VolumeSpecification(path, name, bufferSize, initialPages, maximumPages,
                        extensionPages, false, true, false));
                _volume.setId(volumeId);
                _volume.open(_persistit);
            }
            if (oldExchange != null && oldExchange.getVolume().equals(_volume)) {
                _exchange = oldExchange;
            }
        }

        protected void handleTreeIdRecord(final String treeName) throws PersistitException {
            final Exchange oldExchange = _exchange;
            _exchange = null;
            _tree = null;

            if (_volume == null) {
                return;
            }

            if (!_treeSelector.isTreeNameSelected(_volume.getName(), treeName)) {
                return;
            }

            _tree = _volume.getTree(treeName, _createMissingVolumes | _createMissingTrees);

            if (oldExchange != null && oldExchange.getTree() == _tree) {
                _exchange = oldExchange;
            }
            _keyFilter = _treeSelector.keyFilter(_volume.getName(), treeName);

        }

        protected void handleTimeStampRecord(final long timeStamp) throws PersistitException {
        }

        protected void handleHostNameRecord(final String hostName) throws PersistitException {
        }

        protected void handleUserRecord(final String userName) throws PersistitException {
        }

        protected void handleCommentRecord(final String comment) throws PersistitException {
        }

        protected void handleCountRecord(final long keyValueRecords, final long otherRecords) throws PersistitException {
        }

        protected void handleStartRecord() throws PersistitException {
        }

        protected void handleEndRecord() throws PersistitException {
        }

        protected void handleExceptionRecord(final String exceptionString) throws PersistitException {
        }

        protected void handleCompletionRecord() throws PersistitException {
        }

    }

    @Override
    public void runTask() throws Exception {
        _dis = new DataInputStream(new BufferedInputStream(new FileInputStream(_filePath), DEFAULT_BUFFER_SIZE));
        load(_treeSelector, _createMissingVolumes, _createMissingTrees);
    }

    @Override
    public String getStatus() {
        if (_handler == null || _handler._tree == null) {
            return null;
        }
        final Tree tree = _handler._tree;
        return tree.getName() + " in " + tree.getVolume().getPath() + " (" + _dataRecordCount + ")";
    }

}
TOP

Related Classes of com.persistit.StreamLoader$ImportHandler

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.