/** @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
