// -*-	Mode:C++; c-basic-offset:8; tab-width:8; indent-tabs-mode:t -*-
/*
# Copyright (c) 2000-2001 by the University of Southern California.
# All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation in source and binary forms for non-commercial purposes and
# without fee is hereby granted, provided that the above copyright notice
# appear in all copies and that both the copyright notice and this permission
# notice appear in supporting documentation, and that any documentation,
# advertising materials, and other materials related to such distribution and
# use acknowledge that the software was developed by the University of
# Southern California, Information Sciences Institute.  The name of the
# University may not be used to endorse or promote products derived from this
# software without specific prior written permission.
#
# THE UNIVERSITY OF SOUTHERN CALIFORNIA MAKES NO REPRESENTATIONS ABOUT THE
# SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE.  THIS SOFTWARE IS PROVIDED "AS
# IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
# LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE.
#
# Other copyrights might apply to parts of this software and are so noted when
# applicable.
# ----------------------------------------------------------------------------
#
# Primary author: Purushotham Kamath
#                 January 2001

#This material is based upon work supported by the Defense Advanced Research
#Projects Agency Information Technology Office, (NGI Multicast Applications 
#and Architecture (NMAA-ADDON), ARPA Order No. H645, Program Code No. 9A20, 
#Issued by DARPA/CMD under Contract No. MDA972-99-C-0022.
*/

#include <stdlib.h>
#include <stdarg.h>


#include <eventhandler.h>
#include <packet.h>
#include <queue.h>
#include <debug.h>

//Queue class functions.

Queue::Queue(int s): size(s *1024), bufferoverflows(0), byteoverflows(0)
{
	qsize =0;
	avgqsize =0;
	maxqsize =0;
	pktcnt =0;
	head = NULL;
	tail = NULL;	
	bytes =0;
}

Queue::~Queue()
{

}

int Queue:: enqueue(Packet *pkt)
{

	dprintf("Queue.cc: Queue::enqueue(): Entered function\n");	


	if (tail == NULL)
	{

//Kamath: 07/09/01: Bug fix
//Check the queue size limitation for the case when there are no packets in 
//the queue
		if(pkt->size > size)
		{
			dprintf("Queue.cc: Queue::enqueue(): Buffer overflow.\n");	
			bufferoverflows++;
			byteoverflows+=pkt->size;
			return 0;
		}

		qsize++;
		bytes+=pkt->size;


		if(qsize > maxqsize)
			maxqsize=qsize;	


		head = pkt;
		tail = pkt;
		pkt->next = NULL;
		pkt->prev = NULL;
		return 1;
	}

	Packet *p = tail;
	if(bytes+ pkt->size > size)
	{
		dprintf("Queue.cc: Queue::enqueue(): Buffer overflow.\n");	
		byteoverflows+=pkt->size;
		bufferoverflows++;
		return 0;
	}


	tail = pkt;
	p->next = pkt;
	pkt->prev = p;
	pkt->next = NULL;
	qsize++;
	bytes+=pkt->size;
	return 1;
}

Packet * Queue:: dequeue()
{
	dprintf("Queue.cc: Queue::dequeue(): Entered function\n");	
	if(head != NULL)
	{
		qsize--;
		Packet *p = head;
		bytes-=p->size;
		head = head->next;
		if (head == NULL)
			tail = NULL;
		dprintf("Queue.cc: Queue::dequeue(): Leaving function\n");	
		return p;
	}
	else 
	{
		dprintf("Queue.cc: Queue::dequeue(): Nothing in queue: Leaving function\n");	
		return NULL;
	}
}

void Queue::dumpstats()
{
	printf("Queue.cc: Queue::dumpstats(): Number of bufferoverflows: %d\n", bufferoverflows);
	printf("Queue.cc: Queue::dumpstats(): Byte overflows: %d\n", byteoverflows);
}
