Package org.nemesis.forum.impl

Source Code of org.nemesis.forum.impl.UserPermsCache

/*
* NEMESIS-FORUM.
* Copyright (C) 2002  David Laurent(lithium2@free.fr). All rights reserved.
*
* Copyright (c) 2000 The Apache Software Foundation. All rights reserved.
*
* Copyright (C) 2001 Yasna.com. All rights reserved.
*
* Copyright (C) 2000 CoolServlets.com. All rights reserved.
*
* NEMESIS-FORUM. is free software; you can redistribute it and/or
* modify it under the terms of the Apache Software License, Version 1.1,
* or (at your option) any later version.
*
* NEMESIS-FORUM core framework, NEMESIS-FORUM backoffice, NEMESIS-FORUM frontoffice
* application are parts of NEMESIS-FORUM and are distributed under
* same terms of licence.
*
*
* NEMESIS-FORUM includes software developed by the Apache Software Foundation (http://www.apache.org/)
* and software developed by CoolServlets.com (http://www.coolservlets.com).
* and software developed by Yasna.com (http://www.yasna.com).
*
*/
package org.nemesis.forum.impl;

import org.nemesis.forum.util.cache.Cache;
import org.nemesis.forum.util.cache.CacheObject;
import org.nemesis.forum.util.cache.Cacheable;

/**
* Central cache management of all caches.
*/
public class DbCacheManager {

  public static int USER_CACHE = 0;
  public static int USER_ID_CACHE = 1;
  public static int GROUP_CACHE = 2;
  public static int GROUP_ID_CACHE = 3;
  public static int FORUM_CACHE = 4;
  public static int FORUM_ID_CACHE = 5;
  public static int THREAD_CACHE = 6;
  public static int MESSAGE_CACHE = 7;
  public static int USER_PERMS_CACHE = 8;

  protected Cache[] caches;

  private boolean cacheEnabled = true;

  public DbCacheManager() {
    int MINUTE = 1000 * 60;
    int HOUR = MINUTE * 60;

    caches = new Cache[9];

    //Initialize all cache structures
    caches[USER_CACHE] = new Cache(256 * 1024, 6 * HOUR);
    caches[USER_ID_CACHE] = new Cache(128 * 1024, 6 * HOUR);
    caches[GROUP_CACHE] = new Cache(128 * 1024, 6 * HOUR);
    caches[GROUP_ID_CACHE] = new Cache(128 * 1024, 6 * HOUR);
    caches[FORUM_CACHE] = new Cache(128 * 1024, 6 * HOUR);
    caches[FORUM_ID_CACHE] = new Cache(128 * 1024, 6 * HOUR);
    caches[THREAD_CACHE] = new Cache(128 * 1024, 6 * HOUR);
    caches[MESSAGE_CACHE] = new Cache(512 * 1024, 6 * HOUR);
    //The user permissions cache is a special one. It's actually a Cache
    //of Cache objects. Each of the cache objects in the main cache
    //corresponds to a particular forum, and is used to cache the
    //permissions that a user has for a forum. In order to handle this
    //requirement, we use a special subclass of Cache.
    caches[USER_PERMS_CACHE] = new UserPermsCache(256 * 1024, 24 * HOUR);
  }

  public Cache getCache(int cacheType) {
    return caches[cacheType];
  }

  public void add(int cacheType, Object key, Cacheable object) {
    caches[cacheType].add(key, object);
  }

  public Cacheable get(int cacheType, Object key) {
    if (!cacheEnabled) {
      return null;
    }
    return caches[cacheType].get(key);
  }

  public void remove(int cacheType, Object key) {
    caches[cacheType].remove(key);
    //when cache becomes distributed, we'd send out an expire message
    //here to all other yazd servers.
  }

  public void removeUserPerm(Object userID) {
    Object[] values = caches[USER_PERMS_CACHE].values().toArray();
    for (int i = 0; i < values.length; i++) {
      Cache cache = (Cache) ((CacheObject) values[i]).object;
      cache.remove(userID);
    }
    //when cache becomes distributed, we'd send out an expire message
    //here to all other yazd servers.
  }

  public void removeUserPerm(Object userID, Object forumID) {
    Cache cache = (Cache) caches[USER_PERMS_CACHE].get(forumID);
    if (cache != null) {
      cache.remove(userID);
    }
    //when cache becomes distributed, we'd send out an expire message
    //here to all other yazd servers.
  }

  public void clear(int cacheType) {
    caches[cacheType].clear();
    //when cache becomes distributed, we'd send out an expire message
    //here to all other yazd servers.
  }

  public boolean isCacheEnabled() {
    return cacheEnabled;
  }

  public void setCacheEnabled(boolean cacheEnabled) {
    this.cacheEnabled = cacheEnabled;
  }
}

/**
* Special purpose Cache to hold all of the different user permission cache
* objects. The main feature is that new caches are automatically created so
* that calling get() never returns null.
*/
class UserPermsCache extends Cache {

  public UserPermsCache(int size, long expireTime) {
    super(size, expireTime);
  }

  public synchronized Cacheable get(Object key) {
    Cache subCache = (Cache) super.get(key);
    if (subCache == null) {
      //cache has expired, or is not there, so put a new one in there.
      //Cache objects only need to last as long as a user's session
      //does. Half an hour is a reasonable amount of time for this.
      subCache = new Cache(2 * 1024, 30 * 1000 * 60);
      add(key, subCache);
    }
    return subCache;
  }

  public synchronized void remove(Object key) {
    CacheObject cacheObject = (CacheObject) cachedObjectsHash.get(key);
    //If the object is not in cache, stop trying to remove it.
    if (cacheObject == null) {
      return;
    }
    //remove from the hash map
    cachedObjectsHash.remove(key);
    //remove from the cache order list
    cacheObject.lastAccessedListNode.remove();
    cacheObject.ageListNode.remove();
    //remove references to linked list nodes
    cacheObject.ageListNode = null;
    cacheObject.lastAccessedListNode = null;
    //removed the object, so subtract its size from the total.
    size -= cacheObject.size;

    //Finally, clear the sub-cache to make sure memory is released.
     ((Cache) cacheObject.object).clear();
  }

  /**
   * Returns the current size in bytes of the cache. The base getSize() method
   * does not work correctly because the sub-caches are empty when we first
   * add them rather than the normal cache assumption that objects are near
   * the size that they will always be.
   *
   * @return the size of the cache in bytes.
   */
  public int getSize() {
    int size = 0;
    Object[] values = values().toArray();
    for (int i = 0; i < values.length; i++) {
      Cache cache = (Cache) values[i];
      size += cache.getSize();
    }
    return size;
  }
}
TOP

Related Classes of org.nemesis.forum.impl.UserPermsCache

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.