PQueue.xcc

Nikola Puzovic (Nikola.Puzovic@st.com)

Copyright 2007 STMicroelectronics.

This program is free software; you can redistribute it and/or modify it under the terms of either (at your option): the GNU General Public License (GPL) version 2; the GNU Lesser General Public License (LGPL) version 2.1; any later version of these licences as published by the Free Software Foundation.

PQueue— Priority queue implemented as a radix-4 heap.

See R.E. Tarjan "Data Structures and Network Algorithms".

The main difference with Tarjan's implementation is that we index the heap array starting at index 0 instead of 1. In Tarjan's implementation, the parent of node x is (x - 1 + d - 1)/d and children its are (d(x - 1) + 2) ... (d(x - 1) + d + 1). In our implementation, the parent of node x is x > 0? (x - 1)/d: -1 and its children are at (dx + 1) ... (dx + d).

For d=4 and Tarjan's implementation, these are (x + 2)/4 and (4x - 2) ... (4x + 1). For d=4 and here implementation, these are (x - 1)>>2 and (4x + 1) ... (4x + 4).

struct PQueue_ {
  //@args       Memory memory, int32_t maxCount
  Memory MEMORY;
  uint32_t STATUS;              // MAXCOUNT:31;ISORDERED:1;
  //@access ISORDERED   (PQueue_STATUS(this)&0x1)
  //@access MAXCOUNT    (int32_t)(PQueue_STATUS(this)>>1)
  int32_t COUNT;                // Count of entries in PQueue.
  struct PQueueEntry_ *ENTRIES;
};
PQueue_empty— Empty this PQueue.
void
PQueue_empty(PQueue this);
PQueue_isEmpty— True iff this PQueue is empty.
static inline bool
PQueue_isEmpty(const_PQueue this)
{
  return PQueue_COUNT(this) == 0;
}
PQueue_count— Count members contained in the PQueue set.
Return
The count of members in this PQueue set.
static inline int32_t
PQueue_count(const_PQueue this)
{
  return PQueue_COUNT(this);
}
PQueue_isOrdered— This PQueue ordered status.
static inline bool
PQueue_isOrdered(const_PQueue this)
{
  return PQueue_ISORDERED(this);
}
PQueue_clearOrdered— Set this PQueue status as unordered.
static inline void
PQueue_clearOrdered(PQueue this)
{
  *PQueue__STATUS(this) &= ~0x1;
}
PQueue_addEntry— Add new entry into this priority queue without preserving the the heap invariant. This should be used only for initial insertion into the IQueue.
void
PQueue_addEntry(PQueue this, PQueueMember member, PQueuePriority priority);
PQueue_makeHeap— Make heap order for this PQueue.
int32_t
PQueue_makeHeap(PQueue this);
PQueue_insert— Insert new member to this priority queue.
void
PQueue_insert(PQueue this, PQueueMember member, PQueuePriority priority);
PQueue_remove— Remove the entry at given index.
void
PQueue_remove(PQueue this, int32_t index);
PQueue_update— Update the priority of an entry.
void
PQueue_update(PQueue this, const_PQueueEntry entry, PQueuePriority priority);
PQueue_extractMin— Extract the member with minimum priority from this PQueue.
PQueueMember
PQueue_extractMin(PQueue this);
PQueue_accessMin— Access the the member with minimum priority from this PQueue.
static inline PQueueMember
PQueue_accessMin(const_PQueue this)
{
  PQueueEntry_ *entries = PQueue_ENTRIES(this);
  PQueueMember member = entries[0].MEMBER;
  return member;
}
PQueue_entries— For use by PQueue_FOREACH.
static inline PQueueEntry_ *
PQueue_entries(const_PQueue this)
{
  return PQueue_ENTRIES(this);
}
PQueue_FOREACH— Iterates over this PQueue ENTRIES.

For each iteration, PQueue_INDEX is index to the internal array of the queue, and PQueue_ENTRY is the current PQueueEntry.

#define PQueue_FOREACH(this, Type, member) { \
  PQueueEntry_ *PQueue_ENTRIES = PQueue_entries(this); \
  int32_t PQueue_COUNT = PQueue_count(this), PQueue_INDEX; \
  if (PQueue_COUNT < 0) PQueue_COUNT = -PQueue_COUNT; \
  for (PQueue_INDEX = 0; PQueue_INDEX < PQueue_COUNT; PQueue_INDEX++) { \
    PQueueEntry PQueue_ENTRY = PQueue_ENTRIES + PQueue_INDEX; \
    Type member = (Type)PQueueEntry_MEMBER(PQueue_ENTRY);
#define PQueue_ENDEACH \
  } \
}