Package com.sleepycat.je.dbi

Source Code of com.sleepycat.je.dbi.MemoryBudget

/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2006
*      Sleepycat Software.  All rights reserved.
*
* $Id: MemoryBudget.java,v 1.47 2006/01/09 12:41:51 cwl Exp $
*/

package com.sleepycat.je.dbi;

import java.util.Iterator;

import com.sleepycat.je.DatabaseException;
import com.sleepycat.je.EnvironmentStats;
import com.sleepycat.je.StatsConfig;
import com.sleepycat.je.config.EnvironmentParams;
import com.sleepycat.je.latch.LatchSupport;
import com.sleepycat.je.tree.BIN;
import com.sleepycat.je.tree.DBIN;
import com.sleepycat.je.tree.DIN;
import com.sleepycat.je.tree.IN;

/**
* MemoryBudget calculates the available memory for JE and how to apportion
* it between cache and log buffers. It is meant to centralize all memory
* calculations. Objects that ask for memory budgets should get settings from
* this class, rather than using the configuration parameter values directly.
*/
public class MemoryBudget implements EnvConfigObserver {

    /*
     * Object overheads. These are set statically with advance measurements.
     * Java doesn't provide a way of assessing object size dynamically. These
     * overheads will not be precise, but are close enough to let the system
     * behave predictably.
     *
     * _32 values are the same on Windows and Solaris.
     * _64 values are from 1.5.0_05 on Solaris.
     * _14 values are from 1.4.2 on Windows and Solaris.
     * _15 values are from 1.5.0_05 on Solaris and Windows.
     *
     * Specifically:
     *
     * java.vm.version=1.5.0_05_b05 os.name=SunOS
     * java.vm.version=1.4.2_05_b04 os.name=SunOS
     * java.vm.version=1.5.0_04_b05, os.name=Windows XP
     * java.vm.version=1.4.2_06-b03, os.name=Windows XP
     *
     * The integer following the // below is the Sizeof argument used to
     * compute the value.
     */

    // 7
    private final static int LONG_OVERHEAD_32 = 16;
    private final static int LONG_OVERHEAD_64 = 24;

    // 8 - 2560
    private final static int BYTE_ARRAY_OVERHEAD_32 = 16;
    private final static int BYTE_ARRAY_OVERHEAD_64 = 24;

    // 2
    private final static int OBJECT_OVERHEAD_32 = 8;
    private final static int OBJECT_OVERHEAD_64 = 16;

    // (4 - BYTE_ARRAY_OVERHEAD_32) / 256
    private final static int ARRAY_ITEM_OVERHEAD_32 = 4;
    private final static int ARRAY_ITEM_OVERHEAD_64 = 8;

    // 20
    private final static int HASHMAP_OVERHEAD_32 = 120;
    private final static int HASHMAP_OVERHEAD_64 = 216;

    // 21 - OBJECT_OVERHEAD_32 - HASHMAP_OVERHEAD_32
    private final static int HASHMAP_ENTRY_OVERHEAD_32 = 24;
    private final static int HASHMAP_ENTRY_OVERHEAD_64 = 48;

    // 22
    private final static int HASHSET_OVERHEAD_32 = 136;
    private final static int HASHSET_OVERHEAD_64 = 240;

    // 23 - OBJECT_OVERHEAD_32 - HASHSET_OVERHEAD_32
    private final static int HASHSET_ENTRY_OVERHEAD_32 = 24;
    private final static int HASHSET_ENTRY_OVERHEAD_64 = 48;

    // 2 * HASHMAP_OVERHEAD_32
    private final static int TWOHASHMAPS_OVERHEAD_32 = 240;
    private final static int TWOHASHMAPS_OVERHEAD_64 = 432;

    // 34
    private final static int TREEMAP_OVERHEAD_32 = 40;
    private final static int TREEMAP_OVERHEAD_64 = 64;

    // 35 - OBJECT_OVERHEAD_32 - TREEMAP_OVERHEAD_32
    private final static int TREEMAP_ENTRY_OVERHEAD_32 = 32;
    private final static int TREEMAP_ENTRY_OVERHEAD_64 = 53;

