Package org.chaidb.db.helper.cache.storage

Source Code of org.chaidb.db.helper.cache.storage.BTreePathStorage

/*
* Copyright (C) 2006  http://www.chaidb.org
*
* 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.
*
*/

package org.chaidb.db.helper.cache.storage;

import com.coyotegulch.jisp.*;
import org.chaidb.db.helper.cache.Cache;
import org.chaidb.db.helper.cache.CacheException;

import java.io.File;
import java.io.IOException;

public class BTreePathStorage {
    public BTreePathStorage(String storagePath) {
        this(storagePath, DEFAULT_CACHE_SIZE);
    }

    public BTreePathStorage(String storagePath, int cacheSize) {
        this.keyFile = new File(storagePath + KEY_FILE_SUFFIX);
        this.dataFile = new File(storagePath + DATA_FILE_SUFFIX);
        this.cache = new Cache(cacheSize);
        this.cache.clearCache();
    }

    public void init() throws SecondaryStorageException {
        Jisp.setClassLoader(this.getClass().getClassLoader());
        boolean toCreate = !keyFile.exists() && !dataFile.exists();
        IndexedObjectDatabase dataStorage = null;
        BTreeIndex keyStorage = null;

        // create new storage
        if (toCreate) {
            try {
                dataStorage = new IndexedObjectDatabase(dataFile.getAbsolutePath(), true);
                keyStorage = new BTreeIndex(keyFile.getAbsolutePath(), DEFAULT_INDEX_ORDER, false);
            } catch (Exception e) {
                throw new SecondaryStorageException("create storage failed!", e);
            } finally {
                try {
                    keyStorage.close();
                    dataStorage.close();
                } catch (IOException e) {
                }
            }
        }

        // open storage
        boolean isConsistent = keyFile.exists() && dataFile.exists();
        if (isConsistent) {
            // populate cache
            try {
                dataStorage = new IndexedObjectDatabase(dataFile.getAbsolutePath(), false);
                keyStorage = new BTreeIndex(keyFile.getAbsolutePath());
                dataStorage.attachIndex(keyStorage);
                int keyCount = keyStorage.count();
                if (keyCount == 0) {
                    return;
                }
                int cacheSize = cache.maxSize();
                int loopTime = (keyCount > cacheSize) ? cacheSize : keyCount;

                for (int i = 1; i <= loopTime; i++) {
                    IntKey key = new IntKey(i);
                    cache.putIntoCache(key, dataStorage.read(key, keyStorage));
                }
            } catch (Exception e) {
                throw new SecondaryStorageException("initializing storage failed.", e);
            } finally {
                try {
                    keyStorage.close();
                    dataStorage.close();
                } catch (IOException e) {
                }
            }
        } else {
            StringBuffer errorMessage = new StringBuffer("!");
            if (!keyFile.exists()) {
                errorMessage.append(" missing key file!");
            }
            if (!dataFile.exists()) {
                errorMessage.append(" missing data file!");
            }
            throw new SecondaryStorageException("storage is corrupted" + errorMessage);
        }
    }

    public synchronized int store(String value) throws SecondaryStorageException {
        if (value == null) {
            throw new SecondaryStorageException("value MUST NOT be null!");
        }

        IndexedObjectDatabase dataStorage = null;
        BTreeIndex keyStorage = null;

        try {
            dataStorage = new IndexedObjectDatabase(dataFile.getAbsolutePath(), false);
            keyStorage = new BTreeIndex(keyFile.getAbsolutePath());
            dataStorage.attachIndex(keyStorage);

            IntKey nextKey = new IntKey(keyStorage.count() + KEY_START_FROM); // start from 1
            dataStorage.write(new OrderedObject[]{nextKey}, value.getBytes(DATA_CHARSET));
            cache.putIntoCache(nextKey, value);
            return nextKey.intValue();
        } catch (Exception e) {
            throw new SecondaryStorageException("store into storage failed, value=" + value, e);
        } finally {
            try {
                keyStorage.close();
                dataStorage.close();
            } catch (IOException e) {
            }
        }
    }

    public synchronized String retrieve(int key) throws SecondaryStorageException {
        if (key < 0) {
            throw new SecondaryStorageException("key MUST NOT less than 0!");
        }

        final IntKey intKey = new IntKey(key);
        IndexedObjectDatabase dataStorage = null;
        BTreeIndex keyStorage = null;
        String value = null;

        try {
            value = (String) cache.getFromCache(intKey);
            if (value != null) {
                return value;
            }
        } catch (CacheException e) {
            throw new SecondaryStorageException("get value from cache failed, value=" + value, e);
        }

        try {
            dataStorage = new IndexedObjectDatabase(dataFile.getAbsolutePath(), false);
            keyStorage = new BTreeIndex(keyFile.getAbsolutePath());
            dataStorage.attachIndex(keyStorage);

            byte[] valueInBytes = (byte[]) dataStorage.read(intKey, keyStorage);
            if (valueInBytes != null) {
                value = new String(valueInBytes, DATA_CHARSET);
                cache.putIntoCache(intKey, value);
            }
            return value;
        } catch (Exception e) {
            throw new SecondaryStorageException("retrieve from storage failed, key=" + key, e);
        } finally {
            try {
                keyStorage.close();
                dataStorage.close();
            } catch (IOException e) {
            }
        }
    }

    public synchronized int size() throws SecondaryStorageException {
        BTreeIndex keyStorage = null;
        try {
            keyStorage = new BTreeIndex(keyFile.getAbsolutePath());
            return keyStorage.count();
        } catch (Exception e) {
            throw new SecondaryStorageException("count storage size failed.", e);
        } finally {
            try {
                keyStorage.close();
            } catch (IOException e) {
            }
        }
    }

    private File keyFile;
    private File dataFile;
    private Cache cache;

    private static final String KEY_FILE_SUFFIX = ".key";
    private static final String DATA_FILE_SUFFIX = ".dat";
    private static final String DATA_CHARSET = "UTF-8";
    private static final int DEFAULT_CACHE_SIZE = 1024;
    private static final int DEFAULT_INDEX_ORDER = 5;
    private static final int KEY_START_FROM = 1;
}
TOP

Related Classes of org.chaidb.db.helper.cache.storage.BTreePathStorage

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.