list.c

来自「Sun公司Dream项目」· C语言 代码 · 共 816 行 · 第 1/2 页

C
816
字号
/*
 * 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
 * http://www.opensource.org/licenses/cddl1.php
 * 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
 * http://www.opensource.org/licenses/cddl1.php.  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]
 */ 

/*
 * $(@)List.c $Revision: 1.2 $ $Date: 2006/07/15 00:02:34 $
 * 
 * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
 */
/*
 * Copyright (c) 1995 by Sun Microsystems, Inc.
 */

/*
 * List.c -- A doubly-linked list of item pointers.
 */

#pragma ident "@(#)List.c 1.4	99/05/28 SMI"

#if	!defined(LIST_HEADER)
#define	LIST_BODY
#define	LIST_INLINE	extern
#include "cobjs/List.h"
#endif	/* !defined(LIST_HEADER) */

#include <stdlib.h>
#include <synch.h>

#include "cobjs/Inline.h"
#include "cobjs/Log.h"
#include "cobjs/Macros.h"
#include "cobjs/Types.h"

#define	LIST_INIT_FREECNT		100

typedef struct ListItem ListItem;

struct ListItem {
    ListItem           *nextp;
    ListItem           *prevp;
    const void         *itemp;
};

struct _ListIter {
    List                list;
    ListItem           *curLip;
    ListItem            curLi;
    ListIter	        nextIterp;
};

/*
 * OBJECT List Instance Variables
 */
struct _List {
    ListItemSort        lis;
    ListItemIdentical   lii;
    size_t              size;		    /* INCLUDING ANCHOR! */
    ListItem		*freeItemp;
    ListItem		*itemArray;
#ifdef	ASSERTS
    Boolean		wasModified;
#endif /* ASSERTS */
    mutex_t		iterLock;
    struct _ListIter	iterHead;
};

static ListItem *listItemNew(List list);
static ListItem *listItem(List list, ListRef ref);
static ListRef listRef(List list, ListItem *lip);
static void listItemFree(List list, ListItem *lip);

INLINE_PRIVATE void listExpandFree(List list);

LIST_INLINE void   *
listHead(const List list)
{
    ListItem           *lip = list->itemArray[0].nextp;

    return lip != &list->itemArray[0] ? (void *) lip->itemp : NULL;
}

LIST_INLINE void   *
listTail(const List list)
{
    ListItem           *lip = list->itemArray[0].prevp;

    return lip != &list->itemArray[0] ? (void *) lip->itemp : NULL;
}

LIST_INLINE ListRef
listHeadInsert(List list, const void *itemp)
{
    ListItem           *nip = listItemNew(list);
    ListItem           *lip = list->itemArray[0].nextp;

    nip->itemp = itemp;

    lip->prevp->nextp = nip;
    nip->nextp = lip;
    nip->prevp = lip->prevp;
    lip->prevp = nip;
    list->size += 1;
#ifdef	ASSERTS
    list->wasModified = TRUE;
#endif /* ASSERTS */
    return listRef(list, nip);
}

LIST_INLINE ListRef
listTailInsert(List list, const void *itemp)
{
    ListItem           *nip = listItemNew(list);
    ListItem           *lip = &list->itemArray[0];

    nip->itemp = itemp;

    lip->prevp->nextp = nip;
    nip->nextp = lip;
    nip->prevp = lip->prevp;
    lip->prevp = nip;
    list->size += 1;
#ifdef	ASSERTS
    list->wasModified = TRUE;
#endif /* ASSERTS */
    return listRef(list, nip);
}

LIST_INLINE void               *
listHeadRemove(List list)
{
    ListItem           *lip = list->itemArray[0].nextp;
    void               *itemp = NULL;

    if (lip != &list->itemArray[0]) {
	lip->prevp->nextp = lip->nextp;
	lip->nextp->prevp = lip->prevp;
	itemp = (void *) lip->itemp;
	listItemFree(list, lip);
	list->size -= 1;
    }
#ifdef	ASSERTS
    list->wasModified = TRUE;
#endif /* ASSERTS */
    return itemp;
}

LIST_INLINE void               *
listTailRemove(List list)
{
    ListItem           *lip = list->itemArray[0].prevp;
    void               *itemp = NULL;

    if (lip != &list->itemArray[0]) {
	lip->prevp->nextp = lip->nextp;
	lip->nextp->prevp = lip->prevp;
	itemp = (void *) lip->itemp;
	listItemFree(list, lip);
	list->size -= 1;
    }
#ifdef	ASSERTS
    list->wasModified = TRUE;
#endif /* ASSERTS */
    return itemp;
}

LIST_INLINE void               *
listRefRemove(List list, ListRef ref)
{
    ListItem           *lip = listItem(list, ref);
    void               *itemp;

    lip->prevp->nextp = lip->nextp;
    lip->nextp->prevp = lip->prevp;
    itemp = (void *) lip->itemp;
    listItemFree(list, lip);
    list->size -= 1;
#ifdef	ASSERTS
    list->wasModified = TRUE;
#endif /* ASSERTS */
    return itemp;
}

LIST_INLINE void        *
listRefItem(List list, ListRef ref)
{
    return (void *) listItem(list, ref)->itemp;
}

LIST_INLINE void
listRefUpdate(List list, ListRef ref, const void *itemp)
{
    listItem(list, ref)->itemp = itemp;
#ifdef	ASSERTS
    list->wasModified = TRUE;
#endif /* ASSERTS */
}

LIST_INLINE Boolean
listIsEmpty(const List list)
{
    return Boolean(list->itemArray[0].nextp == &list->itemArray[0]);
}

LIST_INLINE size_t
listSize(const List list)
{
    /* decr by 1 because anchor is counted */
    return list->size - 1;
}

/************************************************************************
 * OBJECT ListIter Inlinable Instance Interface
 ************************************************************************/

/*
 * Position iterator at list head Returns TRUE if list is non-empty; FALSE if
 * list is empty.
 */
LIST_INLINE Boolean
listIterHead(ListIter li)
{
    li->curLip = li->list->itemArray[0].nextp;
    li->curLi = *li->curLip;
#ifdef	ASSERTS
    li->list->wasModified = FALSE;
#endif /* ASSERTS */
    return Boolean(li->curLip != &li->list->itemArray[0]);
}

/*
 * Position iterator at list tail Returns TRUE if list is non-empty; FALSE if
 * list is empty.
 */
LIST_INLINE Boolean
listIterTail(ListIter li)
{
#ifdef	ASSERTS
    li->list->wasModified = FALSE;
#endif /* ASSERTS */
    li->curLip = li->list->itemArray[0].prevp;
    li->curLi = *li->curLip;
    return Boolean(li->curLip != &li->list->itemArray[0]);
}

/*
 * Position iterator at next item in list. Return TRUE if there is a next
 * item; FALSE if wrapping around.
 */
LIST_INLINE Boolean
listIterNext(ListIter li)
{
    if (li->curLip == NULL) {
	li->curLip = &li->list->itemArray[0];
	li->curLi = *li->curLip;
#ifdef	ASSERTS
	li->list->wasModified = FALSE;
#endif /* ASSERTS */
    }
    ASSERT(! li->list->wasModified);
    li->curLip = li->curLi.nextp;
    li->curLi = *li->curLip;
    return Boolean(li->curLip != &li->list->itemArray[0]);
}

/*
 * Position iterator at previous item in list. Return TRUE if there is a
 * previous item; FALSE if wrapping around.
 */
LIST_INLINE Boolean
listIterPrev(ListIter li)
{
    if (li->curLip == NULL) {
	li->curLip = &li->list->itemArray[0];
	li->curLi = *li->curLip;
#ifdef	ASSERTS
	li->list->wasModified = FALSE;
#endif /* ASSERTS */
    }
    ASSERT(! li->list->wasModified);
    li->curLip = li->curLi.prevp;
    li->curLi = *li->curLip;
    return Boolean(li->curLip != &li->list->itemArray[0]);
}

LIST_INLINE void
listIterRef(ListIter li, ListRef ref)
{
    li->curLip = listItem(li->list, ref);
    li->curLi = *li->curLip;
#ifdef	ASSERTS
    li->list->wasModified = FALSE;
#endif /* ASSERTS */
}

/*
 * Return the item referenced by the iterator Returns NULL if iterator not
 * positioned at item.
 */
LIST_INLINE void   *
listIterItem(const ListIter li)
{
    ASSERT(! li->list->wasModified);
    return (void *) li->curLi.itemp;
}

/*
 * Return TRUE if iterator points to valid item
 */
LIST_INLINE Boolean
listIterValid(const ListIter li)
{
    ASSERT(! li->list->wasModified);
    return Boolean(li->curLip != NULL && li->curLip != &li->list->itemArray[0]);
}

LIST_INLINE ListRef
listIterToRef(const ListIter li)
{
    ASSERT(! li->list->wasModified);
    return li->curLip == NULL ? 0 : li->curLip - &li->list->itemArray[0];
}

/*
 * Removes and returns the item referenced by the iterator. Returns NULL if
 * iterator not positioned at item.
 */
LIST_INLINE void               *
listIterRemove(ListIter li)
{
    ListItem           *lip = li->curLip;

    ASSERT(! li->list->wasModified);
    if (lip != NULL && lip != &li->list->itemArray[0]) {
	lip->prevp->nextp = lip->nextp;
	lip->nextp->prevp = lip->prevp;
	listItemFree(li->list, lip);
	li->list->size -= 1;
    }
    li->curLip = &li->list->itemArray[0];
    return (void *) li->curLi.itemp;
}

/*
 * Insert an item before the item reference by the iterator. Iterator
 * position is unchanged.  If iterator is not positioned at item, insert at
 * list head.
 */
LIST_INLINE ListRef
listIterInsert(ListIter li, const void *itemp)
{
    ListItem           *nip = listItemNew(li->list);
    ListItem           *lip = li->curLip;

    ASSERT(! li->list->wasModified);
    if (lip == NULL || lip == &li->list->itemArray[0]) {
	lip = li->list->itemArray[0].nextp;
    }
    nip->itemp = itemp;

    lip->prevp->nextp = nip;
    nip->nextp = lip;
    nip->prevp = lip->prevp;
    lip->prevp = nip;

    li->curLi = *li->curLip;
    li->list->size += 1;
    return listRef(li->list, nip);
}

/*
 * Append an item after the item reference by the iterator. Iterator position
 * is unchanged.  If iterator is not positioned at item, insert at list tail.
 */
LIST_INLINE ListRef
listIterAppend(ListIter li, const void *itemp)
{
    ListItem           *nip = listItemNew(li->list);
    ListItem           *lip = li->curLip;

    ASSERT(! li->list->wasModified);
    if (lip == NULL || lip == &li->list->itemArray[0]) {
	lip = li->list->itemArray[0].prevp;
    }
    nip->itemp = itemp;

    lip->nextp->prevp = nip;
    nip->prevp = lip;
    nip->nextp = lip->nextp;
    lip->nextp = nip;

    li->curLi = *li->curLip;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?