/* deque.c 
 
   Simple deque routines. Meant to store pointers.
   Return NULL when empty, so can't store 0.
 */

#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "pageHeader.h"
#include "prototypes.h"

Deque* newDeque(void)
{
 Deque *ret;
 PageInfo *pi;

 pi = internalPageRequest();
 ret = (Deque *)pi;
 assert(ret!=NULL);

 assert(&(ret->header) == &(pi->header));
 assert(&(ret->next) == &(pi->next)); 
 assert((Word *)&(ret->start) == (Word *)&(pi->prev));
 assert((Word *)&(ret->end) == (Word *)&(pi->reserved));
 assert(sizeof(Deque)<=sizeof(PageInfo));

 ret->start = PI_TO_PAGE(pi);
 ret->end = ret->start;
 ret->next = NULL;

 return ret;
}

/* enqueue adds the element to the deque q in FIFO fashion. */
void enqueue(Deque *q, Word element)
{
 PageInfo *pi;
 PageInfo *endPI;
 Word *end;

 end = q->end;
 if((end+1) == GC_PAGE_END(end)) /* No space on this page so we need a new
				    one. We are not using the last word on the
				    page. */
   {
     endPI = PAGE_TO_PI(end);
     pi = internalPageRequest();
     endPI->next = pi;
     pi->next = NULL;
     q->end = PI_TO_PAGE(pi);
   }

 *(q->end) = element;
 q->end++;
}

/* dequeue returns the next element from the q in FIFO fashion */
Word dequeue(Deque *q)
{
 Word ret;
 Word *start;
 PageInfo *startPI;

 start = q->start;

 if(start == q->end) return NULL; /* The Deque is empty. */

 if((start+1) == GC_PAGE_END(start))
   {
     startPI = PAGE_TO_PI(start);
     assert(startPI->next!=NULL);
     
     startPI = startPI->next;
     q->start = PI_TO_PAGE(startPI);
     assert(q->start!=q->end);
   }

 ret = *(q->start);

 q->start++;

 return ret;
 
}

/* Pop pops an element off the deque. */
Word pop(Deque *q)
{
 PageInfo *pi;
 PageInfo *endPI, *startPI;
 Word *end;
 Word ret;

 if(q->end == q->start) return NULL; /* The deque is empty. */

 q->end--;
 ret = *(q->end);

 end = q->end;
 endPI = PAGE_TO_PI(end);

 if(endPI->next == NULL)
   {
     startPI = PAGE_TO_PI(q->start);
     if(endPI != startPI)
       {
	 pi=startPI;
	 while(pi->next != endPI)
	   {
	     pi = pi->next;
	     assert(pi!=NULL);
	   }
	 
	 pi->next = NULL;
	 
	 internalPageFree(endPI);
	 q->end = PI_TO_PAGE(pi) + PAGE_SIZE - 1; /* Not using the last word on
						     the page. But end points to
						     the last word. */
       }
   }

 return ret;
}
/* freeDeque frees the memory for a Deque. */
void freeDeque(Deque *q)
{
 PageInfo *pi,*pi2;

 pi = q->next;
 while(pi!=NULL)
   {
     pi2 = pi;
     pi = pi->next;
     internalPageFree(pi2);
   }
 internalPageFree((PageInfo *)q);
}

/* resetDeque */
void resetDeque(Deque *q)
{
  q->start = PI_TO_PAGE(((PageInfo *)q));
}

/* mergeDeque - merges the second Deque into the first.  The victim is not freed
 upon being devoured. */
void mergeDeque(Deque *qCannibal, Deque *qVictim)
{
 Word *ptr;

 if(qVictim==NULL) return;

 while((ptr = (Word *)dequeue(qVictim)) != NULL)
   {
     enqueue(qCannibal,(Word)ptr);
   }
}
/* EOF: deque.c */

/* (c) Frederick Smith, Greg Morrisett.
 *     October 1998, all rights reserved.
 *
 *
 *              Copyright 1990-1993 Digital Equipment Corporation
 *                         All Rights Reserved
 *
 * Permission to use, copy, and modify this software and its documentation is
 * hereby granted only under the following terms and conditions.  Both the
 * above copyright notice and this permission notice must appear in all copies
 * of the software, derivative works or modified versions, and any portions
 * thereof, and both notices must appear in supporting documentation.
 *
 * Users of this software agree to the terms and conditions set forth herein,
 * and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
 * right and license under any changes, enhancements or extensions made to the
 * core functions of the software, including but not limited to those affording
 * compatibility with other hardware or software environments, but excluding
 * applications which incorporate this software.  Users further agree to use
 * their best efforts to return to Digital any such changes, enhancements or
 * extensions that they make and inform Digital of noteworthy uses of this
 * software.  Correspondence should be provided to Digital at:
 * 
 *                       Director of Licensing
 *                       Western Research Laboratory
 *                       Digital Equipment Corporation
 *                       250 University Avenue
 *                       Palo Alto, California  94301  
 * 
 * This software may be distributed (but not offered for sale or transferred
 * for compensation) to third parties, provided such third parties agree to
 * abide by the terms and conditions of this notice.  
 * 
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.
 */
