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

📄 kwqmapimpl.cpp

📁 khtml在gtk上的移植版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2003 Apple Computer, Inc.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  */#include "KWQMapImpl.h"#include "KWQDef.h"KWQMapNodeImpl::KWQMapNodeImpl() :    prev(NULL),    next(NULL),    prevIsChild(true),    nextIsChild(true),    color(Red){}KWQMapNodeImpl *KWQMapNodeImpl::left(){    return prevIsChild ? prev : NULL;}const KWQMapNodeImpl *KWQMapNodeImpl::left() const{    return prevIsChild ? prev : NULL;}KWQMapNodeImpl *KWQMapNodeImpl::right(){    return nextIsChild ? next : NULL;}const KWQMapNodeImpl *KWQMapNodeImpl::right() const{    return nextIsChild ? next : NULL;}KWQMapNodeImpl *KWQMapNodeImpl::predecessor(){    if (!prevIsChild || prev == NULL) {	return prev;    }    KWQMapNodeImpl *pred = left();    while (pred->right() != NULL) {	pred = pred->right();    }    return pred;}const KWQMapNodeImpl *KWQMapNodeImpl::predecessor() const{    if (!prevIsChild || prev == NULL) {	return prev;    }    const KWQMapNodeImpl *pred = left();    while (pred->right() != NULL) {	pred = pred->right();    }    return pred;}KWQMapNodeImpl *KWQMapNodeImpl::successor(){    if (!nextIsChild || next == NULL) {	return next;    }    KWQMapNodeImpl *succ = right();    while (succ->left() != NULL) {	succ = succ->left();    }    return succ;}const KWQMapNodeImpl *KWQMapNodeImpl::successor() const{    if (!nextIsChild || next == NULL) {	return next;    }    const KWQMapNodeImpl *succ = right();    while (succ->left() != NULL) {	succ = succ->left();    }    return succ;}KWQMapIteratorImpl::KWQMapIteratorImpl() : node(NULL){}void KWQMapIteratorImpl::incrementInternal(){    node = node->successor();}// KWQMapImplPrivateclass KWQMapImpl::KWQMapPrivate{public:    KWQMapPrivate(KWQMapNodeImpl *node,		  uint count,		  void (*deleteFunc)(KWQMapNodeImpl *));    ~KWQMapPrivate();    KWQMapNodeImpl *guard;    uint numNodes;    int refCount;    void (*deleteNode)(KWQMapNodeImpl *);    friend class KWQRefPtr<KWQMapImpl::KWQMapPrivate>;};KWQMapImpl::KWQMapPrivate::KWQMapPrivate(KWQMapNodeImpl *node,					 uint count,					 void (*deleteFunc)(KWQMapNodeImpl *)) :    guard(node),    numNodes(count),    refCount(0),    deleteNode(deleteFunc){}KWQMapImpl::KWQMapPrivate::~KWQMapPrivate(){    deleteNode(guard);}// KWQMapImplKWQMapImpl::KWQMapImpl(KWQMapNodeImpl *guard, void (*deleteNode)(KWQMapNodeImpl *)) :    d(new KWQMapPrivate(guard, 0, deleteNode)){}KWQMapImpl::KWQMapImpl(const KWQMapImpl &impl) :    d(impl.d){}KWQMapImpl::~KWQMapImpl(){}void KWQMapImpl::copyOnWrite(){    if (d->refCount > 1) {	d = KWQRefPtr<KWQMapPrivate>(new KWQMapPrivate(copyTree(d->guard, NULL, NULL), d->numNodes, d->deleteNode));    }}KWQMapNodeImpl *KWQMapImpl::copyTree(const KWQMapNodeImpl *node, 				     KWQMapNodeImpl *subtreePredecessor, 				     KWQMapNodeImpl *subtreeSuccessor) const{    if (node == NULL) {	return NULL;    }        // FIXME: not exception-safe - use auto_ptr?    KWQMapNodeImpl *copy = duplicateNode(node);    copy->color = node->color;        if (node->prevIsChild) {	copy->prevIsChild = true;	copy->prev = copyTree(node->prev, subtreePredecessor, copy);    } else {	copy->prevIsChild = false;	copy->prev = subtreePredecessor;    }        if (node->nextIsChild) {	copy->nextIsChild = true;	copy->next = copyTree(node->next, copy, subtreeSuccessor);    } else {	copy->nextIsChild = false;	copy->next = subtreeSuccessor;    }        return copy;}void KWQMapImpl::rotateRight(KWQMapNodeImpl *node, KWQMapNodeImpl *parent, bool leftParent){    KWQMapNodeImpl *rotationChild = node->left();	if (leftParent) {	    parent->prev = rotationChild;	} else {	    parent->next = rotationChild;	}		node->prev = rotationChild->next;	node->prevIsChild = rotationChild->nextIsChild;		rotationChild->next = node;	rotationChild->nextIsChild = true;	// fixup threads	if (!node->prevIsChild) {	    node->prev = rotationChild;	}    }    void KWQMapImpl::rotateLeft(KWQMapNodeImpl *node, KWQMapNodeImpl *parent, bool leftParent){    KWQMapNodeImpl *rotationChild = node->right();        if (leftParent) {	parent->prev = rotationChild;    } else {	parent->next = rotationChild;    }        node->next = rotationChild->prev;    node->nextIsChild = rotationChild->prevIsChild;        rotationChild->prev = node;    rotationChild->prevIsChild = true;        // fixup threads    if (!node->nextIsChild) {	node->next = rotationChild;    }}void KWQMapImpl::rebalanceAfterInsert(KWQMapNodeImpl **nodes, bool *wentLeft, int height){    nodes[height]->color = KWQMapNodeImpl::Red;        while (nodes[height] != d->guard->prev && nodes[height-1]->color == KWQMapNodeImpl::Red) {	if (wentLeft[height-2]) {	    KWQMapNodeImpl *uncle = nodes[height-2]->right();	    if (uncle != NULL && uncle->color == KWQMapNodeImpl::Red) {		nodes[height-1]->color = KWQMapNodeImpl::Black;		uncle->color = KWQMapNodeImpl::Black;		nodes[height-2]->color = KWQMapNodeImpl::Red;				// go up two levels		height = height - 2;	    } else {		KWQMapNodeImpl *parent;		if (!wentLeft[height-1]) {		    parent = nodes[height-1]->right();		    rotateLeft(nodes[height-1], nodes[height-2], wentLeft[height-2]);		} else {		    parent = nodes[height-1];		}		parent->color = KWQMapNodeImpl::Black;		nodes[height-2]->color = KWQMapNodeImpl::Red;		rotateRight(nodes[height-2], nodes[height-3], wentLeft[height-3]);		break;	    }	} else {	    // same as the other branch, but with left and right swapped	    	    KWQMapNodeImpl *uncle = nodes[height-2]->left();	    	    if (uncle != NULL && uncle->color == KWQMapNodeImpl::Red) {		nodes[height-1]->color = KWQMapNodeImpl::Black;		uncle->color = KWQMapNodeImpl::Black;		nodes[height-2]->color = KWQMapNodeImpl::Red;				// go up two levels		height = height - 2;	    } else {		KWQMapNodeImpl *parent;		if (wentLeft[height-1]) {		    parent = nodes[height-1]->left();		    rotateRight(nodes[height-1], nodes[height-2], wentLeft[height-2]);		} else {		    parent = nodes[height-1];		}		parent->color = KWQMapNodeImpl::Black;		nodes[height-2]->color = KWQMapNodeImpl::Red;		rotateLeft(nodes[height-2], nodes[height-3], wentLeft[height-3]);		break;	    }	}    }        d->guard->prev->color = KWQMapNodeImpl::Black;}void KWQMapImpl::rebalanceAfterRemove(KWQMapNodeImpl *nodeToRemove, KWQMapNodeImpl **nodes, bool *wentLeft, int height) {    if (nodeToRemove->color == KWQMapNodeImpl::Black) {	while (nodes[height] != d->guard->prev && (nodes[height]==NULL || nodes[height]->color==KWQMapNodeImpl::Black)) {	    if (wentLeft[height-1]) {		KWQMapNodeImpl *sibling = nodes[height-1]->right();		if (sibling != NULL && sibling->color == KWQMapNodeImpl::Red) {		    sibling->color = KWQMapNodeImpl::Black;		    nodes[height-1]->color = KWQMapNodeImpl::Red;		    rotateLeft(nodes[height-1], nodes[height-2], wentLeft[height-2]);		    		    nodes[height] = nodes[height-1];		    wentLeft[height] = true;		    nodes[height-1] = sibling;		    height = height + 1;		    		    sibling = nodes[height-1]->right();		}		if ((sibling->left() == NULL || sibling->left()->color == KWQMapNodeImpl::Black) &&

⌨️ 快捷键说明

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