    // 9
    private final static int LN_OVERHEAD_32 = 24;
    private final static int LN_OVERHEAD_64 = 32;

    // 19
    private final static int DUPCOUNTLN_OVERHEAD_32 = 24;
    private final static int DUPCOUNTLN_OVERHEAD_64 = 40;

    // 12
    private final static int BIN_FIXED_OVERHEAD_32_14 = 344;
    private final static int BIN_FIXED_OVERHEAD_32_15 = 360;
    private final static int BIN_FIXED_OVERHEAD_64_15 = 528;

    // 18
    private final static int DIN_FIXED_OVERHEAD_32_14 = 352;
    private final static int DIN_FIXED_OVERHEAD_32_15 = 360;
    private final static int DIN_FIXED_OVERHEAD_64_15 = 536;

    // 17
    private final static int DBIN_FIXED_OVERHEAD_32_14 = 352;
    private final static int DBIN_FIXED_OVERHEAD_32_15 = 368;
    private final static int DBIN_FIXED_OVERHEAD_64_15 = 544;

    // 13
    private final static int IN_FIXED_OVERHEAD_32_14 = 312;
    private final static int IN_FIXED_OVERHEAD_32_15 = 320;
    private final static int IN_FIXED_OVERHEAD_64_15 = 472;

    // 6
    private final static int KEY_OVERHEAD_32 = 16;
    private final static int KEY_OVERHEAD_64 = 24;

    // 24
    private final static int LOCK_OVERHEAD_32 = 32;
    private final static int LOCK_OVERHEAD_64 = 56;

    // 25
    private final static int LOCKINFO_OVERHEAD_32 = 16;
    private final static int LOCKINFO_OVERHEAD_64 = 32;

    /*
     * Txn memory is the size for the Txn + a hashmap entry
     * overhead for being part of the transaction table.
     */
    // 15
    private final static int TXN_OVERHEAD_32_14 = 167;
    private final static int TXN_OVERHEAD_32_15 = 175;
    private final static int TXN_OVERHEAD_64_15 = 293;

    // 26
    private final static int CHECKPOINT_REFERENCE_SIZE_32_14 = 32 +
        HASHSET_ENTRY_OVERHEAD_32;
    private final static int CHECKPOINT_REFERENCE_SIZE_32_15 = 40 +
        HASHSET_ENTRY_OVERHEAD_32;
    private final static int CHECKPOINT_REFERENCE_SIZE_64_15 = 56 +
        HASHSET_ENTRY_OVERHEAD_64;

    /* The per-log-file bytes used in UtilizationProfile. */
    // 29 / 500
    private final static int UTILIZATION_PROFILE_ENTRY_32 = 88;
    private final static int UTILIZATION_PROFILE_ENTRY_64 = 136;

    /* Tracked File Summary overheads. */
    // 31
    private final static int TFS_LIST_INITIAL_OVERHEAD_32 = 464;
    private final static int TFS_LIST_INITIAL_OVERHEAD_64 = 504;

    // 30
    private final static int TFS_LIST_SEGMENT_OVERHEAD_32 = 440;
    private final static int TFS_LIST_SEGMENT_OVERHEAD_64 = 464;

    // 33
    private final static int LN_INFO_OVERHEAD_32 = 24;
    private final static int LN_INFO_OVERHEAD_64 = 48;

    /* Approximate element size in an ArrayList of Long. */
    // (28 - 27) / 100
    private final static int LONG_LIST_PER_ITEM_OVERHEAD_32 = 20;
    private final static int LONG_LIST_PER_ITEM_OVERHEAD_64 = 32;

