list.cpp
来自「konqueror3 embedded版本, KDE环境下的当家浏览器的嵌入式版」· C++ 代码 · 共 329 行
CPP
329 行
/* * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */#include "list.h"#include "internal.h"#ifndef MIN#define MIN(a,b) ((a) < (b) ? (a) : (b))#endif#define DUMP_STATISTICS 0namespace KJS {// tunable parametersconst int poolSize = 32; // must be a power of 2const int inlineValuesSize = 4;// derived constantsconst int poolSizeMask = poolSize - 1;enum ListImpState { unusedInPool = 0, usedInPool, usedOnHeap, immortal };struct ListImp : ListImpBase{ ListImpState state; ValueImp *values[inlineValuesSize]; int capacity; ValueImp **overflow;#if DUMP_STATISTICS int sizeHighWaterMark;#endif};static ListImp pool[poolSize];static int poolCursor;#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. int c = poolCursor; int i = c; do { ListImp *imp = &pool[i]; ListImpState s = imp->state; i = (i + 1) & poolSizeMask; if (s == unusedInPool) { poolCursor = i; imp->state = usedInPool; return imp; } } while (i != c); ListImp *imp = new ListImp; imp->state = usedOnHeap; return imp;}static inline void deallocateListImp(ListImp *imp){ if (imp->state == usedInPool) imp->state = unusedInPool; 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 + =
减小字号Ctrl + -
显示快捷键?