Package io.conducive.server.db.impl

Source Code of io.conducive.server.db.impl.AbstractMapDBDao

package io.conducive.server.db.impl;

import com.google.common.collect.Lists;
import io.conducive.server.bind.DBFile;
import org.mapdb.DB;
import org.mapdb.Fun;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.inject.Inject;
import java.io.File;
import java.nio.file.FileStore;
import java.nio.file.Files;
import java.util.*;

import static com.google.common.base.Preconditions.*;

/**
* @author Reuben Firmin
*/
public class AbstractMapDBDao {

    final Logger logger = LoggerFactory.getLogger(getClass());
    final File dbFile;
    final DB db;

    @Inject
    public AbstractMapDBDao(@DBFile final File dbFile, final DB db) {
        this.dbFile = dbFile;
        this.db = db;
    }

    protected void commit() {
        db.commit();
    }

    public boolean enoughDiskSpace() {
        try {
            FileStore fs = Files.getFileStore(dbFile.toPath());
            // we want 20% of the partition free
            return ((double) fs.getTotalSpace() / (double) fs.getUsableSpace()) > 1.25;
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return false;
        }
    }

    /**
     * Create / retrieve a one to many collection.
     */
    protected <S, T> NavigableSet<Fun.Tuple2<S, T>> oneToMany(final String name) {
        return db.getTreeSet(name);
    }

    /**
     * Create / retrieve a one to one collection.
     */
    protected <S, T> NavigableMap<S, T> oneToOne(final String name) {
        return db.getTreeMap(name);
    }

    /**
     * Get items associated with this key.
     */
    protected <S, T> Iterable<T> get(NavigableSet<Fun.Tuple2<S, T>> oneToMany, S key) {
        return Fun.filter(oneToMany, key);
    }

    /**
     * Get single item associated with this key.
     */
    protected <S, T> T get(NavigableMap<S, T> oneToOne, S key) {
        return oneToOne.get(key);
    }

    /**
     * Put an item into the oneToMany.
     */
    protected <S, T> void put(NavigableSet<Fun.Tuple2<S, T>> oneToMany, S key, T item) {
        remove(oneToMany, key, item);
        oneToMany.add(Fun.t2(key, item));
    }

    /**
     * Put an item into the oneToOne.
     */
    protected <S, T> void put(NavigableMap<S, T> oneToOne, S key, T item) {
        oneToOne.put(key, item);
    }

    /**
     * Remove an item.
     */
    protected <S, T> void remove(NavigableSet<Fun.Tuple2<S, T>> oneToMany, S key, T item) {
        oneToMany.remove(Fun.t2(key, item));
    }

    /**
     * Remove all items mapped to this key, and the key itself.
     */
    protected <S, T> void remove(NavigableSet<Fun.Tuple2<S, T>> oneToMany, S key) {
        List<T> ts = Lists.newLinkedList(get(oneToMany, key));
        for (T t : ts) {
            remove(oneToMany, key, t);
        }
    }

    /**
     * Remove an item.
     */
    protected <S, T> void remove(NavigableMap<S, T> oneToOne, S key) {
        oneToOne.remove(key);
    }

    /**
     * Check if a mapping exists.
     * @return
     */
    protected <S, T> boolean exists(NavigableSet<Fun.Tuple2<S, T>> oneToMany, S key, T item) {
        Iterable<T> mapped = get(oneToMany, key);
        if (mapped != null) {
            for (T mappedItem : mapped) {
                if (item.equals(mappedItem)) {
                    return true;
                }
            }
        }
        return false;
    }

    protected <S> boolean exists(NavigableMap<S, ?> oneToOne, S key) {
        return oneToOne.get(key) != null;
    }


    // ------------------ EXPERIMENTAL STUFF BELOW -------------------------------------- //

    /**
     * TODO - in progress (experimental)
     * Create / retrieve a model store. This is a map of id -> entity.
     */
    protected <E extends Entity> LookupTable<String, E> table(final Class<E> entityClazz) {
        return new LookupTable<String, E>() {
            Map<String, E> map = oneToOne(entityClazz.getName());

            @Override
            public E get(String s) {
                checkNotNull(s);
                return map.get(s);
            }

            @Override
            public void put(String s, E e) {
                checkNotNull(s);
                checkNotNull(e);
                checkNotNull(e.getId());
                map.put(s, e);
            }
        };
    }

    /**
     * TODO - in progress
     * Create / retrieve a structure that maps keys to models.
     * @return
     */
    protected <K, E extends Entity> LookupTable<K, E> lookup(final Class<E> entityClazz, final Class<K> keyClazz) {
        if (Entity.class.isAssignableFrom(keyClazz)) {
            throw new RuntimeException("Use foreignKey instead");
        }
        return new LookupTable<K, E>() {
            Map<K, String> map = oneToOne(entityClazz.getName() + "_" + keyClazz.getName());

            @Override
            public E get(K k) {
                checkNotNull(k);
                return table(entityClazz).get(map.get(k));
            }

            @Override
            public void put(K k, E e) {
                checkNotNull(k);
                checkNotNull(e.getId());
                // make sure we're storing it in the main datastore
                checkNotNull(AbstractMapDBDao.this.<E>table(entityClazz).get(e.getId()));

                map.put(k, e.getId());
            }
        };
    }

    /**
     * TODO - in progress
     * Create / retrieve a structure that maps one entity to another.
     * @return
     */
    protected <K extends Entity, E extends Entity> LookupTable<K, E> foreignKey(final Class<K> keyEntityClass, final Class<E> entityClass) {
        return new LookupTable<K, E>() {
            // key id -> entity id
            Map<String, String> map = oneToOne(keyEntityClass.getName() + "_" + entityClass.getName());

            @Override
            public E get(K k) {
                checkNotNull(k.getId());
                if (AbstractMapDBDao.this.<K>table(keyEntityClass).get(k.getId()) == null) {
                    throw new RuntimeException("Must store key prior to using it for lookup");
                }
                return AbstractMapDBDao.this.<E>table(entityClass).get(map.get(k.getId()));
            }

            @Override
            public void put(K k, E e) {
                if (AbstractMapDBDao.this.<K>table(keyEntityClass).get(k.getId()) == null) {
                    throw new RuntimeException("Must store key prior to using it for mapping");
                }
                map.put(k.getId(), e.getId());
            }
        };
    }
}
TOP

Related Classes of io.conducive.server.db.impl.AbstractMapDBDao

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.