Package org.xtreemfs.babudb.lsmdb

Source Code of org.xtreemfs.babudb.lsmdb.DBConfig

/*
* Copyright (c) 2009 - 2011, Jan Stender, Bjoern Kolbeck, Mikael Hoegqvist,
*                     Felix Hupfeld, Felix Langner, Zuse Institute Berlin
*
* Licensed under the BSD License, see LICENSE file for details.
*
*/
package org.xtreemfs.babudb.lsmdb;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.xtreemfs.babudb.api.dev.BabuDBInternal;
import org.xtreemfs.babudb.api.dev.DatabaseInternal;
import org.xtreemfs.babudb.api.dev.DatabaseManagerInternal;
import org.xtreemfs.babudb.api.exception.BabuDBException;
import org.xtreemfs.babudb.api.exception.BabuDBException.ErrorCode;
import org.xtreemfs.babudb.api.index.ByteRangeComparator;
import org.xtreemfs.foundation.logging.Logging;

import static org.xtreemfs.babudb.BabuDBFactory.*;

/**
* <p>
* Operations to manipulate the DB-config-file.
* </p>
*
* @author flangner
* @since 09/02/2009
*/

public class DBConfig {
   
    private final BabuDBInternal dbs;
   
    private final File           configFile;
   
    private boolean              conversionRequired;
   
    private int                  dbFormatVer;
   
    public DBConfig(BabuDBInternal dbs) throws BabuDBException {
        this.dbs = dbs;
        this.configFile = new File(dbs.getConfig().getBaseDir() + dbs.getConfig().getDbCfgFile());
        load();
    }
   
