All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.objectweb.dream.queue.buffer.AbstractBuffer Maven / Gradle / Ivy

/**
 * Dream
 * Copyright (C) 2003-2004 INRIA Rhone-Alpes
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Contact: [email protected]
 *
 * Initial developer(s): Vivien Quema
 * Contributor(s): Romain Lenglet
 */

package org.objectweb.dream.queue.buffer;


import org.objectweb.dream.message.Message;
import org.objectweb.dream.message.MessageManagerType;
import org.objectweb.fractal.fraclet.annotation.annotations.Attribute;
import org.objectweb.dream.dreamannotation.DreamComponent;
import org.objectweb.fractal.fraclet.annotation.annotations.Requires;

/**
 * Abstract implementation of a buffer. It implements the {@link BufferAdd } and
 * {@link BufferRemove } interfaces.
 * 

* The add and remove methods are implemented as * follows *

    *
  • The add method checks for available space and then calls * the doAdd method to add the message to the buffer.
  • *
  • The remove method checks for available messages and then * calls the doRemove method to remove a message from the buffer. *
  • *
*

* Buffer developers can inherit this class. They must implement several * methods: *

    *
  • canAdd(message) returns a boolean indicating whether the * given message can be added into the buffer.
  • *
  • doAdd(message) adds the given message into the buffer. *
  • *
  • hasAvailableMessage() returns a boolean indicating * whether there is an available message.
  • *
  • doRemove() removes a message from the buffer.
  • *
  • etc.
  • *
*

* Moreover developers must use the incrementAvailableMessagesCount * and incrementStoredMessagesCount methods to increment * indicators on stored messages, available messages and available space. *

* Note: the add and remove methods should * not be overridden. */ @DreamComponent() public abstract class AbstractBuffer implements BufferAdd, BufferRemove, BufferMonitoring { // ------------------------------------------------------------------------ // Client interfaces // ------------------------------------------------------------------------ /** * Can be used by subclasses to create aggregated messages in {@link * BufferRemove#removeAll()}. */ @Requires(name = "message-manager") protected MessageManagerType messageManagerItf; // ------------------------------------------------------------------------ // Attributes // ------------------------------------------------------------------------ /** * The maximal capacity of the buffer. */ @Attribute(argument = "maxCapacity") protected int maxCapacity = 0; // ------------------------------------------------------------------------ // Fields // ------------------------------------------------------------------------ /** * The lock object. */ protected final Object lock = new Object(); /** * The count of available messages in the buffer. This attribute should only * be updated using the {@link #incrementAvailableMessagesCount(int)}method. */ protected int availableMessagesCount = 0; /** * The count of stored messages into the buffer. This attribute should only be * updated using the {@link #incrementStoredMessagesCount(int)}method. */ protected int storedMessagesCount = 0; // ------------------------------------------------------------------------ // Implementation of the BufferAdd interface // ------------------------------------------------------------------------ /** * @see BufferAdd#add(Message) */ public final void add(Message message) throws InterruptedException { synchronized (lock) { while (!canAdd(message)) { lock.wait(); } doAdd(message); lock.notifyAll(); } } /** * @see BufferAdd#tryAdd(Message) */ public boolean tryAdd(Message message) { synchronized (lock) { if (canAdd(message)) { doAdd(message); lock.notifyAll(); return true; } return false; } } // ------------------------------------------------------------------------ // Implementation of the BufferRemove interface // ------------------------------------------------------------------------ /** * @see BufferRemove#remove() */ public final Message remove() throws InterruptedException { synchronized (lock) { while (!hasAvailableMessage()) { lock.wait(); } final Message m = doRemove(); lock.notifyAll(); return m; } } /** * @see BufferRemove#tryRemove() */ public Message tryRemove() { synchronized (lock) { if (hasAvailableMessage()) { final Message m = doRemove(); lock.notifyAll(); return m; } return null; } } /** * @see BufferRemove#get() */ public Message get() throws InterruptedException { synchronized (lock) { while (!hasAvailableMessage()) { lock.wait(); } final Message m = doGet(); return m; } } /** * @see BufferRemove#tryGet() */ public Message tryGet() { synchronized (lock) { if (hasAvailableMessage()) { final Message m = doGet(); return m; } return null; } } /** * @see BufferRemove#removeAll() */ public Message removeAll() { synchronized (lock) { final Message m = doRemoveAll(); lock.notifyAll(); return m; } } // ------------------------------------------------------------------------ // Methods that must be implemented by concrete sub classes. // ------------------------------------------------------------------------ /** * Adds a message to the buffer. This method should not check if there is * enough available space provided it has already been done in the * {@link #add}method. The {@link #lock lock}has been acquired when this * method is called. * * @param message the message to be added. */ protected abstract void doAdd(Message message); /** * Removes a message from the buffer. This method should not check if there is * a message available provided it has already been done in the * {@link #remove}method. The {@link #lock lock}has been acquired when this * method is called. * * @return a message. */ protected abstract Message doRemove(); /** * Removes all the messages stored into the buffer. The {@link #lock lock}has * been acquired when this method is called. * * @return an aggregated message. */ protected abstract Message doRemoveAll(); /** * Gets a message from the buffer. This method should not check if there is a * message available provided it has already been done in the {@link #get} * method. The {@link #lock lock}has been acquired when this method is * called. * * @return a message. */ protected abstract Message doGet(); // ------------------------------------------------------------------------ // Methods that may be overridden by concrete sub classes. // ------------------------------------------------------------------------ /** * Checks whether the given message can be added into the buffer. The * {@link #lock lock}has been acquired when this method is called. * * @param message the message to be tested. * @return true if the message can be added. */ protected boolean canAdd(Message message) { if (maxCapacity > 0 && (maxCapacity - storedMessagesCount <= 0)) { return false; } return true; } /** * Checks whether there is a message available to get or remove. * * @return true if there is an available message. */ public boolean hasAvailableMessage() { return (availableMessagesCount > 0); } // ------------------------------------------------------------------------ // Utility methods. // ------------------------------------------------------------------------ protected int availableSpace() { if (maxCapacity <= 0) { return Integer.MAX_VALUE; } return maxCapacity - storedMessagesCount; } /** * Increments the count of available messages. When calling this method, the * {@link #lock lock}must have already been acquired. * * @param delta the value that must be added to the previous count. */ protected void incrementAvailableMessagesCount(int delta) { availableMessagesCount += delta; /* * It is assumed that the locked has already been acquired. */ lock.notifyAll(); } /** * Increments the count of stored messages. When calling this method, the * {@link #lock lock}must have already been acquired. * * @param delta the value that must be added to previous indicator. */ protected void incrementStoredMessagesCount(int delta) { storedMessagesCount += delta; /* * It is assumed that the locked has already been acquired. */ lock.notifyAll(); } // ------------------------------------------------------------------------ // Overriding of the AttributeController interface // generated by fraclet // ------------------------------------------------------------------------ /** * BufferMonitoring#setMaxCapacity(int) */ public void setMaxCapacity(int maxCapacity) { synchronized (lock) { int previousCapacity = this.maxCapacity; this.maxCapacity = maxCapacity; if (maxCapacity > previousCapacity) { lock.notifyAll(); } } } // ------------------------------------------------------------------------ // Implementation of the BufferMonitoring interface. // ------------------------------------------------------------------------ /** * @see BufferMonitoring#getCurrentSize() */ public int getCurrentSize() { return storedMessagesCount; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy