⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 list.cpp

📁 khtml在gtk上的移植版本
💻 CPP
字号:
/* *  This file is part of the KDE libraries *  Copyright (C) 2003 Apple Computer, Inc. * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU Library General Public *  License as published by the Free Software Foundation; either *  version 2 of the License, or (at your option) any later version. * *  This library is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU *  Library General Public License for more details. * *  You should have received a copy of the GNU Library General Public License *  along with this library; see the file COPYING.LIB.  If not, write to *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330, *  Boston, MA 02111-1307, USA. * */#include "list.h"#include "internal.h"#define DUMP_STATISTICS 0namespace KJS {// tunable parametersconst int poolSize = 384;const int inlineValuesSize = 4;enum ListImpState { unusedInPool = 0, usedInPool, usedOnHeap, immortal };struct ListImp : ListImpBase{    ListImpState state;    ValueImp *values[inlineValuesSize];    int capacity;    ValueImp **overflow;    ListImp *nextInFreeList;#if DUMP_STATISTICS    int sizeHighWaterMark;#endif};static ListImp pool[poolSize];static ListImp *poolFreeList;static int poolUsed;#if DUMP_STATISTICSstatic int numLists;static int numListsHighWaterMark;static int listSizeHighWaterMark;static int numListsDestroyed;static int numListsBiggerThan[17];struct ListStatisticsExitLogger { ~ListStatisticsExitLogger(); };static ListStatisticsExitLogger logger;ListStatisticsExitLogger::~ListStatisticsExitLogger(){    printf("\nKJS::List statistics:\n\n");    printf("%d lists were allocated\n", numLists);    printf("%d lists was the high water mark\n", numListsHighWaterMark);    printf("largest list had %d elements\n", listSizeHighWaterMark);    if (numListsDestroyed) {        putc('\n', stdout);        for (int i = 0; i < 17; i++) {            printf("%.1f%% of the lists (%d) had more than %d element%s\n",                100.0 * numListsBiggerThan[i] / numListsDestroyed,                numListsBiggerThan[i],                i, i == 1 ? "" : "s");        }        putc('\n', stdout);    }}#endifstatic inline ListImp *allocateListImp(){    // Find a free one in the pool.    if (poolUsed < poolSize) {	ListImp *imp = poolFreeList ? poolFreeList : &pool[0];	poolFreeList = imp->nextInFreeList ? imp->nextInFreeList : imp + 1;	imp->state = usedInPool;	poolUsed++;	return imp;    }        ListImp *imp = new ListImp;    imp->state = usedOnHeap;    return imp;}static inline void deallocateListImp(ListImp *imp){    if (imp->state == usedInPool) {        imp->state = unusedInPool;	imp->nextInFreeList = poolFreeList;	poolFreeList = imp;	poolUsed--;    } else {        delete imp;    }}List::List() : _impBase(allocateListImp()), _needsMarking(false){    ListImp *imp = static_cast<ListImp *>(_impBase);    imp->size = 0;    imp->refCount = 1;    imp->capacity = 0;    imp->overflow = 0;    if (!_needsMarking) {	imp->valueRefCount = 1;    }#if DUMP_STATISTICS    if (++numLists > numListsHighWaterMark)        numListsHighWaterMark = numLists;    imp->sizeHighWaterMark = 0;#endif}List::List(bool needsMarking) : _impBase(allocateListImp()), _needsMarking(needsMarking){    ListImp *imp = static_cast<ListImp *>(_impBase);    imp->size = 0;    imp->refCount = 1;    imp->capacity = 0;    imp->overflow = 0;    if (!_needsMarking) {	imp->valueRefCount = 1;    }#if DUMP_STATISTICS    if (++numLists > numListsHighWaterMark)        numListsHighWaterMark = numLists;    imp->sizeHighWaterMark = 0;#endif}void List::derefValues(){    ListImp *imp = static_cast<ListImp *>(_impBase);        int size = imp->size;        int inlineSize = MIN(size, inlineValuesSize);    for (int i = 0; i != inlineSize; ++i)        imp->values[i]->deref();        int overflowSize = size - inlineSize;    ValueImp **overflow = imp->overflow;    for (int i = 0; i != overflowSize; ++i)        overflow[i]->deref();}void List::refValues(){    ListImp *imp = static_cast<ListImp *>(_impBase);        int size = imp->size;        int inlineSize = MIN(size, inlineValuesSize);    for (int i = 0; i != inlineSize; ++i)        imp->values[i]->ref();        int overflowSize = size - inlineSize;    ValueImp **overflow = imp->overflow;    for (int i = 0; i != overflowSize; ++i)        overflow[i]->ref();}void List::markValues(){    ListImp *imp = static_cast<ListImp *>(_impBase);        int size = imp->size;        int inlineSize = MIN(size, inlineValuesSize);    for (int i = 0; i != inlineSize; ++i) {	if (!imp->values[i]->marked()) {	    imp->values[i]->mark();	}    }    int overflowSize = size - inlineSize;    ValueImp **overflow = imp->overflow;    for (int i = 0; i != overflowSize; ++i) {	if (!overflow[i]->marked()) {	    overflow[i]->mark();	}    }}void List::release(){    ListImp *imp = static_cast<ListImp *>(_impBase);    #if DUMP_STATISTICS    --numLists;    ++numListsDestroyed;    for (int i = 0; i < 17; i++)        if (imp->sizeHighWaterMark > i)            ++numListsBiggerThan[i];#endif    delete [] imp->overflow;    deallocateListImp(imp);}ValueImp *List::impAt(int i) const{    ListImp *imp = static_cast<ListImp *>(_impBase);    if ((unsigned)i >= (unsigned)imp->size)        return UndefinedImp::staticUndefined;    if (i < inlineValuesSize)        return imp->values[i];    return imp->overflow[i - inlineValuesSize];}void List::clear(){    if (_impBase->valueRefCount > 0) {	derefValues();    }    _impBase->size = 0;}void List::append(ValueImp *v){    ListImp *imp = static_cast<ListImp *>(_impBase);    int i = imp->size++;#if DUMP_STATISTICS    if (imp->size > listSizeHighWaterMark)        listSizeHighWaterMark = imp->size;#endif    if (imp->valueRefCount > 0) {	v->ref();    }        if (i < inlineValuesSize) {        imp->values[i] = v;        return;    }        if (i >= imp->capacity) {        int newCapacity = i * 2;        ValueImp **newOverflow = new ValueImp * [newCapacity - inlineValuesSize];        ValueImp **oldOverflow = imp->overflow;        int oldOverflowSize = i - inlineValuesSize;        for (int j = 0; j != oldOverflowSize; j++)            newOverflow[j] = oldOverflow[j];        delete [] oldOverflow;        imp->overflow = newOverflow;        imp->capacity = newCapacity;    }        imp->overflow[i - inlineValuesSize] = v;}List List::copy() const{    List copy;    ListImp *imp = static_cast<ListImp *>(_impBase);    int size = imp->size;    int inlineSize = MIN(size, inlineValuesSize);    for (int i = 0; i != inlineSize; ++i)        copy.append(imp->values[i]);    ValueImp **overflow = imp->overflow;    int overflowSize = size - inlineSize;    for (int i = 0; i != overflowSize; ++i)        copy.append(overflow[i]);    return copy;}List List::copyTail() const{    List copy;    ListImp *imp = static_cast<ListImp *>(_impBase);    int size = imp->size;    int inlineSize = MIN(size, inlineValuesSize);    for (int i = 1; i < inlineSize; ++i)        copy.append(imp->values[i]);    ValueImp **overflow = imp->overflow;    int overflowSize = size - inlineSize;    for (int i = 0; i < overflowSize; ++i)        copy.append(overflow[i]);    return copy;}const List &List::empty(){    static List emptyList;    return emptyList;}} // namespace KJS

⌨️ 快捷键说明

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