    public final static int LONG_OVERHEAD;
    public final static int BYTE_ARRAY_OVERHEAD;
    public final static int OBJECT_OVERHEAD;
    public final static int ARRAY_ITEM_OVERHEAD;
    public final static int HASHMAP_OVERHEAD;
    public final static int HASHMAP_ENTRY_OVERHEAD;
    public final static int HASHSET_OVERHEAD;
    public final static int HASHSET_ENTRY_OVERHEAD;
    public final static int TWOHASHMAPS_OVERHEAD;
    public final static int TREEMAP_OVERHEAD;
    public final static int TREEMAP_ENTRY_OVERHEAD;
    public final static int LN_OVERHEAD;
    public final static int DUPCOUNTLN_OVERHEAD;
    public final static int BIN_FIXED_OVERHEAD;
    public final static int DIN_FIXED_OVERHEAD;
    public final static int DBIN_FIXED_OVERHEAD;
    public final static int IN_FIXED_OVERHEAD;
    public final static int KEY_OVERHEAD;
    public final static int LOCK_OVERHEAD;
    public final static int LOCKINFO_OVERHEAD;
    public final static int TXN_OVERHEAD;
    public final static int CHECKPOINT_REFERENCE_SIZE;
    public final static int UTILIZATION_PROFILE_ENTRY;
    public final static int TFS_LIST_INITIAL_OVERHEAD;
    public final static int TFS_LIST_SEGMENT_OVERHEAD;
    public final static int LN_INFO_OVERHEAD;
    public final static int LONG_LIST_PER_ITEM_OVERHEAD;

    private final static String JVM_ARCH_PROPERTY = "sun.arch.data.model";
    private final static String FORCE_JVM_ARCH = "je.forceJVMArch";

