| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.texteditor.quickdiff.compare.rangedifferencer; |
| |
| /** |
| * Memory-monitoring factory for <code>LinkedRangeDifference</code>. |
| * |
| * @since 3.0 |
| */ |
| public class LinkedRangeFactory { |
| |
| /** |
| * Exception that is thrown after the minimal allowed free memory is reached. |
| */ |
| public static class LowMemoryException extends Exception { |
| |
| /** |
| * Initialize without detail message. |
| */ |
| public LowMemoryException() { |
| super(); |
| } |
| |
| /** |
| * Initialize with the given detail message. |
| * |
| * @param message the detail message |
| */ |
| public LowMemoryException(String message) { |
| super(message); |
| } |
| } |
| |
| /** |
| * Relative amount of memory that must be free in order to allow the creation of additional instances |
| */ |
| private static final double THRESHOLD= 0.1; |
| /** |
| * Number of instantiations after which the amount of free memory is checked |
| */ |
| private static final long CHECK_INTERVAL= 5000; |
| /** |
| * Considered maximal size of a difference object in bytes. |
| */ |
| private static final long OBJECT_SIZE= 100; |
| /** |
| * The maximal memory requirement for the next round in bytes. |
| */ |
| private static final long MAXIMAL_INTERVAL_REQUIREMENT= CHECK_INTERVAL * OBJECT_SIZE; |
| /** |
| * Allowed memory consumption in bytes. |
| */ |
| private static final long MAX_MEMORY_CONSUMPTION= 10 * 1024 * 1024; |
| /** |
| * The maximal number of instances. |
| */ |
| private static final long MAX_INSTANCES= MAX_MEMORY_CONSUMPTION / OBJECT_SIZE; |
| |
| |
| /** |
| * Preallocated low memory exception |
| */ |
| private LowMemoryException fLowMemoryException= new LowMemoryException(); |
| |
| /** |
| * Number of instantiations |
| */ |
| private long fCount= 0; |
| |
| /** |
| * Create a new linked range difference with the given next range and operation. |
| * |
| * @param next the next linked range difference |
| * @param operation the operation |
| * @return the new linked range difference |
| * @throws LowMemoryException |
| */ |
| public LinkedRangeDifference newRange(LinkedRangeDifference next, int operation) throws LowMemoryException { |
| check(); |
| return new LinkedRangeDifference(next, operation); |
| } |
| |
| /** |
| * After <code>CHECK_INTERVAL</code> calls check whether at least a fraction of <code>THRESHOLD</code> |
| * of the maximal available memory is free, otherwise throw an {@link LowMemoryException}. |
| * |
| * @throws LowMemoryException |
| */ |
| private void check() throws LowMemoryException { |
| if (fCount % CHECK_INTERVAL == 0) { |
| |
| Runtime runtime= Runtime.getRuntime(); |
| long maxMemory= runtime.maxMemory(); |
| long maxFreeMemory= maxMemory - (runtime.totalMemory() - runtime.freeMemory()); |
| |
| if (((float) (maxFreeMemory - MAXIMAL_INTERVAL_REQUIREMENT)) / maxMemory < THRESHOLD) |
| throw fLowMemoryException; |
| } |
| if (++fCount >= MAX_INSTANCES) |
| throw fLowMemoryException; |
| } |
| } |