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

Alachisoft.NCache.Common.DataStructures.QueueClosedException Maven / Gradle / Ivy

package Alachisoft.NCache.Common.DataStructures;

// $Id: Queue.java,v 1.13 2004/03/30 06:47:28 belaban Exp $


/**
 * Elements are added at the tail and removed from the head. Class is thread-safe in that
 * 1 producer and 1 consumer may add/remove elements concurrently. The class is not
 * explicitely designed for multiple producers or consumers. Implemented as a linked
 * list, so that removal of an element at the head does not cause a right-shift of the
 * remaining elements (as in a Vector-based implementation).
 *
 *   Bela Ban
 * 
 */
//	public class Queue
//	{
//		///  Returns the first element. Returns null if no elements are available.
//		virtual public object First
//		{
//			get { return head != null?head.obj:null; }
//		}
//
//		///  Returns the last element. Returns null if no elements are available.
//		virtual public object Last
//		{
//			get { return tail != null?tail.obj:null; }			
//		}
//
//		/*head and the tail of the list so that we can easily add and remove objects*/
//		internal Element head = null, tail = null;
//		
//		/*flag to determine the state of the queue*/
//		internal bool closed = false;
//		
//		/*current size of the queue*/
//		private int size = 0;
//		
//		/* Lock object for synchronization. Is notified when element is added */
//		internal object mutex = new object();
//		
//		/// Lock object for syncing on removes. It is notified when an object is removed 
//		// Object  remove_mutex=new Object();
//		
//		/*the number of end markers that have been added*/
//		internal int num_markers = 0;
//		
//		///  if the queue closes during the runtime
//		/// an endMarker object is added to the end of the queue to indicate that
//		/// the queue will close automatically when the end marker is encountered
//		/// This allows for a "soft" close.
//		/// 
//		/// 
//		/// 
//		private static readonly object endMarker = new object();
//		
//		
//		///  the class Element indicates an object in the queue.
//		/// This element allows for the linked list algorithm by always holding a
//		/// reference to the next element in the list.
//		/// if Element.next is null, then this element is the tail of the list.
//		/// 
//		internal class Element
//		{
//			/*the actual value stored in the queue*/
//			internal object obj = null;
//			/*pointer to the next item in the (queue) linked list*/
//			internal Element next = null;
//			
//			///  creates an Element object holding its value
//			/// - the object to be stored in the queue position
//			/// 
//			internal Element(object o)
//			{
//				//this.enclosingInstance = enclosingInstance;
//				obj = o;
//			}
//			
//			///  prints out the value of the object
//			public override string ToString()
//			{
//				return obj != null?obj.ToString():"null";
//			}
//		}
//		
//		
//		///  creates an empty queue
//		public Queue()
//		{
//		}
//		
//		
//		///  returns true if the Queue has been closed
//		/// however, this method will return false if the queue has been closed
//		/// using the close(true) method and the last element has yet not been received.
//		/// 
//		///  true if the queue has been closed
//		/// 
//		public bool Closed
//		{
//			get{return closed;}
//		}
//		
//		///  adds an object to the tail of this queue
//		/// If the queue has been closed with close(true) no exception will be
//		/// thrown if the queue has not been flushed yet.
//		/// 
//		/// - the object to be added to the queue
//		/// 
//		///  QueueClosedException exception if closed() returns true
//		/// 
//		public void  add(object obj)
//		{
//			if (obj == null)
//			{
////				if (log.isErrorEnabled())
////					log.error("argument must not be null");
//				return ;
//			}
//			if (closed)
//				throw new QueueClosedException();
//			if (this.num_markers > 0)
//				throw new QueueClosedException("Queue.add(): queue has been closed. You can not add more elements. " + "Waiting for removal of remaining elements.");
//			
//			/*lock the queue from other threads*/
//			lock (mutex)
//			{
//				/*create a new linked list element*/
//				Element el = new Element(obj);
//				/*check the first element*/
//				if (head == null)
//				{
//					/*the object added is the first element*/
//					/*set the head to be this object*/
//					head = el;
//					/*set the tail to be this object*/
//					tail = head;
//					/*set the size to be one, since the queue was empty*/
//					size = 1;
//				}
//				else
//				{
//					/*add the object to the end of the linked list*/
//					tail.next = el;
//					/*set the tail to point to the last element*/
//					tail = el;
//					/*increase the size*/
//					size++;
//				}
//				/*wake up all the threads that are waiting for the lock to be released*/
//				Monitor.PulseAll(mutex);
//			}
//		}
//		
//		
//		///  Adds a new object to the head of the queue
//		/// basically (obj.equals(queue.remove(queue.add(obj)))) returns true
//		/// If the queue has been closed with close(true) no exception will be
//		/// thrown if the queue has not been flushed yet.
//		/// 
//		/// - the object to be added to the queue
//		/// 
//		///  QueueClosedException exception if closed() returns true
//		/// 
//		/// 
//		public void  addAtHead(object obj)
//		{
//			if (obj == null)
//			{
////				if (log.isErrorEnabled())
////					log.error("argument must not be null");
//				return ;
//			}
//			if (closed)
//				throw new QueueClosedException();
//			if (this.num_markers > 0)
//				throw new QueueClosedException("Queue.addAtHead(): queue has been closed. You can not add more elements. " + "Waiting for removal of remaining elements.");
//			
//			/*lock the queue from other threads*/
//			lock (mutex)
//			{
//				Element el = new Element(obj);
//				/*check the head element in the list*/
//				if (head == null)
//				{
//					/*this is the first object, we could have done add(obj) here*/
//					head = el;
//					tail = head;
//					size = 1;
//				}
//				else
//				{
//					/*set the head element to be the child of this one*/
//					el.next = head;
//					/*set the head to point to the recently added object*/
//					head = el;
//					/*increase the size*/
//					size++;
//				}
//				/*wake up all the threads that are waiting for the lock to be released*/
//				Monitor.PulseAll(mutex);
//			}
//		}
//		
//		
//		///  Removes 1 element from head or blocks
//		/// until next element has been added or until queue has been closed
//		/// 
//		///  the first element to be taken of the queue
//		/// 
//		public object remove()
//		{
//			object retval = null;
//			try
//			{
//				retval = remove(Timeout.Infinite);
//			}
//			catch (TimeoutException)
//			{
//			}
//			return retval;
//		}
//		
//		
//		///  Removes 1 element from the head.
//		/// If the queue is empty the operation will wait for timeout ms.
//		/// if no object is added during the timeout time, a Timout exception is thrown
//		/// 
//		/// - the number of milli seconds this operation will wait before it times out
//		/// 
//		///  the first object in the queue
//		/// 
//		public object remove(long timeout)
//		{
//			object retval = null;
//			
//			/*lock the queue*/
//			lock (mutex)
//			{
//				/*if the queue size is zero, we want to wait until a new object is added*/
//				if (size == 0)
//				{
//					if (closed) throw new QueueClosedException();
//
//					if(!Monitor.Wait(mutex, (int)timeout))
//					{
//						throw new TimeoutException();
//					}
//				}
//				/*we either timed out, or got notified by the add_mutex lock object*/
//				
//				/*check to see if the object closed*/
//				if (closed) throw new QueueClosedException();
//				
//				/*get the next value*/
//				retval = removeInternal();
//			
//				/*if we reached an end marker we are going to close the queue*/
//				if (retval == endMarker)
//				{
//					close(false);
//					throw new QueueClosedException();
//				}
//				/*at this point we actually did receive a value from the queue, return it*/
//				return retval;
//			}
//		}
//		
//		
//		///  removes a specific object from the queue.
//		/// the object is matched up using the Object.equals method.
//		/// 
//		/// the actual object to be removed from the queue
//		/// 
//		public void  removeElement(object obj)
//		{
//			Element el, tmp_el;
//			
//			if (obj == null)
//			{
////				if (log.isErrorEnabled())
////					log.error("argument must not be null");
//				return ;
//			}
//			
//			/*lock the queue*/
//			lock (mutex)
//			{
//				el = head;
//				
//				/*the queue is empty*/
//				if (el == null)
//					return ;
//				
//				/*check to see if the head element is the one to be removed*/
//				if (el.obj.Equals(obj))
//				{
//					/*the head element matched we will remove it*/
//					head = el.next;
//					el.next = null;
//					/*check if we only had one object left
//					*at this time the queue becomes empty
//					*this will set the tail=head=null
//					*/
//					if (size == 1)
//						tail = head; // null
//					decrementSize();
//					
//					//                if(size == 0) {
//					//                    synchronized(remove_mutex) {
//					//                        remove_mutex.notifyAll();
//					//                    }
//					//                }
//					return ;
//				}
//				
//				/*look through the other elements*/
//				while (el.next != null)
//				{
//					if (el.next.obj.Equals(obj))
//					{
//						tmp_el = el.next;
//						if (tmp_el == tail)
//						// if it is the last element, move tail one to the left (bela Sept 20 2002)
//							tail = el;
//						el.next = el.next.next; // point to the el past the next one. can be null.
//						tmp_el.next = null;
//						decrementSize();
//						//                    if(size == 0) {
//						//                        synchronized(remove_mutex) {
//						//                            remove_mutex.notifyAll();
//						//                        }
//						//                    }
//						break;
//					}
//					el = el.next;
//				}
//			}
//		}
//		
//		
//		///  returns the first object on the queue, without removing it.
//		/// If the queue is empty this object blocks until the first queue object has
//		/// been added
//		/// 
//		///  the first object on the queue
//		/// 
//		public object peek()
//		{
//			object retval = null;
//			try
//			{
//				retval = peek(Timeout.Infinite);
//			}
//			catch (TimeoutException)
//			{
//			}
//			return retval;
//		}
//		
//		
//		///  returns the first object on the queue, without removing it.
//		/// If the queue is empty this object blocks until the first queue object has
//		/// been added or the operation times out
//		/// 
//		/// how long in milli seconds will this operation wait for an object to be added to the queue
//		/// before it times out
//		/// 
//		///  the first object on the queue
//		/// 
//		
//		public object peek(long timeout)
//		{
//			object retval = null;
//			
//			lock (mutex)
//			{
//				if (size == 0)
//				{
//					if (closed) throw new QueueClosedException();
//
//					if(!Monitor.Wait(mutex, (int)timeout))
//					{
//						throw new TimeoutException();
//					}
//				}
//
//				if (closed) throw new QueueClosedException();
//				retval = head != null ? head.obj:null;
//				
//				if (retval == endMarker)
//				{
//					close(false);
//					throw new QueueClosedException();
//				}
//				return retval;
//			}
//		}
//		
//		
//		/// Marks the queues as closed. When an add or remove operation is
//		/// attempted on a closed queue, an exception is thrown.
//		/// 
//		/// When true, a end-of-entries marker is added to the end of the queue.
//		/// Entries may be added and removed, but when the end-of-entries marker
//		/// is encountered, the queue is marked as closed. This allows to flush
//		/// pending messages before closing the queue.
//		/// 
//		public void  close(bool flush_entries)
//		{
//			if (flush_entries)
//			{
//				try
//				{
//					add(endMarker); // add an end-of-entries marker to the end of the queue
//					num_markers++;
//				}
//				catch (QueueClosedException ex)
//				{
//					Trace.error("Queue.close()", "exception=" + ex.Message);
//				}
//				return ;
//			}
//			
//			lock (mutex)
//			{
//				closed = true;
//				Monitor.PulseAll(mutex);
//			}
//			
//			//        synchronized(remove_mutex) {
//			//            remove_mutex.notifyAll();
//			//        }
//		}
//		
//		
//		///  resets the queue.
//		/// This operation removes all the objects in the queue and marks the queue open
//		/// 
//		public void  reset()
//		{
//			num_markers = 0;
//			if (!closed)
//				close(false);
//			
//			lock (mutex)
//			{
//				size = 0;
//				head = null;
//				tail = null;
//				closed = false;
//				Monitor.PulseAll(mutex);
//			}
//			
//			//        synchronized(remove_mutex) {
//			//            remove_mutex.notifyAll();
//			//        }
//		}
//		
//		/// 
//		/// Number of Objects in the queue
//		/// 
//		public int Count
//		{
//			get{return size - num_markers;}
//		}
//		
//		///  prints the size of the queue
//		public override string ToString()
//		{
//			return "Queue (" + Count + ") messages";
//		}
//		
//		
//		///  Removes the first element. Returns null if no elements in queue.
//		/// Always called with add_mutex locked (we don't have to lock add_mutex ourselves)
//		/// 
//		private object removeInternal()
//		{
//			Element retval;
//			
//			/*if the head is null, the queue is empty*/
//			if (head == null)
//				return null;
//			
//			retval = head; // head must be non-null now
//			
//			head = head.next;
//			if (head == null)
//				tail = null;
//			
//			decrementSize();
//			//        if(size == 0) {
//			//            synchronized(remove_mutex) {
//			//                remove_mutex.notifyAll();
//			//            }
//			//        }
//			
//			if (head != null && head.obj == endMarker)
//			{
//				closed = true;
//			}
//			
//			retval.next = null;
//			return retval.obj;
//		}
//		
//		
//		void  decrementSize()
//		{
//			size--;
//			if (size < 0)
//				size = 0;
//		}
//		
//	}
//

public class QueueClosedException extends RuntimeException {
    /**
     * Basic Exception
     */
    public QueueClosedException() {
    }

    /**
     * Exception with custom message
     *
     * @param msg Message to display when exception is thrown
     */
    public QueueClosedException(String msg) {
        super(msg);
    }

    /**
     * Creates a String representation of the Exception
     *
     * @return A String representation of the Exception
     */
    public final String toString() {
        if (this.getMessage() != null) {
            return "QueueClosedException:" + this.getMessage();
        } else {
            return "QueueClosedException";
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy