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

📄 property_map.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* *  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 "property_map.h"#include "object.h"#include "protect.h"#include "reference_list.h"#define DEBUG_PROPERTIES 0#define DO_CONSISTENCY_CHECK 0#define DUMP_STATISTICS 0#define USE_SINGLE_ENTRY 1// At the time I added USE_SINGLE_ENTRY, the optimization still gave a 1.5%// performance boost to the iBench JavaScript benchmark so I didn't remove it.// FIXME: _singleEntry.index is unused.#if !DO_CONSISTENCY_CHECK#define checkConsistency() ((void)0)#endifnamespace KJS {// Choose a number for the following so that most property maps are smaller,// but it's not going to blow out the stack to allocate this number of pointers.const int smallMapThreshold = 1024;#if DUMP_STATISTICSstatic int numProbes;static int numCollisions;static int numRehashes;static int numRemoves;struct PropertyMapStatisticsExitLogger { ~PropertyMapStatisticsExitLogger(); };static PropertyMapStatisticsExitLogger logger;PropertyMapStatisticsExitLogger::~PropertyMapStatisticsExitLogger(){    printf("\nKJS::PropertyMap statistics\n\n");    printf("%d probes\n", numProbes);    printf("%d collisions (%.1f%%)\n", numCollisions, 100.0 * numCollisions / numProbes);    printf("%d rehashes\n", numRehashes);    printf("%d removes\n", numRemoves);}#endif// lastIndexUsed is an ever-increasing index used to identify the order items// were inserted into the property map. It's vital that addEnumerablesToReferenceList// return the properties in the order they were added for compatibility with other// browsers' JavaScript implementations.struct PropertyMapHashTable{    int sizeMask;    int size;    int keyCount;    int lastIndexUsed;    PropertyMapHashTableEntry entries[1];};class SavedProperty {public:    Identifier key;    ProtectedValue value;    int attributes;};SavedProperties::SavedProperties() : _count(0), _properties(0) { }SavedProperties::~SavedProperties(){    delete [] _properties;}// Algorithm concepts from Algorithms in C++, Sedgewick.PropertyMap::PropertyMap() : _table(0){}PropertyMap::~PropertyMap(){    if (!_table) {#if USE_SINGLE_ENTRY        UString::Rep *key = _singleEntry.key;        if (key)            key->deref();#endif        return;    }        for (int i = 0; i < _table->size; i++) {        UString::Rep *key = _table->entries[i].key;        if (key)            key->deref();    }    free(_table);}void PropertyMap::clear(){    if (!_table) {#if USE_SINGLE_ENTRY        UString::Rep *key = _singleEntry.key;        if (key) {            key->deref();            _singleEntry.key = 0;        }#endif        return;    }    for (int i = 0; i < _table->size; i++) {        UString::Rep *key = _table->entries[i].key;        if (key) {            key->deref();            _table->entries[i].key = 0;        }    }    _table->keyCount = 0;}ValueImp *PropertyMap::get(const Identifier &name, int &attributes) const{    assert(!name.isNull());        UString::Rep *rep = name._ustring.rep;        if (!_table) {#if USE_SINGLE_ENTRY        UString::Rep *key = _singleEntry.key;        if (rep == key) {            attributes = _singleEntry.attributes;            return _singleEntry.value;        }#endif        return 0;    }        unsigned h = rep->hash();    int i = h & _table->sizeMask;    int k = 0;#if DUMP_STATISTICS    ++numProbes;    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;#endif    while (UString::Rep *key = _table->entries[i].key) {        if (rep == key) {            attributes = _table->entries[i].attributes;            return _table->entries[i].value;        }        if (k == 0)            k = 1 | (h % _table->sizeMask);        i = (i + k) & _table->sizeMask;#if DUMP_STATISTICS        ++numRehashes;#endif    }    return 0;}ValueImp *PropertyMap::get(const Identifier &name) const{    assert(!name.isNull());        UString::Rep *rep = name._ustring.rep;    if (!_table) {#if USE_SINGLE_ENTRY        UString::Rep *key = _singleEntry.key;        if (rep == key)            return _singleEntry.value;#endif        return 0;    }        unsigned h = rep->hash();    int i = h & _table->sizeMask;    int k = 0;#if DUMP_STATISTICS    ++numProbes;    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;#endif    while (UString::Rep *key = _table->entries[i].key) {        if (rep == key)            return _table->entries[i].value;        if (k == 0)            k = 1 | (h % _table->sizeMask);        i = (i + k) & _table->sizeMask;#if DUMP_STATISTICS        ++numRehashes;#endif    }    return 0;}#if DEBUG_PROPERTIESstatic void printAttributes(int attributes){    if (attributes == 0)        printf("None");    else {        if (attributes & ReadOnly)            printf("ReadOnly ");        if (attributes & DontEnum)            printf("DontEnum ");        if (attributes & DontDelete)            printf("DontDelete ");        if (attributes & Internal)            printf("Internal ");        if (attributes & Function)            printf("Function ");    }}#endifvoid PropertyMap::put(const Identifier &name, ValueImp *value, int attributes){    assert(!name.isNull());    assert(value != 0);        checkConsistency();    UString::Rep *rep = name._ustring.rep;    #if DEBUG_PROPERTIES    printf("adding property %s, attributes = 0x%08x (", name.ascii(), attributes);    printAttributes(attributes);    printf(")\n");#endif    #if USE_SINGLE_ENTRY    if (!_table) {        UString::Rep *key = _singleEntry.key;        if (key) {            if (rep == key) {                _singleEntry.value = value;                return;            }        } else {            rep->ref();            _singleEntry.key = rep;            _singleEntry.value = value;            _singleEntry.attributes = attributes;            checkConsistency();            return;        }    }#endif    if (!_table || _table->keyCount * 2 >= _table->size)        expand();        unsigned h = rep->hash();    int i = h & _table->sizeMask;    int k = 0;#if DUMP_STATISTICS    ++numProbes;    numCollisions += _table->entries[i].key && _table->entries[i].key != rep;#endif    while (UString::Rep *key = _table->entries[i].key) {        if (rep == key) {            // Put a new value in an existing hash table entry.            _table->entries[i].value = value;            // Attributes are intentionally not updated.            return;        }        // If we find the deleted-element sentinel, insert on top of it.        if (key == &UString::Rep::null) {            key->deref();            break;        }        if (k == 0)            k = 1 | (h % _table->sizeMask);        i = (i + k) & _table->sizeMask;#if DUMP_STATISTICS        ++numRehashes;#endif    }        // Create a new hash table entry.    rep->ref();    _table->entries[i].key = rep;    _table->entries[i].value = value;    _table->entries[i].attributes = attributes;    _table->entries[i].index = ++_table->lastIndexUsed;    ++_table->keyCount;    checkConsistency();}void PropertyMap::insert(UString::Rep *key, ValueImp *value, int attributes, int index){    assert(_table);    unsigned h = key->hash();    int i = h & _table->sizeMask;    int k = 0;#if DUMP_STATISTICS    ++numProbes;    numCollisions += _table->entries[i].key && _table->entries[i].key != key;#endif    while (_table->entries[i].key) {        assert(_table->entries[i].key != &UString::Rep::null);        if (k == 0)            k = 1 | (h % _table->sizeMask);        i = (i + k) & _table->sizeMask;#if DUMP_STATISTICS        ++numRehashes;#endif    }        _table->entries[i].key = key;

⌨️ 快捷键说明

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