Blame source/vdo/base/priorityTable.h

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