/** @file | |
An ordered collection library interface. | |
The library class provides a set of APIs to manage an ordered collection of | |
items. | |
Copyright (C) 2014, Red Hat, Inc. | |
This program and the accompanying materials are licensed and made available | |
under the terms and conditions of the BSD License that accompanies this | |
distribution. The full text of the license may be found at | |
http://opensource.org/licenses/bsd-license.php. | |
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT | |
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
**/ | |
#ifndef __ORDERED_COLLECTION_LIB__ | |
#define __ORDERED_COLLECTION_LIB__ | |
#include <Base.h> | |
// | |
// Opaque structure for a collection. | |
// | |
typedef struct ORDERED_COLLECTION ORDERED_COLLECTION; | |
// | |
// Opaque structure for collection entries. | |
// | |
// Collection entries do not take ownership of the associated user structures, | |
// they only link them. This makes it easy to link the same user structure into | |
// several collections. If reference counting is required, the caller is | |
// responsible for implementing it, as part of the user structure. | |
// | |
// A pointer-to-ORDERED_COLLECTION_ENTRY is considered an "iterator". Multiple, | |
// simultaneous iterations are supported. | |
// | |
typedef struct ORDERED_COLLECTION_ENTRY ORDERED_COLLECTION_ENTRY; | |
// | |
// Altering the key field of an in-collection user structure (ie. the portion | |
// of the user structure that ORDERED_COLLECTION_USER_COMPARE and | |
// ORDERED_COLLECTION_KEY_COMPARE, below, read) is not allowed in-place. The | |
// caller is responsible for bracketing the key change with the deletion and | |
// the reinsertion of the user structure, so that the changed key value is | |
// reflected in the collection. | |
// | |
/** | |
Comparator function type for two user structures. | |
@param[in] UserStruct1 Pointer to the first user structure. | |
@param[in] UserStruct2 Pointer to the second user structure. | |
@retval <0 If UserStruct1 compares less than UserStruct2. | |
@retval 0 If UserStruct1 compares equal to UserStruct2. | |
@retval >0 If UserStruct1 compares greater than UserStruct2. | |
**/ | |
typedef | |
INTN | |
(EFIAPI *ORDERED_COLLECTION_USER_COMPARE)( | |
IN CONST VOID *UserStruct1, | |
IN CONST VOID *UserStruct2 | |
); | |
/** | |
Compare a standalone key against a user structure containing an embedded key. | |
@param[in] StandaloneKey Pointer to the bare key. | |
@param[in] UserStruct Pointer to the user structure with the embedded | |
key. | |
@retval <0 If StandaloneKey compares less than UserStruct's key. | |
@retval 0 If StandaloneKey compares equal to UserStruct's key. | |
@retval >0 If StandaloneKey compares greater than UserStruct's key. | |
**/ | |
typedef | |
INTN | |
(EFIAPI *ORDERED_COLLECTION_KEY_COMPARE)( | |
IN CONST VOID *StandaloneKey, | |
IN CONST VOID *UserStruct | |
); | |
// | |
// Some functions below are read-only, while others are read-write. If any | |
// write operation is expected to run concurrently with any other operation on | |
// the same collection, then the caller is responsible for implementing locking | |
// for the whole collection. | |
// | |
/** | |
Retrieve the user structure linked by the specified collection entry. | |
Read-only operation. | |
@param[in] Entry Pointer to the collection entry whose associated user | |
structure we want to retrieve. The caller is responsible | |
for passing a non-NULL argument. | |
@return Pointer to user structure linked by Entry. | |
**/ | |
VOID * | |
EFIAPI | |
OrderedCollectionUserStruct ( | |
IN CONST ORDERED_COLLECTION_ENTRY *Entry | |
); | |
/** | |
Allocate and initialize the ORDERED_COLLECTION structure. | |
@param[in] UserStructCompare This caller-provided function will be used to | |
order two user structures linked into the | |
collection, during the insertion procedure. | |
@param[in] KeyCompare This caller-provided function will be used to | |
order the standalone search key against user | |
structures linked into the collection, during | |
the lookup procedure. | |
@retval NULL If allocation failed. | |
@return Pointer to the allocated, initialized ORDERED_COLLECTION | |
structure, otherwise. | |
**/ | |
ORDERED_COLLECTION * | |
EFIAPI | |
OrderedCollectionInit ( | |
IN ORDERED_COLLECTION_USER_COMPARE UserStructCompare, | |
IN ORDERED_COLLECTION_KEY_COMPARE KeyCompare | |
); | |
/** | |
Check whether the collection is empty (has no entries). | |
Read-only operation. | |
@param[in] Collection The collection to check for emptiness. | |
@retval TRUE The collection is empty. | |
@retval FALSE The collection is not empty. | |
**/ | |
BOOLEAN | |
EFIAPI | |
OrderedCollectionIsEmpty ( | |
IN CONST ORDERED_COLLECTION *Collection | |
); | |
/** | |
Uninitialize and release an empty ORDERED_COLLECTION structure. | |
Read-write operation. | |
It is the caller's responsibility to delete all entries from the collection | |
before calling this function. | |
@param[in] Collection The empty collection to uninitialize and release. | |
**/ | |
VOID | |
EFIAPI | |
OrderedCollectionUninit ( | |
IN ORDERED_COLLECTION *Collection | |
); | |
/** | |
Look up the collection entry that links the user structure that matches the | |
specified standalone key. | |
Read-only operation. | |
@param[in] Collection The collection to search for StandaloneKey. | |
@param[in] StandaloneKey The key to locate among the user structures linked | |
into Collection. StandaloneKey will be passed to | |
ORDERED_COLLECTION_KEY_COMPARE. | |
@retval NULL StandaloneKey could not be found. | |
@return The collection entry that links to the user structure matching | |
StandaloneKey, otherwise. | |
**/ | |
ORDERED_COLLECTION_ENTRY * | |
EFIAPI | |
OrderedCollectionFind ( | |
IN CONST ORDERED_COLLECTION *Collection, | |
IN CONST VOID *StandaloneKey | |
); | |
/** | |
Find the collection entry of the minimum user structure stored in the | |
collection. | |
Read-only operation. | |
@param[in] Collection The collection to return the minimum entry of. The | |
user structure linked by the minimum entry compares | |
less than all other user structures in the collection. | |
@retval NULL If Collection is empty. | |
@return The collection entry that links the minimum user structure, | |
otherwise. | |
**/ | |
ORDERED_COLLECTION_ENTRY * | |
EFIAPI | |
OrderedCollectionMin ( | |
IN CONST ORDERED_COLLECTION *Collection | |
); | |
/** | |
Find the collection entry of the maximum user structure stored in the | |
collection. | |
Read-only operation. | |
@param[in] Collection The collection to return the maximum entry of. The | |
user structure linked by the maximum entry compares | |
greater than all other user structures in the | |
collection. | |
@retval NULL If Collection is empty. | |
@return The collection entry that links the maximum user structure, | |
otherwise. | |
**/ | |
ORDERED_COLLECTION_ENTRY * | |
EFIAPI | |
OrderedCollectionMax ( | |
IN CONST ORDERED_COLLECTION *Collection | |
); | |
/** | |
Get the collection entry of the least user structure that is greater than the | |
one linked by Entry. | |
Read-only operation. | |
@param[in] Entry The entry to get the successor entry of. | |
@retval NULL If Entry is NULL, or Entry is the maximum entry of its | |
containing collection (ie. Entry has no successor entry). | |
@return The collection entry linking the least user structure that is | |
greater than the one linked by Entry, otherwise. | |
**/ | |
ORDERED_COLLECTION_ENTRY * | |
EFIAPI | |
OrderedCollectionNext ( | |
IN CONST ORDERED_COLLECTION_ENTRY *Entry | |
); | |
/** | |
Get the collection entry of the greatest user structure that is less than the | |
one linked by Entry. | |
Read-only operation. | |
@param[in] Entry The entry to get the predecessor entry of. | |
@retval NULL If Entry is NULL, or Entry is the minimum entry of its | |
containing collection (ie. Entry has no predecessor entry). | |
@return The collection entry linking the greatest user structure that | |
is less than the one linked by Entry, otherwise. | |
**/ | |
ORDERED_COLLECTION_ENTRY * | |
EFIAPI | |
OrderedCollectionPrev ( | |
IN CONST ORDERED_COLLECTION_ENTRY *Entry | |
); | |
/** | |
Insert (link) a user structure into the collection, allocating a new | |
collection entry. | |
Read-write operation. | |
@param[in,out] Collection The collection to insert UserStruct into. | |
@param[out] Entry The meaning of this optional, output-only | |
parameter depends on the return value of the | |
function. | |
When insertion is successful (RETURN_SUCCESS), | |
Entry is set on output to the new collection entry | |
that now links UserStruct. | |
When insertion fails due to lack of memory | |
(RETURN_OUT_OF_RESOURCES), Entry is not changed. | |
When insertion fails due to key collision (ie. | |
another user structure is already in the | |
collection that compares equal to UserStruct), | |
with return value RETURN_ALREADY_STARTED, then | |
Entry is set on output to the entry that links the | |
colliding user structure. This enables | |
"find-or-insert" in one function call, or helps | |
with later removal of the colliding element. | |
@param[in] UserStruct The user structure to link into the collection. | |
UserStruct is ordered against in-collection user | |
structures with the | |
ORDERED_COLLECTION_USER_COMPARE function. | |
@retval RETURN_SUCCESS Insertion successful. A new collection entry | |
has been allocated, linking UserStruct. The | |
new collection entry is reported back in | |
Entry (if the caller requested it). | |
Existing ORDERED_COLLECTION_ENTRY pointers | |
into Collection remain valid. For example, | |
on-going iterations in the caller can | |
continue with OrderedCollectionNext() / | |
OrderedCollectionPrev(), and they will | |
return the new entry at some point if user | |
structure order dictates it. | |
@retval RETURN_OUT_OF_RESOURCES The function failed to allocate memory for | |
the new collection entry. The collection has | |
not been changed. Existing | |
ORDERED_COLLECTION_ENTRY pointers into | |
Collection remain valid. | |
@retval RETURN_ALREADY_STARTED A user structure has been found in the | |
collection that compares equal to | |
UserStruct. The entry linking the colliding | |
user structure is reported back in Entry (if | |
the caller requested it). The collection has | |
not been changed. Existing | |
ORDERED_COLLECTION_ENTRY pointers into | |
Collection remain valid. | |
**/ | |
RETURN_STATUS | |
EFIAPI | |
OrderedCollectionInsert ( | |
IN OUT ORDERED_COLLECTION *Collection, | |
OUT ORDERED_COLLECTION_ENTRY **Entry OPTIONAL, | |
IN VOID *UserStruct | |
); | |
/** | |
Delete an entry from the collection, unlinking the associated user structure. | |
Read-write operation. | |
@param[in,out] Collection The collection to delete Entry from. | |
@param[in] Entry The collection entry to delete from Collection. | |
The caller is responsible for ensuring that Entry | |
belongs to Collection, and that Entry is non-NULL | |
and valid. Entry is typically an earlier return | |
value, or output parameter, of: | |
- OrderedCollectionFind(), for deleting an entry | |
by user structure key, | |
- OrderedCollectionMin() / OrderedCollectionMax(), | |
for deleting the minimum / maximum entry, | |
- OrderedCollectionNext() / | |
OrderedCollectionPrev(), for deleting an entry | |
found during an iteration, | |
- OrderedCollectionInsert() with return value | |
RETURN_ALREADY_STARTED, for deleting an entry | |
whose linked user structure caused collision | |
during insertion. | |
Existing ORDERED_COLLECTION_ENTRY pointers (ie. | |
iterators) *different* from Entry remain valid. | |
For example: | |
- OrderedCollectionNext() / | |
OrderedCollectionPrev() iterations in the caller | |
can be continued from Entry, if | |
OrderedCollectionNext() or | |
OrderedCollectionPrev() is called on Entry | |
*before* OrderedCollectionDelete() is. That is, | |
fetch the successor / predecessor entry first, | |
then delete Entry. | |
- On-going iterations in the caller that would | |
have otherwise returned Entry at some point, as | |
dictated by user structure order, will correctly | |
reflect the absence of Entry after | |
OrderedCollectionDelete() is called | |
mid-iteration. | |
@param[out] UserStruct If the caller provides this optional output-only | |
parameter, then on output it is set to the user | |
structure originally linked by Entry (which is now | |
freed). | |
This is a convenience that may save the caller a | |
OrderedCollectionUserStruct() invocation before | |
calling OrderedCollectionDelete(), in order to | |
retrieve the user structure being unlinked. | |
**/ | |
VOID | |
EFIAPI | |
OrderedCollectionDelete ( | |
IN OUT ORDERED_COLLECTION *Collection, | |
IN ORDERED_COLLECTION_ENTRY *Entry, | |
OUT VOID **UserStruct OPTIONAL | |
); | |
#endif |