    static {
  boolean is64 = false;
  boolean isJVM14 = (LatchSupport.getJava5LatchClass() == null);
  String overrideArch = System.getProperty(FORCE_JVM_ARCH);
  try {
      if (overrideArch == null) {
    String arch = System.getProperty(JVM_ARCH_PROPERTY);
    if (arch != null) {
        is64 = Integer.parseInt(arch) == 64;
    }
      } else {
    is64 = Integer.parseInt(overrideArch) == 64;
      }
  } catch (NumberFormatException NFE) {
      NFE.printStackTrace(System.err);
  }

  if (is64) {
      if (isJVM14) {
    RuntimeException RE = new RuntimeException
        ("1.4 based 64 bit JVM not supported");
    RE.printStackTrace(System.err);
    throw RE;
      }
      LONG_OVERHEAD = LONG_OVERHEAD_64;
      BYTE_ARRAY_OVERHEAD = BYTE_ARRAY_OVERHEAD_64;
      OBJECT_OVERHEAD = OBJECT_OVERHEAD_64;
      ARRAY_ITEM_OVERHEAD = ARRAY_ITEM_OVERHEAD_64;
      HASHMAP_OVERHEAD = HASHMAP_OVERHEAD_64;
      HASHMAP_ENTRY_OVERHEAD = HASHMAP_ENTRY_OVERHEAD_64;
      HASHSET_OVERHEAD = HASHSET_OVERHEAD_64;
      HASHSET_ENTRY_OVERHEAD = HASHSET_ENTRY_OVERHEAD_64;
      TWOHASHMAPS_OVERHEAD = TWOHASHMAPS_OVERHEAD_64;
      TREEMAP_OVERHEAD = TREEMAP_OVERHEAD_64;
      TREEMAP_ENTRY_OVERHEAD = TREEMAP_ENTRY_OVERHEAD_64;
      LN_OVERHEAD = LN_OVERHEAD_64;
      DUPCOUNTLN_OVERHEAD = DUPCOUNTLN_OVERHEAD_64;
      BIN_FIXED_OVERHEAD = BIN_FIXED_OVERHEAD_64_15;
      DIN_FIXED_OVERHEAD = DIN_FIXED_OVERHEAD_64_15;
      DBIN_FIXED_OVERHEAD = DBIN_FIXED_OVERHEAD_64_15;
      IN_FIXED_OVERHEAD = IN_FIXED_OVERHEAD_64_15;
      TXN_OVERHEAD = TXN_OVERHEAD_64_15;
      CHECKPOINT_REFERENCE_SIZE = CHECKPOINT_REFERENCE_SIZE_64_15;
      KEY_OVERHEAD = KEY_OVERHEAD_64;
      LOCK_OVERHEAD = LOCK_OVERHEAD_64;
      LOCKINFO_OVERHEAD = LOCKINFO_OVERHEAD_64;
      UTILIZATION_PROFILE_ENTRY = UTILIZATION_PROFILE_ENTRY_64;
      TFS_LIST_INITIAL_OVERHEAD = TFS_LIST_INITIAL_OVERHEAD_64;
      TFS_LIST_SEGMENT_OVERHEAD = TFS_LIST_SEGMENT_OVERHEAD_64;
      LN_INFO_OVERHEAD = LN_INFO_OVERHEAD_64;
      LONG_LIST_PER_ITEM_OVERHEAD = LONG_LIST_PER_ITEM_OVERHEAD_64;
  } else {
      LONG_OVERHEAD = LONG_OVERHEAD_32;
      BYTE_ARRAY_OVERHEAD = BYTE_ARRAY_OVERHEAD_32;
      OBJECT_OVERHEAD = OBJECT_OVERHEAD_32;
      ARRAY_ITEM_OVERHEAD = ARRAY_ITEM_OVERHEAD_32;
      HASHMAP_OVERHEAD = HASHMAP_OVERHEAD_32;
      HASHMAP_ENTRY_OVERHEAD = HASHMAP_ENTRY_OVERHEAD_32;
      HASHSET_OVERHEAD = HASHSET_OVERHEAD_32;
      HASHSET_ENTRY_OVERHEAD = HASHSET_ENTRY_OVERHEAD_32;
      TWOHASHMAPS_OVERHEAD = TWOHASHMAPS_OVERHEAD_32;
      TREEMAP_OVERHEAD = TREEMAP_OVERHEAD_32;
      TREEMAP_ENTRY_OVERHEAD = TREEMAP_ENTRY_OVERHEAD_32;
      LN_OVERHEAD = LN_OVERHEAD_32;
      DUPCOUNTLN_OVERHEAD = DUPCOUNTLN_OVERHEAD_32;
      if (isJVM14) {
    BIN_FIXED_OVERHEAD = BIN_FIXED_OVERHEAD_32_14;
    DIN_FIXED_OVERHEAD = DIN_FIXED_OVERHEAD_32_14;
    DBIN_FIXED_OVERHEAD = DBIN_FIXED_OVERHEAD_32_14;
    IN_FIXED_OVERHEAD = IN_FIXED_OVERHEAD_32_14;
    TXN_OVERHEAD = TXN_OVERHEAD_32_14;
    CHECKPOINT_REFERENCE_SIZE = CHECKPOINT_REFERENCE_SIZE_32_14;
      } else {
    BIN_FIXED_OVERHEAD = BIN_FIXED_OVERHEAD_32_15;
    DIN_FIXED_OVERHEAD = DIN_FIXED_OVERHEAD_32_15;
    DBIN_FIXED_OVERHEAD = DBIN_FIXED_OVERHEAD_32_15;
    IN_FIXED_OVERHEAD = IN_FIXED_OVERHEAD_32_15;
    TXN_OVERHEAD = TXN_OVERHEAD_32_15;
    CHECKPOINT_REFERENCE_SIZE = CHECKPOINT_REFERENCE_SIZE_32_15;
      }
      KEY_OVERHEAD = KEY_OVERHEAD_32;
      LOCK_OVERHEAD = LOCK_OVERHEAD_32;
      LOCKINFO_OVERHEAD = LOCKINFO_OVERHEAD_32;
      UTILIZATION_PROFILE_ENTRY = UTILIZATION_PROFILE_ENTRY_32;
      TFS_LIST_INITIAL_OVERHEAD = TFS_LIST_INITIAL_OVERHEAD_32;
      TFS_LIST_SEGMENT_OVERHEAD = TFS_LIST_SEGMENT_OVERHEAD_32;
      LN_INFO_OVERHEAD = LN_INFO_OVERHEAD_32;
      LONG_LIST_PER_ITEM_OVERHEAD = LONG_LIST_PER_ITEM_OVERHEAD_32;
  }
    }

    /* public for unit tests. */
    public final static long MIN_MAX_MEMORY_SIZE = 96 * 1024;
    public final static String MIN_MAX_MEMORY_SIZE_STRING =
  Long.toString(MIN_MAX_MEMORY_SIZE);

