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 {
        String volumeName = null;
        String treeName = null;
        for (;;) {
            final int b1 = _dis.read();
            if (b1 == -1) {
                break;
            }
            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();
                volumeName = _dis.readUTF();
                handler.handleVolumeIdRecord(id, initialPages, extensionPages, maximumPages, bufferSize, path,
                        volumeName);
                _otherRecordCount++;
                break;
            }
            case StreamSaver.RECORD_TYPE_TREE_ID: {
                treeName = _dis.readUTF();
                handler.handleTreeIdRecord(treeName);
                _otherRecordCount++;
                postMessage("Loading Tree " + 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");
            }
            }

        }
        postMessage(String.format("DONE - processed %,d data records and %,d other records", _dataRecordCount,
                _otherRecordCount), Task.LOG_NORMAL);
    }

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

    public 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;

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

        public 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;
        }

        public void handleFillRecord() throws PersistitException {
        }

        public 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);
            }
        }

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

        public 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;
            }
        }

        public 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);

        }

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

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

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

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

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

        public void handleStartRecord() throws PersistitException {
        }

        public void handleEndRecord() throws PersistitException {
        }

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

        public 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.