home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1995 by Oracle Corporation. All Rights Reserved.
- *
- * yslst.h - Linked List Manipulation
- *
- * DESCRIPTION
- * This package implements doubly-linked lists in a fast, general purpose
- * manner. Each list consists of zero or more list elements. List elements
- * may either hold a pointer, or may hold copied data. See ysDLst*() below
- * for more information about the data-oriented list routines.
- *
- * THREAD SAFETY
- * The user of this package is responsible for coordinating access to a
- * list among multiple threads. Locking a mutex associated with an
- * individual list is sufficient to protect that list during insert and
- * removal operations.
- */
-
- #ifndef YSLST_ORACLE
- #define YSLST_ORACLE
-
- #ifndef SYSX_ORACLE
- #include <sysx.h>
- #endif
- #ifndef YS_ORACLE
- #include <ys.h>
- #endif
- #ifndef YSFO_ORACLE
- #include <ysfo.h>
- #endif
-
- EXTC_START
-
- /*
- * ysLstCreate, ysLstDestroy - create and destroy a list
- *
- * DESCRIPTION
- * ysLstCreate() creates and returns an empty list. ysLstDestroy() destroys
- * a list previously allocated with ysLstCreate(). If the list is not empty
- * and destructor is a valid function pointer, the destructor function will
- * be invoked once on the value of each list element. In any case, the list
- * itself is destroyed.
- */
- yslst *ysLstCreate(void);
- void ysLstDestroy(yslst *l, ysmff destructor);
-
- /*
- * ysLstHead, ysLstTail, ysLstPrev, ysLstNext, ysLstVal, ysLstCount
- * - List Navigation
- *
- * SYNOPSIS
- * ysle *ysLstHead(yslst *l);
- * ysle *ysLstTail(yslst *l);
- * ysle *ysLstPrev(ysle *le);
- * ysle *ysLstNext(ysle *le);
- *
- * void *ysLstVal(ysle *le);
- * ub4 ysLstCount(yslst *l);
- *
- * DESCRIPTION
- * Several functions are provided for list navigation and inspection.
- * ysLstHead() and ysLstTail() return the head element and tail element
- * of the list, respectively. ysLstPrev() returns the element previous
- * to the given element, and ysLstNext() returns the element following
- * the given element. If the element requested by one of these routines
- * does not exist, a null pointer is returned. These routines do not
- * alter the list.
- *
- * ysLstVal() extracts the user value from a list element. ysLstCount()
- * returns the number of elements in the list.
- */
- #define ysLstHead(l) ((l)->head)
- #define ysLstTail(l) ((l)->tail)
- #define ysLstPrev(le) ((le)->prev)
- #define ysLstNext(le) ((le)->next)
- #define ysLstVal(le) ((le)->ptr)
- #define ysLstCount(l) ((l)->cnt)
-
- /*
- * ysLstIns, ysLstRem - insert and remove a list element
- *
- * DESCRIPTION
- * ysLstIns() and ysLstRem() provide for ordered insertion and removal of
- * a value in a list. ysLstIns() creates a new list element with the
- * value val, and inserts it into the list following the list element le.
- * If le is null, the new element is inserted at the beginning of the list.
- * The list element created is returned. ysLstRem() removes the list element
- * le, and returns the value of the element. If le is null, the list is left
- * unchanged and a null pointer is returned.
- */
- ysle *ysLstIns(yslst *l, ysle *le, dvoid *val);
- dvoid *ysLstRem(yslst *l, ysle *le);
-
- /*
- * ysLstMov - move a list element
- *
- * DESCRIPTION
- * ysLstMov() moves the list element sle to the position following the
- * list element dle in the list l. Both sle and dle must be part of the
- * list at the time this routine is called. If dle is null, then sle
- * is moved to the beginning of the list. Unlike the sequence ysLstRem()/
- * ysLstIns(), this routine guarantees that the list element pointer
- * remains unchanged.
- */
- void ysLstMov(yslst *l, ysle *sle, ysle *dle);
-
- /*
- * ysLstEnq, ysLstDeq - enqueue and dequeue an element
- * ysLstPush, ysLstPop - push and pop an element
- *
- * SYNOPSIS
- * ysle *ysLstEnq(yslst *l, dvoid *val);
- * dvoid *ysLstDeq(yslst *l);
- * ysle *ysLstPush(yslst *l, dvoid *val);
- * dvoid *ysLstPop(yslst *l);
- *
- * DESCRIPTION
- * Several functions provide common idioms for list usage. ysLstEnq() and
- * ysLstDeq() manipulate the list as a first-in, first-out queue. ysLstPush()
- * and ysLstPop() manipulate the list as a last-in, first-out queue, also
- * known as a stack. If the queue or stack is empty when an element is
- * dequeued or popped, a null pointer is returned. Both ysLstEnq() and
- * ysLstPush() return the list element that was created.
- */
- #define ysLstEnq(l, v) ysLstIns((l), ysLstTail(l), (v))
- #define ysLstDeq(l) ysLstRem((l), ysLstHead(l))
- #define ysLstPush(l, v) ysLstIns((l), (ysle *) 0, (v))
- #define ysLstPop(l) ysLstRem((l), ysLstHead(l))
-
- /*
- * ysLstMetricsOn, ysLstMetricsOff() - instrumented lists
- *
- * DESCRIPTION
- * ysLstMetricsOn() turns on activity metrics for a list. Once on, metrics
- * describing the usage of the list are accumulated. This continues until
- * ysLstMetricsOff() is called, which disables measuring. Turning metrics
- * back on again resets all the accumulated statistics. When a list is
- * created, metrics are off and must explicitly be turned on.
- *
- * If metrics are already on when ysLstMetricsOn() is called, the accumulated
- * statistics are reset. If metrics are already off when ysLstMetricsOff()
- * is called, the routine does nothing.
- *
- * Turning on metrics will affect the performance of the list operations.
- */
- void ysLstMetricsOn(yslst *l);
- void ysLstMetricsOff(yslst *l);
-
- /*
- * ysLstGetMetrics, ysLstGetCurTime - get metrics for a list
- *
- * DESCRIPTION
- * ysLstGetMetrics() returns a set of metrics accumulated for a list since
- * the last call to ysLstMetricsOn(). These metrics are returned in the
- * structure pointed to by metrics. The fields are filled in as follows:
- *
- * totins - total number of elements inserted into the list
- * curlen - current length of list; same as ysLstCount()
- * maxlen - maximum length that the list has ever reached
- * avglen - a rolling weighted average of the list length
- * maxtm - maximum time that an element ever spent on the list (in
- * microseconds)
- * avgtm - a rolling weighted average of the time each element spends
- * in the list (in microseconds)
- *
- * ysLstGetCurTime() returns the amount of time elapsed since the given
- * element was placed on the list.
- *
- * These routines both throw the exception YS_EX_BADPARAM if the given list
- * does not have metrics turned on.
- */
- /* DISABLE check_naming */
- struct yslmtc
- {
- ub4 totins; /* total number of elements inserted into the list */
- ub4 curlen; /* same as ysLstCount() */
- ub4 maxlen; /* maximum length that the list ever reached */
- ub4 avglen; /* average length of the list */
- sysb8 maxtm; /* maximum time an element was in the list (in usecs) */
- sysb8 avgtm; /* average time an element was in the list (in usecs) */
- };
- /* ENABLE check_naming */
-
- void ysLstGetMetrics(yslst *l, yslmtc *metrics);
- void ysLstGetCurTime(yslst *l, ysle *le, sysb8 *delta);
-
- /*
- * Data List Manipulation
- *
- * SYNOPSIS
- * yslst *ysDLstCreate(size_t osz);
- * void ysDLstDestroy(yslst *l);
- * dvoid *ysDLstVal(ysle *le);
- * ysle *ysDLstIns(yslst *l, ysle *le, dvoid *val);
- * dvoid *ysDLstRem(yslst *l, ysle *le, dvoid *val);
- * ysle *ysDLstEnq(yslst *l, dvoid *val);
- * dvoid *ysDLstDeq(yslst *l, dvoid *val);
- * ysle *ysDLstPush(yslst *l, dvoid *val);
- * dvoid *ysDLstPop(yslst *l, dvoid *val);
- *
- * DESCRIPTION
- * Data lists are lists whose elements actually hold data, as opposed to
- * just a pointer to some data like the above list mechanism supports.
- * When using data lists, the values being put onto the list are actually
- * copied. This is convenient when the data that is being put on the
- * list is coming from stack variables.
- *
- * The routines used for data list manipulation are essentially as their
- * pointer-oriented counterparts with the following exceptions:
- *
- * ysDLstCreate() takes the size of the elements that are on the list.
- * This size must be same for all elements. ysDLstRem(), ysDLstDeq(),
- * and ysDLstPop() all take an extra argument which is a pointer to a
- * location where the data value may be copied. The buffer must be
- * osz bytes long. If null, then the value is not copied prior to
- * removal. As a convenience, all of these functions return the
- * argument val for use by the caller. If le is null when passed to
- * ysDLstRem(), the list is left unchanged and a null pointer is
- * returned. If the list is empty when ysDLstDeq() or ysDLstPop()
- * are called, then a null pointer is returned to indicate this fact.
- * Note that is not possible to both pass a null pointer for val and
- * use the return value as a meaningful indicator.
- *
- * ysDLstVal() returns a pointer to the value as it is embedded in the
- * list. This pointer is only valid for as long as the list element
- * remains in the list. Be sure to copy it if the value needs to be
- * saved after the element is removed or the list destroyed. (ysDLstRem()
- * may be used to accomplish the copying and removal of the element
- * simultaneously.
- *
- * ysDLstDestroy() destroys the list along with all values contained
- * within the list. There is no need for a separate destructor function.
- *
- * All routines that do not have a counterpart here may be used directly
- * on lists of this type. BE AWARE THAT THE CODE DOES NOT DO TYPE-
- * CHECKING TO MAKE SURE THAT YOU ARE USING THE RIGHT OPERATIONS ON THE
- * RIGHT LISTS.
- */
- yslst *ysDLstCreate(size_t osz);
- dvoid *ysDLstRem(yslst *l, ysle *le, dvoid *val);
- /* DISABLE check_macro_naming */
- #define ysDLstDestroy(l) ysLstDestroy((l), (ysmff) 0)
- #define ysDLstVal(le) ((dvoid *) &(le)->ptr)
- #define ysDLstIns(l, le, v) ysLstIns((l), (le), (v))
- #define ysDLstEnq(l, v) ysLstIns((l), ysLstTail(l), (v))
- #define ysDLstDeq(l, v) ysDLstRem((l), ysLstHead(l), (v))
- #define ysDLstPush(l, v) ysLstIns((l), (ysle *) 0, (v))
- #define ysDLstPop(l, v) ysDLstRem((l), ysLstHead(l), (v))
- /* ENABLE check_macro_naming */
-
- /*
- * PRIVATE DECLARATIONS
- */
-
- /* DISABLE check_naming */
- struct yslst
- {
- ysle *head; /* head of list */
- ysle *tail; /* tail of list */
- ub4 cnt; /* number of elements */
- size_t osz; /* object size */
- ysfop fop; /* fixed object pool */
- boolean mtcon; /* TRUE if metrics are on */
- yslmtc metrics; /* metrics buffer */
- };
-
- struct ysle
- {
- ysle *next; /* next element in list */
- ysle *prev; /* previous element in list */
- sysb8 enqtm; /* time of enqueue (if metrics are on) */
- dvoid *ptr; /* element value */
- };
- /* ENABLE check_naming */
-
- EXTC_END
- #endif /* YSLST_ORACLE */
-