de.rwhq.io.rm.CachedResourceManager.java Source code

Java tutorial

Introduction

Here is the source code for de.rwhq.io.rm.CachedResourceManager.java

Source

/*
 * This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported License:
 *
 * http://creativecommons.org/licenses/by-nc/3.0/
 *
 * For alternative conditions contact the author.
 *
 * Copyright (c) 2011 "Robin Wenglewski <robin@wenglewski.de>"
 */

package de.rwhq.io.rm;

import com.google.common.base.Objects;
import com.google.common.cache.*;

import java.io.IOException;
import java.util.concurrent.ExecutionException;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * This class caches RawPages coming from a ResourceManager. Through the caching, we can ensure that pages are written
 * back to the ResourceManager even if they are not explicitly persisted in the using class.
 * <p/>
 * Additionally, if a Page is requested which is not in cache but still in Memory (meaning that maybe it's still being
 * used), then the memory instance is added to the cache and returned.
 * <p/>
 * CachedResourceManager works with all kinds of ResourceManagers, although usually used with a {@link
 * FileResourceManager}
 */
public class CachedResourceManager implements ResourceManager {

    private final ResourceManager rm;
    private final Cache<Integer, RawPage> cache;
    private final int cacheSize;

    CachedResourceManager(final ResourceManager _rm, final int cacheSize) {
        checkNotNull(_rm);
        checkArgument(cacheSize > 0, "cacheSize must be > 0");

        this.rm = _rm;
        this.cacheSize = cacheSize;
        this.cache = CacheBuilder.newBuilder().maximumSize(cacheSize)
                .removalListener(new RemovalListener<Integer, RawPage>() {
                    @Override
                    public void onRemoval(
                            final RemovalNotification<Integer, RawPage> integerRawPageRemovalNotification) {
                        final RawPage rawPage = integerRawPageRemovalNotification.getValue();
                        rawPage.sync();
                    }
                }).build(new CacheLoader<Integer, RawPage>() {
                    @Override
                    public RawPage load(final Integer key) throws Exception {
                        return rm.getPage(key);
                    }
                });

    }

    public int getCacheSize() {
        return cacheSize;
    }

    @Override
    public void writePage(final RawPage page) {
        cache.asMap().put(page.id(), page);
        rm.writePage(page);
    }

    @Override
    public Integer getPageSize() {
        return rm.getPageSize();
    }

    @Override
    public void open() throws IOException {
        rm.open();
    }

    @Override
    public boolean isOpen() {
        return rm.isOpen();
    }

    @Override
    public void close() throws IOException {
        sync();
        cache.invalidateAll();
        rm.close();
    }

    @Override
    public int numberOfPages() {
        return rm.numberOfPages();
    }

    @Override
    public void clear() {
        cache.invalidateAll();
        rm.clear();
    }

    @Override
    public RawPage createPage() {
        final RawPage page = rm.createPage();
        cache.asMap().put(page.id(), page);
        return page;
    }

    @Override
    public RawPage getPage(final int id) {
        try {
            return cache.get(id);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void removePage(final int id) {
        cache.invalidate(id);
        rm.removePage(id);
    }

    @Override
    public boolean hasPage(final int id) {
        return rm.hasPage(id);
    }

    public void sync() {
        for (final RawPage p : cache.asMap().values()) {
            p.sync();
        }
    }

    public ResourceManager getResourceManager() {
        return rm;
    }

    public Cache<Integer, RawPage> getCache() {
        return cache;
    }

    public String toString() {
        return Objects.toStringHelper(this).add("maxCacheSize", cacheSize).add("cacheSize", cache.asMap().size())
                .add("cacheStats", cache.stats()).add("resourceManager", rm).toString();
    }
}