/* * This file is part of the HyperGraphDB source distribution. This is copyrighted * software. For permitted uses, licensing options and redistribution, please see * the LicensingInformation file at the root level of the distribution. * * Copyright (c) 2005-2010 Kobrix Software, Inc. All rights reserved. */ package org.hypergraphdb.cache; import org.hypergraphdb.HGEnvironment; import org.hypergraphdb.util.MemoryWarningSystem; import org.hypergraphdb.util.SimplyLinkedQueue; /** * The purpose of this class is just to keep references to atoms in the WeakRefAtomCache * for a little while so that they don't get evicted as soon as the garbage collector * collects them because they are not referred to anymore in the program. * * The term "cold" means "not really frozen" :) * * @author Boris * */ public class ColdAtoms { public static int DEFAULT_BUCKET_SIZE = 2000; int bucket_size; int evictFactor = 3; // evict 1/3 of elements when memory is about to fill up private SimplyLinkedQueue<Object []> buckets = new SimplyLinkedQueue<Object[]>(); int pos = 0; private MemoryWarningSystem.Listener memListener = new MemoryWarningSystem.Listener() { public void memoryUsageLow(long usedMemory, long maxMemory) { // System.out.println("FREE COLD ATOMS START " + Runtime.getRuntime().freeMemory() + " - " + buckets.size()); synchronized (buckets) { int cnt = buckets.size() / evictFactor; if (cnt == 0) cnt = buckets.size() > 0 ? 1 : 0; while (cnt-- > 0) buckets.fetch(); } //2012.02.02 System.gc(); // System.out.println("FREE COLD ATOMS END " + Runtime.getRuntime().freeMemory() + " - " + buckets.size()); } }; private void initMemoryListener() { HGEnvironment.getMemoryWarningSystem().addListener(memListener); } public ColdAtoms() { this(DEFAULT_BUCKET_SIZE); initMemoryListener(); } /** * * @param capacity * @param bucket_size */ public ColdAtoms(int bucket_size) { this.bucket_size = bucket_size; buckets.put(new Object[bucket_size]); } public void add(Object atom) { synchronized (buckets) { if (pos >= bucket_size || buckets.size() == 0) { buckets.put(new Object[bucket_size]); pos = 0; } buckets.peekBack()[pos++] = atom; } } public int size() { return bucket_size*buckets.size(); } }