Package elephantdb.persistence

Source Code of elephantdb.persistence.JavaBerkDB$JavaBerkDBPersistence

package elephantdb.persistence;

import com.sleepycat.je.*;
import elephantdb.document.KeyValDocument;
import elephantdb.Utils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.util.Map;

public class JavaBerkDB implements Coordinator {
    public static Logger LOG = Logger.getLogger(JavaBerkDB.class);

    public JavaBerkDB() {
        super();
    }

    public Persistence openPersistenceForRead(String root, Map options) throws IOException {
        return new JavaBerkDBPersistence(root, options, true, false);
    }

    public Persistence openPersistenceForAppend(String root, Map options) throws IOException {
        return new JavaBerkDBPersistence(root, options, false, false);
    }

    public Persistence createPersistence(String root, Map options) throws IOException {
        JavaBerkDBPersistence ret = new JavaBerkDBPersistence(root, options, false, true);
        ret.close();
        return ret;
    }

    public static class JavaBerkDBPersistence implements KeyValPersistence {
        private static final String DATABASE_NAME = "elephant";
        Environment env;
        Database db;
        public JavaBerkDBPersistence(String root, Map options,
                                     boolean readOnly, boolean allowCreate) {

            new File(root).mkdirs();
            EnvironmentConfig envConf = new EnvironmentConfig();
            envConf.setAllowCreate(allowCreate);

            envConf.setReadOnly(readOnly);
            envConf.setLocking(false);
            envConf.setTransactional(false);
            envConf.setSharedCache(true);

            // TODO: Loop through options, setConfigParam for each one.
            envConf.setConfigParam(EnvironmentConfig.CLEANER_MIN_UTILIZATION, "10");
            envConf.setConfigParam(EnvironmentConfig.CLEANER_MIN_FILE_UTILIZATION, "5");
            envConf.setConfigParam(EnvironmentConfig.ENV_RUN_CLEANER, "false");
            envConf.setConfigParam(EnvironmentConfig.LOG_FILE_MAX, "104857600"); // 100 MB

            envConf.setConfigParam(EnvironmentConfig.FILE_LOGGING_LEVEL, "ALL");
            envConf.setConfigParam(EnvironmentConfig.CONSOLE_LOGGING_LEVEL, "ALL");
           
            env = new Environment(new File(root), envConf);
           
            DatabaseConfig dbConf = new DatabaseConfig();
            dbConf.setAllowCreate(allowCreate);
            dbConf.setReadOnly(readOnly);
            dbConf.setDeferredWrite(true);
           
            dbConf.setNodeMaxEntries(512);

            db = env.openDatabase(null, DATABASE_NAME, dbConf);
        }

        public byte[] get(byte[] key) throws IOException {
            EnvironmentConfig envConf = env.getConfig();
           
            DatabaseEntry chrysalis = new DatabaseEntry();

            OperationStatus stat = db.get(null, new DatabaseEntry(key), chrysalis, LockMode.READ_UNCOMMITTED);
            if (stat == OperationStatus.SUCCESS) {
                return chrysalis.getData();
            } else {
                LOG.debug("Lookup failed in " + env.getHome() + ": " + stat);
                return null;
            }
        }

        public void put(byte[] key, byte[] value) throws IOException {
            index(new KeyValDocument(key, value));
        }

        private void add(byte[] key, byte[] value) throws IOException {
            db.put(null, new DatabaseEntry(key), new DatabaseEntry(value));
        }

        public void index(KeyValDocument document) throws IOException {
            add(document.key, document.value);
        }

        public void close() throws IOException {
            if (!db.getConfig().getReadOnly()) {
                LOG.info("Syncing environment at " + env.getHome().getPath());
                env.sync();
                LOG.info("Done syncing environment at " + env.getHome().getPath());

                LOG.info("Cleaning environment log at " + env.getHome().getPath());
                boolean anyCleaned = false;
                while (env.cleanLog() > 0) {
                    anyCleaned = true;
                }
                LOG.info("Done cleaning environment log at " + env.getHome().getPath());
                if (anyCleaned) {
                    LOG.info("Checkpointing environment at " + env.getHome().getPath());
                    CheckpointConfig checkpoint = new CheckpointConfig();
                    checkpoint.setForce(true);
                    env.checkpoint(checkpoint);
                    LOG.info("Done checkpointing environment at " + env.getHome().getPath());
                }
            }

            db.close();
            env.close();
        }

        public CloseableIterator<KeyValDocument> iterator() {
            return new CloseableIterator<KeyValDocument>() {
                Cursor cursor = null;
                KeyValDocument next = null;

                private void cacheNext() {
                    DatabaseEntry key = new DatabaseEntry();
                    DatabaseEntry val = new DatabaseEntry();

                    // cursor stores the next key and value in the above mutable objects.
                    OperationStatus stat = cursor.getNext(key, val, LockMode.READ_UNCOMMITTED);
                    if (stat == OperationStatus.SUCCESS) {
                        next = new KeyValDocument(key.getData(), val.getData());
                    } else {
                        next = null;
                        close();
                    }
                }

                private void initCursor() {
                    if (cursor == null) {
                        cursor = db.openCursor(null, null);
                        cacheNext();
                    }
                }

                public boolean hasNext() {
                    initCursor();
                    return next != null;
                }

                public KeyValDocument next() {
                    initCursor();
                    if (next == null) { throw new RuntimeException("No key/value pair available"); }
                    KeyValDocument ret = next;
                    cacheNext(); // caches up n + 1,
                    return ret;  // return the old.
                }

                public void remove() {
                    throw new UnsupportedOperationException("Not supported.");
                }

                public void close() {
                    if (cursor != null)
                        cursor.close();
                }

            };
        }
    }

}
TOP

Related Classes of elephantdb.persistence.JavaBerkDB$JavaBerkDBPersistence

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.