/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/sysmacros.h>
static void group_grow_set(group_t *);
static void group_shrink_set(group_t *);
static void group_pack_set(void **, uint_t);
/*
* Initialize a group_t
*/
void
{
}
/*
* Destroy a group_t
* The group must already be empty
*/
void
{
if (g->grp_capacity > 0) {
g->grp_capacity = 0;
}
}
/*
* Empty a group_t
* Capacity is preserved.
*/
void
{
int i;
g->grp_size = 0;
for (i = 0; i < sz; i++)
}
/*
* Add element "e" to group "g"
*
* Returns -1 if addition would result in overcapacity, and
* resize operations aren't allowed, and 0 otherwise
*/
int
{
int entry;
if ((gflag & GRP_NORESIZE) &&
g->grp_size == g->grp_capacity)
return (-1);
if (g->grp_size > g->grp_capacity)
group_grow_set(g);
return (0);
}
/*
* Remove element "e" from group "g"
*
* Returns -1 if "e" was not present in "g" and 0 otherwise
*/
int
{
int i;
if (g->grp_size == 0)
return (-1);
/*
* Find the element in the group's set
*/
for (i = 0; i < g->grp_size; i++)
if (g->grp_set[i] == e)
break;
if (g->grp_set[i] != e)
return (-1);
g->grp_size--;
if ((gflag & GRP_RESIZE) &&
group_shrink_set(g);
return (0);
}
/*
* Expand the capacity of group "g" so that it may
* contain at least "n" elements
*/
void
{
while (g->grp_capacity < n)
group_grow_set(g);
}
/*
* Upsize a group's holding capacity
*/
static void
{
cap_old = g->grp_capacity;
/*
* The array size grows in powers of two
*/
/*
* The set is unallocated.
* Allocate a default sized set.
*/
g->grp_capacity = cap_new;
} else {
/*
* Allocate a newly sized array,
* copy the data, and free the old array.
*/
g->grp_capacity = cap_new;
}
/*
* The new array size should be a power of two
*/
}
/*
* Downsize a group's holding capacity
*/
static void
{
cap_old = g->grp_capacity;
/*
* The group's existing array size must already
* be a power of two
*/
/*
* GRP_SET_SIZE_DEFAULT is the minumum set size.
*/
if (cap_new < GRP_SET_SIZE_DEFAULT)
return;
g->grp_capacity = cap_new;
}
/*
* Pack a group's set
* Element order is not preserved
*/
static void
{
for (i = 0; i < sz; i++) {
/*
* Found a new free slot.
* Start packing from here.
*/
free = i;
/*
* Found a slot to pack into
* an earlier free slot.
*/
/*
* Find the next free slot
*/
ASSERT(j <= i);
if (j == i)
break;
}
free = j;
else
}
}
}
/*
* Initialize a group iterator cookie
*/
void
{
*iter = 0;
}
/*
* Iterate over the elements in a group
*/
void *
{
break;
}
return (data);
}
/*
* Indexed access to a group's elements
*/
void *
{
if (idx >= g->grp_capacity)
return (NULL);
}
/*
* Add a new ordered group element at specified
* index. The group must already be of sufficient
* capacity to hold an element at the specified index.
*
* Returns 0 if addition was sucessful, and -1 if the
* addition failed because the table was too small
*/
int
{
if (idx >= g->grp_capacity)
return (-1);
return (0);
}
/*
* Remove the element at the specified index
*/
void
{
}
/*
* Find an element in the group, and return its index
* Returns -1 if the element could not be found.
*/
{
return (idx);
}
return ((uint_t)-1);
}
/*
* Return a string in a given buffer with list of integer entries in a group.
* The string concatenates consecutive integer ranges ax x-y.
* The resulting string looks like "1,2-5,8"
*
* The convert argument is used to map group elements to integer IDs.
*/
char *
{
void *v;
/*
* Allow for the terminating NULL-byte
*/
int nbytes = 0;
if (first_iteration) {
/*
* Got consecutive ID, so extend end of range without
* doing anything since the range may extend further
*/
} else {
if (first_value) {
} else {
*ptr++ = ',';
len--;
}
if (len == 0)
break;
/*
* Next ID is not consecutive, so dump IDs gotten so
* far.
*/
else /* same value */
if (nbytes <= 0) {
len = 0;
break;
}
/*
* Advance position in the string
*/
/*
* Try finding consecutive range starting from current
* ID.
*/
}
}
if (!first_value) {
*ptr++ = ',';
len--;
}
/*
* Print last ID(s)
*/
if (len > 0) {
} else {
}
}
return (buffer);
}