    private final static long N_64MB = (1 << 26);

    /*
     * Note that this class contains long fields that are accessed by multiple
     * threads, and access to these fields is intentionally not synchronized.
     * Although inaccuracies may result, correcting them is not worth the cost
     * of synchronizing every time we adjust the treeMemoryUsage or
     * miscMemoryUsage.
     */

    /*
     * Amount of memory cached for tree objects.
     */
    private long treeMemoryUsage;

    /*
     * Amount of memory cached for Txn and other objects.
     */
    private long miscMemoryUsage;

    /*
     * Used to protect treeMemoryUsage and miscMemoryUsage updates.
     */
    private Object memoryUsageSynchronizer = new Object();

    /*
     * Number of lock tables (cache of EnvironmentParams.N_LOCK_TABLES).
     */
    private int nLockTables;

    /*
     * Amount of memory cached for locks. Protected by the
     * LockManager.lockTableLatches[lockTableIndex].  Individual elements of
     * array may be negative, but the sum will be >= 0.
     */
    private long[] lockMemoryUsage;

    /*
     * Memory available to JE, based on je.maxMemory and the memory available
     * to this process.
     */
    private long maxMemory;
    private long criticalThreshold; // experimental mark for sync eviction.
                          
    /* Memory available to log buffers. */
    private long logBufferBudget;
                          
    /* Maximum allowed use of the misc budget by the UtilizationTracker. */
    private long trackerBudget;

    /*
     * Memory to hold internal nodes and misc memory (locks), controlled by the
     * evictor.  Does not include the log buffers.
     */
    private long cacheBudget;
   
    /*
     * Overheads that are a function of node capacity.
     */
    private long inOverhead;
    private long binOverhead;
    private long dinOverhead;
    private long dbinOverhead;

    private EnvironmentImpl envImpl;

    MemoryBudget(EnvironmentImpl envImpl,
                 DbConfigManager configManager)
        throws DatabaseException {

        this.envImpl = envImpl;

        /* Request notification of mutable property changes. */
        envImpl.addConfigObserver(this);

        /* Peform first time budget initialization. */
        reset(configManager);

        /*
         * Calculate IN and BIN overheads, which are a function of
         * capacity. These values are stored in this class so that they can be
         * calculated once per environment. The logic to do the calculations is
         * left in the respective node classes so it can be done properly in
         * the domain of those objects.
         */
        inOverhead = IN.computeOverhead(configManager);
        binOverhead = BIN.computeOverhead(configManager);
        dinOverhead = DIN.computeOverhead(configManager);
        dbinOverhead = DBIN.computeOverhead(configManager);
    }

    /**
     * Respond to config updates.
     */
    public void envConfigUpdate(DbConfigManager configManager)
        throws DatabaseException {

        /*
         * Reinitialize the cache budget and the log buffer pool, in that
         * order.  Do not reset the log buffer pool if the log buffer budget
         * hasn't changed, since that is expensive and may cause I/O.
         */
        long oldLogBufferBudget = logBufferBudget;
        reset(configManager);
        if (oldLogBufferBudget != logBufferBudget) {
            envImpl.getLogManager().resetPool(configManager);
        }
    }

