|
Packit Service |
d40955 |
/*
|
|
Packit Service |
d40955 |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
d40955 |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
d40955 |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
d40955 |
* of the License, or (at your option) any later version.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
d40955 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
d40955 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
d40955 |
* GNU General Public License for more details.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
d40955 |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
d40955 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
d40955 |
* 02110-1301, USA.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/base/priorityTable.h#2 $
|
|
Packit Service |
d40955 |
*/
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#ifndef PRIORITY_TABLE_H
|
|
Packit Service |
d40955 |
#define PRIORITY_TABLE_H
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#include "ringNode.h"
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* A PriorityTable is a simple implementation of a priority queue for entries
|
|
Packit Service |
d40955 |
* with priorities that are small non-negative integer values. It implements
|
|
Packit Service |
d40955 |
* the obvious priority queue operations of enqueuing an entry and dequeuing
|
|
Packit Service |
d40955 |
* an entry with the maximum priority. It also supports removing an arbitrary
|
|
Packit Service |
d40955 |
* entry. The priority of an entry already in the table can be changed by
|
|
Packit Service |
d40955 |
* removing it and re-enqueuing it with a different priority. All operations
|
|
Packit Service |
d40955 |
* have O(1) complexity.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* The links for the table entries must be embedded in the entries themselves.
|
|
Packit Service |
d40955 |
* RingNode is used to link entries in the table and no wrapper type is
|
|
Packit Service |
d40955 |
* declared, so an existing RingNode link in an object can also be used to
|
|
Packit Service |
d40955 |
* queue it in a PriorityTable, assuming the field is not used for anything
|
|
Packit Service |
d40955 |
* else while so queued.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* The table is implemented as an array of queues (circular lists) indexed by
|
|
Packit Service |
d40955 |
* priority, along with a hint for which queues are non-empty. Steven Skiena
|
|
Packit Service |
d40955 |
* calls a very similar structure a "bounded height priority queue", but given
|
|
Packit Service |
d40955 |
* the resemblance to a hash table, "priority table" seems both shorter and
|
|
Packit Service |
d40955 |
* more apt, if somewhat novel.
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
typedef struct priorityTable PriorityTable;
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Allocate and initialize a new PriorityTable.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param [in] maxPriority The maximum priority value for table entries
|
|
Packit Service |
d40955 |
* @param [out] tablePtr A pointer to hold the new table
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return VDO_SUCCESS or an error code
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
int makePriorityTable(unsigned int maxPriority, PriorityTable **tablePtr)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Free a PriorityTable and null out the reference to it. NOTE: The table does
|
|
Packit Service |
d40955 |
* not own the entries stored in it and they are not freed by this call.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param [in,out] tablePtr The reference to the table to free
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
void freePriorityTable(PriorityTable **tablePtr);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Add a new entry to the priority table, appending it to the queue for
|
|
Packit Service |
d40955 |
* entries with the specified priority.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param table The table in which to store the entry
|
|
Packit Service |
d40955 |
* @param priority The priority of the entry
|
|
Packit Service |
d40955 |
* @param entry The RingNode embedded in the entry to store in the table
|
|
Packit Service |
d40955 |
* (the caller must have initialized it)
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
void priorityTableEnqueue(PriorityTable *table,
|
|
Packit Service |
d40955 |
unsigned int priority,
|
|
Packit Service |
d40955 |
RingNode *entry);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Reset a priority table, leaving it in the same empty state as when newly
|
|
Packit Service |
d40955 |
* constructed. NOTE: The table does not own the entries stored in it and they
|
|
Packit Service |
d40955 |
* are not freed (or even unlinked from each other) by this call.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param table The table to reset
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
void resetPriorityTable(PriorityTable *table);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Find the highest-priority entry in the table, remove it from the table, and
|
|
Packit Service |
d40955 |
* return it. If there are multiple entries with the same priority, the one
|
|
Packit Service |
d40955 |
* that has been in the table with that priority the longest will be returned.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param table The priority table from which to remove an entry
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return the dequeued entry, or NULL if the table is currently empty
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
RingNode *priorityTableDequeue(PriorityTable *table)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Remove a specified entry from its priority table.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param table The table from which to remove the entry
|
|
Packit Service |
d40955 |
* @param entry The entry to remove from the table
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
void priorityTableRemove(PriorityTable *table, RingNode *entry);
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
/**
|
|
Packit Service |
d40955 |
* Return whether the priority table is empty.
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @param table The table to check
|
|
Packit Service |
d40955 |
*
|
|
Packit Service |
d40955 |
* @return true if the table is empty
|
|
Packit Service |
d40955 |
**/
|
|
Packit Service |
d40955 |
bool isPriorityTableEmpty(PriorityTable *table)
|
|
Packit Service |
d40955 |
__attribute__((warn_unused_result));
|
|
Packit Service |
d40955 |
|
|
Packit Service |
d40955 |
#endif /* PRIORITY_TABLE_H */
|