/*
- * "$Id: array.c 6123 2006-11-21 15:36:04Z mike $"
+ * "$Id: array.c 7616 2008-05-28 00:34:13Z mike $"
*
* Sorted array routines for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007-2008 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
- * "LICENSE.txt" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* This file is subject to the Apple OS-Developed Software exception.
*
void **elements; /* Array elements */
cups_array_func_t compare; /* Element comparison function */
void *data; /* User data passed to compare */
+ cups_ahash_func_t hashfunc; /* Hash function */
+ int hashsize, /* Size of hash */
+ *hash; /* Hash array */
};
* 'cupsArrayAdd()' - Add an element to the array.
*
* When adding an element to a sorted array, non-unique elements are
- * appended at the end of the run. For unsorted arrays, the element
- * is inserted at the end of the array.
+ * appended at the end of the run of identical elements. For unsorted arrays,
+ * the element is appended to the end of the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 1 on success, 0 on failure */
/*
* 'cupsArrayClear()' - Clear the array.
+ *
+ * This function is equivalent to removing all elements in the array.
+ * The caller is responsible for freeing the memory used by the
+ * elements themselves.
+ *
+ * @since CUPS 1.2@
*/
void
/*
* 'cupsArrayCount()' - Get the number of elements in the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - Number of elements */
/*
* 'cupsArrayCurrent()' - Return the current element in the array.
+ *
+ * The current element is undefined until you call @link cupsArrayFind@,
+ * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@.
+ *
+ * @since CUPS 1.2@
*/
void * /* O - Element */
/*
* 'cupsArrayDelete()' - Free all memory used by the array.
+ *
+ * The caller is responsible for freeing the memory used by the
+ * elements themselves.
+ *
+ * @since CUPS 1.2@
*/
void
if (a->alloc_elements)
free(a->elements);
+ if (a->hashsize)
+ free(a->hash);
+
free(a);
}
/*
* 'cupsArrayDup()' - Duplicate the array.
+ *
+ * @since CUPS 1.2@
*/
cups_array_t * /* O - Duplicate array */
/*
* 'cupsArrayFind()' - Find an element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Element found or NULL */
+void * /* O - Element found or @code NULL@ */
cupsArrayFind(cups_array_t *a, /* I - Array */
void *e) /* I - Element */
{
int current, /* Current element */
- diff; /* Difference */
+ diff, /* Difference */
+ hash; /* Hash index */
/*
* Yes, look for a match...
*/
- current = cups_array_find(a, e, a->current, &diff);
+ if (a->hash)
+ {
+ hash = (*(a->hashfunc))(e, a->data);
+
+ if (hash < 0 || hash >= a->hashsize)
+ {
+ current = a->current;
+ hash = -1;
+ }
+ else
+ {
+ current = a->hash[hash];
+
+ if (current < 0 || current >= a->num_elements)
+ current = a->current;
+ }
+ }
+ else
+ {
+ current = a->current;
+ hash = -1;
+ }
+
+ current = cups_array_find(a, e, current, &diff);
if (!diff)
{
/*
a->current = current;
+ if (hash >= 0)
+ a->hash[hash] = current;
+
return (a->elements[current]);
}
else
/*
* 'cupsArrayFirst()' - Get the first element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - First element or NULL */
+void * /* O - First element or @code NULL@ if the array is empty */
cupsArrayFirst(cups_array_t *a) /* I - Array */
{
/*
/*
* 'cupsArrayGetIndex()' - Get the index of the current element.
*
+ * The current element is undefined until you call @link cupsArrayFind@,
+ * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@.
+ *
* @since CUPS 1.3@
*/
-int /* O - Index of the current element */
+int /* O - Index of the current element, starting at 0 */
cupsArrayGetIndex(cups_array_t *a) /* I - Array */
{
if (!a)
* @since CUPS 1.3@
*/
-int /* O - Index of the last inserted element */
+int /* O - Index of the last inserted element, starting at 0 */
cupsArrayGetInsert(cups_array_t *a) /* I - Array */
{
if (!a)
/*
* 'cupsArrayIndex()' - Get the N-th element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - N-th element or NULL */
+void * /* O - N-th element or @code NULL@ */
cupsArrayIndex(cups_array_t *a, /* I - Array */
int n) /* I - Index into array, starting at 0 */
{
* 'cupsArrayInsert()' - Insert an element in the array.
*
* When inserting an element in a sorted array, non-unique elements are
- * inserted at the beginning of the run. For unsorted arrays, the element
- * is inserted at the beginning of the array.
+ * inserted at the beginning of the run of identical elements. For unsorted
+ * arrays, the element is inserted at the beginning of the array.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 0 on failure, 1 on success */
/*
* 'cupsArrayLast()' - Get the last element in the array.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Last element or NULL */
+void * /* O - Last element or @code NULL@ if the array is empty */
cupsArrayLast(cups_array_t *a) /* I - Array */
{
/*
/*
* 'cupsArrayNew()' - Create a new array.
+ *
+ * The comparison function ("f") is used to create a sorted array. The function
+ * receives pointers to two elements and the user data pointer ("d") - the user
+ * data pointer argument can safely be omitted when not required so functions
+ * like @code strcmp@ can be used for sorted string arrays.
+ *
+ * @since CUPS 1.2@
*/
cups_array_t * /* O - Array */
-cupsArrayNew(cups_array_func_t f, /* I - Comparison function */
- void *d) /* I - User data */
+cupsArrayNew(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */
+ void *d) /* I - User data pointer or @code NULL@ */
+{
+ return (cupsArrayNew2(f, d, 0, 0));
+}
+
+
+/*
+ * 'cupsArrayNew2()' - Create a new array with hash.
+ *
+ * The comparison function ("f") is used to create a sorted array. The function
+ * receives pointers to two elements and the user data pointer ("d") - the user
+ * data pointer argument can safely be omitted when not required so functions
+ * like @code strcmp@ can be used for sorted string arrays.
+ *
+ * The hash function ("h") is used to implement cached lookups with the
+ * specified hash size ("hsize").
+ *
+ * @since CUPS 1.3@
+ */
+
+cups_array_t * /* O - Array */
+cupsArrayNew2(cups_array_func_t f, /* I - Comparison function or @code NULL@ for an unsorted array */
+ void *d, /* I - User data or @code NULL@ */
+ cups_ahash_func_t h, /* I - Hash function or @code NULL@ for unhashed lookups */
+ int hsize) /* I - Hash size (>= 0) */
{
cups_array_t *a; /* Array */
a->num_saved = 0;
a->unique = 1;
+ if (hsize > 0 && h)
+ {
+ a->hashfunc = h;
+ a->hashsize = hsize;
+ a->hash = malloc(hsize * sizeof(int));
+
+ if (!a->hash)
+ {
+ free(a);
+ return (NULL);
+ }
+
+ memset(a->hash, -1, hsize * sizeof(int));
+ }
+
return (a);
}
/*
* 'cupsArrayNext()' - Get the next element in the array.
+ *
+ * This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) + 1)".
+ *
+ * The next element is undefined until you call @link cupsArrayFind@,
+ * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@
+ * to set the current element.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Next element or NULL */
+void * /* O - Next element or @code NULL@ */
cupsArrayNext(cups_array_t *a) /* I - Array */
{
/*
/*
* 'cupsArrayPrev()' - Get the previous element in the array.
+ *
+ * This function is equivalent to "cupsArrayIndex(a, cupsArrayGetIndex(a) - 1)".
+ *
+ * The previous element is undefined until you call @link cupsArrayFind@,
+ * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@
+ * to set the current element.
+ *
+ * @since CUPS 1.2@
*/
-void * /* O - Previous element or NULL */
+void * /* O - Previous element or @code NULL@ */
cupsArrayPrev(cups_array_t *a) /* I - Array */
{
/*
/*
* 'cupsArrayRemove()' - Remove an element from the array.
+ *
+ * If more than one element matches "e", only the first matching element is
+ * removed.
+ *
+ * The caller is responsible for freeing the memory used by the
+ * removed element.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 1 on success, 0 on failure */
/*
- * 'cupsArrayRestore()' - Reset the current element to the last cupsArraySave.
+ * 'cupsArrayRestore()' - Reset the current element to the last @link cupsArraySave@.
+ *
+ * @since CUPS 1.2@
*/
void * /* O - New current element */
/*
- * 'cupsArraySave()' - Mark the current element for a later cupsArrayRestore.
+ * 'cupsArraySave()' - Mark the current element for a later @link cupsArrayRestore@.
+ *
+ * The current element is undefined until you call @link cupsArrayFind@,
+ * @link cupsArrayFirst@, or @link cupsArrayIndex@, or @link cupsArrayLast@
+ * to set the current element.
*
* The save/restore stack is guaranteed to be at least 32 elements deep.
+ *
+ * @since CUPS 1.2@
*/
int /* O - 1 on success, 0 on failure */
/*
* 'cupsArrayUserData()' - Return the user data for an array.
+ *
+ * @since CUPS 1.2@
*/
void * /* O - User data */
/*
* 'cups_array_add()' - Insert or append an element to the array...
+ *
+ * @since CUPS 1.2@
*/
static int /* O - 1 on success, 0 on failure */
}
#ifdef DEBUG
else
- printf("cups_array_add: append element at %d...\n", current);
+ DEBUG_printf(("cups_array_add: append element at %d...\n", current));
#endif /* DEBUG */
a->elements[current] = e;
#ifdef DEBUG
for (current = 0; current < a->num_elements; current ++)
- printf("cups_array_add: a->elements[%d]=%p\n", current, a->elements[current]);
+ DEBUG_printf(("cups_array_add: a->elements[%d]=%p\n", current,
+ a->elements[current]));
#endif /* DEBUG */
DEBUG_puts("cups_array_add: returning 1");
/*
* 'cups_array_find()' - Find an element in the array...
+ *
+ * @since CUPS 1.2@
*/
static int /* O - Index of match */
/*
- * End of "$Id: array.c 6123 2006-11-21 15:36:04Z mike $".
+ * End of "$Id: array.c 7616 2008-05-28 00:34:13Z mike $".
*/