    /**
     * Initialize at construction time and when the cache is resized.
     */
    private void reset(DbConfigManager configManager)
        throws DatabaseException {

        /*
         * Calculate the total memory allotted to JE.
         * 1. If je.maxMemory is specified, use that. Check that it's
         * not more than the jvm memory.
         * 2. Otherwise, take je.maxMemoryPercent * JVM max memory.
         */
        long newMaxMemory =
            configManager.getLong(EnvironmentParams.MAX_MEMORY);
        long jvmMemory = getRuntimeMaxMemory();

        if (newMaxMemory != 0) {
            /* Application specified a cache size number, validate it. */
            if (jvmMemory < newMaxMemory) {
                throw new IllegalArgumentException
                    (EnvironmentParams.MAX_MEMORY.getName() +
                     " has a value of " + newMaxMemory +
                     " but the JVM is only configured for " +
                     jvmMemory +
                     ". Consider using je.maxMemoryPercent.");
            }
            if (newMaxMemory < MIN_MAX_MEMORY_SIZE) {
                throw new IllegalArgumentException
                    (EnvironmentParams.MAX_MEMORY.getName() +
                     " is " + newMaxMemory +
                     " which is less than the minimum: " +
                     MIN_MAX_MEMORY_SIZE);
            }
        } else {

            /*
             * When no explicit cache size is specified and the JVM memory size
             * is unknown, assume a default sized (64 MB) heap.  This produces
             * a reasonable cache size when no heap size is known.
             */
            if (jvmMemory == Long.MAX_VALUE) {
                jvmMemory = N_64MB;
            }

            /* Use the configured percentage of the JVM memory size. */
            int maxMemoryPercent =
                configManager.getInt(EnvironmentParams.MAX_MEMORY_PERCENT);
            newMaxMemory = (maxMemoryPercent * jvmMemory) / 100;
        }

        /*
   * Calculate the memory budget for log buffering.  If the LOG_MEM_SIZE
   * parameter is not set, start by using 7% (1/16th) of the cache
   * size. If it is set, use that explicit setting.
   *
   * No point in having more log buffers than the maximum size. If
   * this starting point results in overly large log buffers,
   * reduce the log buffer budget again.
         */
        long newLogBufferBudget =
            configManager.getLong(EnvironmentParams.LOG_MEM_SIZE);     
        if (newLogBufferBudget == 0) {
      newLogBufferBudget = newMaxMemory >> 4;
  } else if (newLogBufferBudget > newMaxMemory / 2) {
            newLogBufferBudget = newMaxMemory / 2;
        }

        /*
         * We have a first pass at the log buffer budget. See what
         * size log buffers result. Don't let them be too big, it would
         * be a waste.
         */
        int numBuffers =
      configManager.getInt(EnvironmentParams.NUM_LOG_BUFFERS);
        long startingBufferSize = newLogBufferBudget / numBuffers;
        int logBufferSize =
            configManager.getInt(EnvironmentParams.LOG_BUFFER_MAX_SIZE);
        if (startingBufferSize > logBufferSize) {
            startingBufferSize = logBufferSize;
            newLogBufferBudget = numBuffers * startingBufferSize;
        } else if (startingBufferSize <
       EnvironmentParams.MIN_LOG_BUFFER_SIZE) {
            startingBufferSize = EnvironmentParams.MIN_LOG_BUFFER_SIZE;
            newLogBufferBudget = numBuffers * startingBufferSize;
  }

        long newCriticalThreshold =
            (newMaxMemory *
             envImpl.getConfigManager().getInt
                (EnvironmentParams.EVICTOR_CRITICAL_PERCENTAGE))/100;

        long newTrackerBudget =
            (newMaxMemory *
             envImpl.getConfigManager().getInt
                (EnvironmentParams.CLEANER_DETAIL_MAX_MEMORY_PERCENTAGE))/100;

        /*
         * If all has gone well, update the budget fields.  Once the log buffer
         * budget is determined, the remainder of the memory is left for tree
         * nodes.
         */
        maxMemory = newMaxMemory;
        criticalThreshold = newCriticalThreshold;
        logBufferBudget = newLogBufferBudget;
        trackerBudget = newTrackerBudget;
        cacheBudget = newMaxMemory - newLogBufferBudget;
  nLockTables =
            configManager.getInt(EnvironmentParams.N_LOCK_TABLES);
  lockMemoryUsage = new long[nLockTables];
    }

    /**
     * Returns Runtime.maxMemory(), accounting for a MacOS bug.
     * May return Long.MAX_VALUE if there is no inherent limit.
     * Used by unit tests as well as by this class.
     */
    public static long getRuntimeMaxMemory() {

        /* Runtime.maxMemory is unreliable on MacOS Java 1.4.2. */
        if ("Mac OS X".equals(System.getProperty("os.name"))) {
            String jvmVersion = System.getProperty("java.version");
            if (jvmVersion != null && jvmVersion.startsWith("1.4.2")) {
                return Long.MAX_VALUE; /* Undetermined heap size. */
            }
        }

        return Runtime.getRuntime().maxMemory();
    }

