abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** Copyright (c) 2007 D. Richard Hipp abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ** This program is free software; you can redistribute it and/or abce5105e2 2007-09-01 drh: ** modify it under the terms of the GNU General Public abce5105e2 2007-09-01 drh: ** License version 2 as published by the Free Software Foundation. abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ** This program is distributed in the hope that it will be useful, abce5105e2 2007-09-01 drh: ** but WITHOUT ANY WARRANTY; without even the implied warranty of abce5105e2 2007-09-01 drh: ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU abce5105e2 2007-09-01 drh: ** General Public License for more details. abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ** You should have received a copy of the GNU General Public abce5105e2 2007-09-01 drh: ** License along with this library; if not, write to the abce5105e2 2007-09-01 drh: ** Free Software Foundation, Inc., 59 Temple Place - Suite 330, abce5105e2 2007-09-01 drh: ** Boston, MA 02111-1307, USA. abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ** Author contact information: abce5105e2 2007-09-01 drh: ** drh@hwaci.com abce5105e2 2007-09-01 drh: ** http://www.hwaci.com/drh/ abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ******************************************************************************* abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ** This file contains code used to implement a priority queue. abce5105e2 2007-09-01 drh: ** A priority queue is a list of items order by a floating point abce5105e2 2007-09-01 drh: ** value. We can insert integers with each integer tied to its abce5105e2 2007-09-01 drh: ** value then extract the integer with the smallest value. abce5105e2 2007-09-01 drh: ** abce5105e2 2007-09-01 drh: ** The way this queue is used, we never expect it to contain more abce5105e2 2007-09-01 drh: ** than 2 or 3 elements, so a simple array is sufficient as the abce5105e2 2007-09-01 drh: ** implementation. This could give worst case O(N) insert times, abce5105e2 2007-09-01 drh: ** but because of the nature of the problem we expect O(1) performance. abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: #include "config.h" abce5105e2 2007-09-01 drh: #include "pqueue.h" abce5105e2 2007-09-01 drh: #include <assert.h> abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: #if INTERFACE abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** An integer can appear in the bag at most once. abce5105e2 2007-09-01 drh: ** Integers must be positive. abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: struct PQueue { abce5105e2 2007-09-01 drh: int cnt; /* Number of entries in the queue */ abce5105e2 2007-09-01 drh: int sz; /* Number of slots in a[] */ abce5105e2 2007-09-01 drh: struct QueueElement { abce5105e2 2007-09-01 drh: int id; /* ID of the element */ abce5105e2 2007-09-01 drh: double value; /* Value of element. Kept in ascending order */ abce5105e2 2007-09-01 drh: } *a; abce5105e2 2007-09-01 drh: }; abce5105e2 2007-09-01 drh: #endif abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** Initialize a PQueue structure abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: void pqueue_init(PQueue *p){ abce5105e2 2007-09-01 drh: memset(p, 0, sizeof(*p)); abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** Destroy a PQueue. Delete all of its content. abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: void pqueue_clear(PQueue *p){ abce5105e2 2007-09-01 drh: free(p->a); abce5105e2 2007-09-01 drh: pqueue_init(p); abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** Change the size of the queue so that it contains N slots abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: static void pqueue_resize(PQueue *p, int N){ abce5105e2 2007-09-01 drh: p->a = realloc(p->a, sizeof(p->a[0])*N); abce5105e2 2007-09-01 drh: p->sz = N; abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** Insert element e into the queue. abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: void pqueue_insert(PQueue *p, int e, double v){ abce5105e2 2007-09-01 drh: int i, j; abce5105e2 2007-09-01 drh: if( p->cnt+1>p->sz ){ abce5105e2 2007-09-01 drh: pqueue_resize(p, p->cnt+5); abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: for(i=0; i<p->cnt; i++){ abce5105e2 2007-09-01 drh: if( p->a[i].value>v ){ abce5105e2 2007-09-01 drh: for(j=p->cnt; j>i; j--){ abce5105e2 2007-09-01 drh: p->a[j] = p->a[j-1]; abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: break; abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: p->a[i].id = e; abce5105e2 2007-09-01 drh: p->a[i].value = v; abce5105e2 2007-09-01 drh: p->cnt++; abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: abce5105e2 2007-09-01 drh: /* abce5105e2 2007-09-01 drh: ** Extract the first element from the queue (the element with abce5105e2 2007-09-01 drh: ** the smallest value) and return its ID. Return 0 if the queue abce5105e2 2007-09-01 drh: ** is empty. abce5105e2 2007-09-01 drh: */ abce5105e2 2007-09-01 drh: int pqueue_extract(PQueue *p){ abce5105e2 2007-09-01 drh: int e, i; abce5105e2 2007-09-01 drh: if( p->cnt==0 ){ abce5105e2 2007-09-01 drh: return 0; abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: e = p->a[0].id; abce5105e2 2007-09-01 drh: for(i=0; i<p->cnt-1; i++){ abce5105e2 2007-09-01 drh: p->a[i] = p->a[i+1]; abce5105e2 2007-09-01 drh: } abce5105e2 2007-09-01 drh: p->cnt--; abce5105e2 2007-09-01 drh: return e; abce5105e2 2007-09-01 drh: }