https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			420 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			420 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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.
 | 
						|
 | 
						|
  SPDX-License-Identifier: BSD-2-Clause-Patent
 | 
						|
**/
 | 
						|
 | 
						|
#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
 |