/* * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. See terms of license at gnu.org. */ package net.java.sip.communicator.util; import java.util.*; /** * The GenericBuffer class provides a way to minimize the effort needed to * bufferize any kind of information. This class is particularly suited to * optimizations based on reusing already computed data. * * @author Benoit Pradelle */ public class GenericBuffer<T> { private final Hashtable<String, GenericBufferPair> buffer; private int minAge = 0; private int curAge = 0; private final int maxCapacity; /** * Sole constructor. * * @param bufferSize The buffer size. Adding data to a full buffer will * cause the oldest data present in the buffer to be overwritten; */ public GenericBuffer(final int bufferSize) { assert bufferSize > 0; buffer = new Hashtable<String, GenericBufferPair>(bufferSize); maxCapacity = bufferSize; } /** * Adds a value to the buffer. If the buffer is full, the oldest value in * the buffer will be overwritten by this new value. * * @param value The value to add. Can't be null. * @param context The context for which this value is valid. This basically * represents the current value of all the variables which * control the value is correct. The context is used to find this * value in the buffer. If the context is already associated in * the buffer with a value, nothing is added nor modified. */ public void addValue(final T value, final String context) { assert value != null && context != null; GenericBufferPair storage = buffer.get(context); if (storage == null) { storage = new GenericBufferPair(); } else { return; // don't override values } // if the amount of data has reach the limit, search the oldest data if (buffer.size() == maxCapacity) { for (Map.Entry<String, GenericBufferPair> e : buffer.entrySet()) { if (e.getValue().age == minAge) { buffer.remove(e.getKey()); minAge++; break; } } } storage.age = curAge++; storage.value = value; buffer.put(context, storage); } /** * Retrieves the value in the buffer corresponding to the context if it * exists. * * @param context The context of the searched value. The context represents * all the variables values for which this value is correct. * @return The bufferized value with the searched context if it exists or * null if no value is found. */ public T getValue(final String context) { assert context != null; GenericBufferPair res = buffer.get(context); if (res == null) { return null; } return res.value; } /** * This class is a simple structure to store a pair context-value */ private class GenericBufferPair { public T value = null; public int age = 0; } }