    /**
     * Loads the configuration and each database from disk and replaces the data
     * of the existing DBs, while removing outdated one's.
     *
     * @throws BabuDBException
     */
    public void reset() throws BabuDBException {
        DatabaseManagerInternal dbman = dbs.getDatabaseManager();
        assert (dbman != null) : "The DatabaseManager is not available!";
       
        ObjectInputStream ois = null;
        try {
            List<Integer> ids = new LinkedList<Integer>();
            if (configFile.exists()) {
                ois = new ObjectInputStream(new FileInputStream(configFile));
                final int dbFormatVer = ois.readInt();
                if (dbFormatVer != BABUDB_DB_FORMAT_VERSION) {
                    throw new BabuDBException(ErrorCode.IO_ERROR, "on-disk format (version " + dbFormatVer
                        + ") is incompatible with this BabuDB release " + "(uses on-disk format version "
                        + BABUDB_DB_FORMAT_VERSION + ")");
                }
                final int numDB = ois.readInt();
                dbman.setNextDBId(ois.readInt());
                for (int i = 0; i < numDB; i++) {
                    Logging.logMessage(Logging.LEVEL_DEBUG, this, "loading DB...");
                    final String dbName = (String) ois.readObject();
                    final int dbId = ois.readInt();
                    final int numIndex = ois.readInt();
                    ByteRangeComparator[] comps = new ByteRangeComparator[numIndex];
                    for (int idx = 0; idx < numIndex; idx++) {
                        final String className = (String) ois.readObject();
                        ByteRangeComparator comp = dbman.getComparatorInstances().get(className);
                        if (comp == null) {
                            Class<?> clazz = Class.forName(className);
                            comp = (ByteRangeComparator) clazz.newInstance();
                            dbman.getComparatorInstances().put(className, comp);
                        }
                       
                        assert (comp != null);
                        comps[idx] = comp;
                    }
                   
                    ids.add(dbId);
                   
                    DatabaseInternal db;
                    try {
                        // reset existing DBs
                        db = dbman.getDatabase(dbId);
                        db.setLSMDB(new LSMDatabase(dbName, dbId, dbs.getConfig().getBaseDir()
                                + dbName + File.separatorChar, numIndex, true, comps,
                                dbs.getConfig().getCompression(),
                                dbs.getConfig().getMaxNumRecordsPerBlock(),
                                dbs.getConfig().getMaxBlockFileSize(),
                                dbs.getConfig().getDisableMMap(),
                                dbs.getConfig().getMMapLimit()));
                    } catch (BabuDBException e) {
                        db = new DatabaseImpl(dbs, new LSMDatabase(dbName, dbId,
                                dbs.getConfig().getBaseDir() + dbName + File.separatorChar,
                                numIndex, true, comps, dbs.getConfig().getCompression(),
                                dbs.getConfig().getMaxNumRecordsPerBlock(),
                                dbs.getConfig().getMaxBlockFileSize(),
                                dbs.getConfig().getDisableMMap(),
                                dbs.getConfig().getMMapLimit()));
                       
                        dbman.putDatabase(db);
                    }
                   
                    Logging.logMessage(Logging.LEVEL_INFO, this, "loaded DB %s" + " successfully. [LSN %s]",
                        dbName, db.getLSMDB().getOndiskLSN());
                }
            }
           
            // delete remaining outdated DBs
            Set<Integer> outdatedIds = dbman.getAllDatabaseIds();
            outdatedIds.removeAll(ids);
            if (outdatedIds.size() > 0) {
                for (int id : outdatedIds) {
                    dbman.removeDatabaseById(id);
                }
            }
        } catch (InstantiationException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR, "cannot instantiate comparator", ex);
        } catch (IllegalAccessException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR, "cannot instantiate comparator", ex);
        } catch (IOException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR,
                "cannot load database config, check path and access rights", ex);
        } catch (ClassNotFoundException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR,
                "cannot load database config, config file might be corrupted", ex);
        } catch (ClassCastException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR,
                "cannot load database config, config file might be corrupted", ex);
        } finally {
            if (ois != null)
                try {
                    ois.close();
                } catch (IOException e) {
                    /* I don't care */
                }
        }
    }
   
    /**
     * Loads the configuration and each database from disk.
     *
     * @throws BabuDBException
     */
    public void load() throws BabuDBException {
        DatabaseManagerInternal dbman = dbs.getDatabaseManager();
        assert (dbman != null) : "The DatabaseManager is not available!";
       
        ObjectInputStream ois = null;
        try {
            if (configFile.exists()) {
                ois = new ObjectInputStream(new FileInputStream(configFile));
                dbFormatVer = ois.readInt();
                if (dbFormatVer != BABUDB_DB_FORMAT_VERSION)
                    conversionRequired = true;
                final int numDB = ois.readInt();
                dbman.setNextDBId(ois.readInt());
                for (int i = 0; i < numDB; i++) {
                    Logging.logMessage(Logging.LEVEL_DEBUG, this, "loading DB...");
                    final String dbName = (String) ois.readObject();
                    final int dbId = ois.readInt();
                    final int numIndex = ois.readInt();
                    ByteRangeComparator[] comps = new ByteRangeComparator[numIndex];
                    for (int idx = 0; idx < numIndex; idx++) {
                        final String className = (String) ois.readObject();
                        ByteRangeComparator comp = dbman.getComparatorInstances().get(className);
                        if (comp == null) {
                            Class<?> clazz = Class.forName(className);
                            comp = (ByteRangeComparator) clazz.newInstance();
                            dbman.getComparatorInstances().put(className, comp);
                        }
                       
                        assert (comp != null);
                        comps[idx] = comp;
                    }
                   
                    if (!conversionRequired) {
                        DatabaseInternal db = new DatabaseImpl(this.dbs,
                                new LSMDatabase(dbName, dbId, this.dbs.getConfig().getBaseDir()
                            + dbName + File.separatorChar, numIndex, true, comps, dbs.getConfig()
                                .getCompression(), this.dbs.getConfig().getMaxNumRecordsPerBlock(),
                                dbs.getConfig().getMaxBlockFileSize(), dbs.getConfig().getDisableMMap(),
                                dbs.getConfig().getMMapLimit()));
                        dbman.putDatabase(db);
                        Logging.logMessage(Logging.LEVEL_DEBUG, this, "loaded DB " + dbName
                            + "(" + dbId + ") successfully.");
                    }
                }
            }
           
        } catch (InstantiationException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR, "cannot instantiate comparator", ex);
        } catch (IllegalAccessException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR, "cannot instantiate comparator", ex);
        } catch (IOException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR,
                "cannot load database config, check path and access rights", ex);
        } catch (ClassNotFoundException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR,
                "cannot load database config, config file might be corrupted", ex);
        } catch (ClassCastException ex) {
            throw new BabuDBException(ErrorCode.IO_ERROR,
                "cannot load database config, config file might be corrupted", ex);
        } finally {
            if (ois != null)
                try {
                    ois.close();
                } catch (IOException e) {
                    /* who cares? */
                }
        }
    }
   
    /**
     * saves the current database config to disk
     *
     * @param filename
     *            path to the config file location
     * @throws BabuDBException
     */
    public void save(String filename) throws BabuDBException {
        DatabaseManagerInternal dbman = dbs.getDatabaseManager();
       
        synchronized (dbman.getDBModificationLock()) {
            try {
                File tempFile = new File(filename + ".in_progress");
                FileOutputStream fos = new FileOutputStream(tempFile);
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                oos.writeInt(BABUDB_DB_FORMAT_VERSION);
                oos.writeInt(dbman.getAllDatabaseIds().size());
                oos.writeInt(dbman.getNextDBId());
                for (int dbId : dbman.getAllDatabaseIds()) {
                    LSMDatabase db = dbman.getDatabase(dbId).getLSMDB();
                    oos.writeObject(db.getDatabaseName());
                    oos.writeInt(dbId);
                    oos.writeInt(db.getIndexCount());
                    String[] compClasses = db.getComparatorClassNames();
                    for (int i = 0; i < db.getIndexCount(); i++) {
                        oos.writeObject(compClasses[i]);
                    }
                }
               
                oos.flush();
                fos.flush();
                fos.getFD().sync();
                oos.close();
               
                File dbFile = new File(filename);
               
                // try to rename the file
                boolean success = tempFile.renameTo(dbFile);
                if (!success) {
                    // on Windows machines, the target mustn't exist; thus, it
                    // is necessary to sacrifice atomicity and delete the
                    // previous file before
                    dbFile.delete();
                    tempFile.renameTo(dbFile);
                }
               
            } catch (IOException ex) {
                throw new BabuDBException(ErrorCode.IO_ERROR, "unable to save database configuration", ex);
            }
           
        }
    }
   
    public void save() throws BabuDBException {
        save(dbs.getConfig().getBaseDir() + dbs.getConfig().getDbCfgFile());
    }
   
    public boolean isConversionRequired() {
        return conversionRequired;
    }
   
    public int getDBFormatVersion() {
        return dbFormatVer;
    }
}
TOP

Related Classes of org.xtreemfs.babudb.lsmdb.DBConfig

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.