    /**
     * Initialize the starting environment memory state
     */
    void initCacheMemoryUsage()
        throws DatabaseException {

  synchronized (memoryUsageSynchronizer) {
      treeMemoryUsage = calcTreeCacheUsage();
  }
        assert LatchSupport.countLatchesHeld() == 0;
    }

    /**
     * Public for testing.
     */
    public long calcTreeCacheUsage()
        throws DatabaseException {

        long totalSize = 0;
        INList inList = envImpl.getInMemoryINs();

        inList.latchMajor();
        try {
            Iterator iter = inList.iterator();
            while (iter.hasNext()) {
                IN in = (IN) iter.next();
                long size = in.getInMemorySize();
                totalSize += size;
            }
        } finally {
            inList.releaseMajorLatch();
        }
        return totalSize;
    }

    /**
     * Update the environment wide tree memory count, wake up the evictor if
     * necessary.
     * @param increment note that increment may be negative.
     */
    public void updateTreeMemoryUsage(long increment) {
  synchronized (memoryUsageSynchronizer) {
      treeMemoryUsage += increment;
  }
        if (getCacheMemoryUsage() > cacheBudget) {
            envImpl.alertEvictor();
        }
    }

    /**
     * Update the environment wide misc memory count, wake up the evictor if
     * necessary.
     * @param increment note that increment may be negative.
     */
    public void updateMiscMemoryUsage(long increment) {
  synchronized (memoryUsageSynchronizer) {
      miscMemoryUsage += increment;
  }
        if (getCacheMemoryUsage() > cacheBudget) {
            envImpl.alertEvictor();
        }
    }

    public void updateLockMemoryUsage(long increment, int lockTableIndex) {
  lockMemoryUsage[lockTableIndex] += increment;
        if (getCacheMemoryUsage() > cacheBudget) {
            envImpl.alertEvictor();
        }
    }

    public long accumulateNewUsage(IN in, long newSize) {
        return in.getInMemorySize() + newSize;
    }

    public void refreshTreeMemoryUsage(long newSize) {
  synchronized (memoryUsageSynchronizer) {
      treeMemoryUsage = newSize;
  }
    }

    public long getCacheMemoryUsage() {
  long accLockMemoryUsage = 0;
  if (nLockTables == 1) {
      accLockMemoryUsage = lockMemoryUsage[0];
  } else {
      for (int i = 0; i < nLockTables; i++) {
    accLockMemoryUsage += lockMemoryUsage[i];
      }
  }
  return treeMemoryUsage + miscMemoryUsage + accLockMemoryUsage;
    }

    /**
     * Used for unit testing.
     */
    public long getTreeMemoryUsage() {
        return treeMemoryUsage;
    }

    public long getLogBufferBudget() {
        return logBufferBudget;
    }

    public long getTrackerBudget() {
        return trackerBudget;
    }

    public long getMaxMemory() {
        return maxMemory;
    }

    public long getCriticalThreshold() {
        return criticalThreshold;
    }

    public long getCacheBudget() {
        return cacheBudget;
    }

    public long getINOverhead() {
        return inOverhead;
    }

    public long getBINOverhead() {
        return binOverhead;
    }

    public long getDINOverhead() {
        return dinOverhead;
    }

    public long getDBINOverhead() {
        return dbinOverhead;
    }

    /**
     * Returns the memory size occupied by a byte array of a given length.
     */
    public static int byteArraySize(int arrayLen) {

        /*
         * BYTE_ARRAY_OVERHEAD accounts for 4 bytes of data.  Data larger than
         * 4 bytes is allocated in 8 byte increments.
         */
        int size = BYTE_ARRAY_OVERHEAD;
        if (arrayLen > 4) {
            size += ((arrayLen - 4 + 7) / 8) * 8;
        }

        return size;
    }

    void loadStats(StatsConfig config, EnvironmentStats stats) {
        stats.setCacheDataBytes(getCacheMemoryUsage());
    }
}
TOP

Related Classes of com.sleepycat.je.dbi.MemoryBudget

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.