consolidate many implicit list types into one

This commit is contained in:
Joshua Warner 2013-12-10 21:36:55 -07:00 committed by Joshua Warner
parent 2cb606babd
commit 06432253ba
11 changed files with 169 additions and 178 deletions

35
include/avian/util/list.h Normal file
View File

@ -0,0 +1,35 @@
/* Copyright (c) 2008-2013, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_UTIL_LIST_H
#define AVIAN_UTIL_LIST_H
template <class T>
class List {
public:
List(const T& item, List<T>* next):
item(item),
next(next) {}
unsigned count() {
unsigned count = 0;
List<T>* c = this;
while (c) {
++ count;
c = c->next;
}
return count;
}
T item;
List<T>* next;
};
#endif // AVIAN_UTIL_LIST_H

View File

@ -1634,8 +1634,8 @@ captureBranchSnapshots(Context* c, Event* e)
e->snapshots = makeSnapshots(c, el.value, e->snapshots); e->snapshots = makeSnapshots(c, el.value, e->snapshots);
} }
for (Cell<Value>* sv = e->successors->forkState->saved; sv; sv = sv->next) { for (List<Value*>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
e->snapshots = makeSnapshots(c, sv->value, e->snapshots); e->snapshots = makeSnapshots(c, sv->item, e->snapshots);
} }
if (DebugControl) { if (DebugControl) {
@ -1925,8 +1925,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
} }
if (e->visitLinks) { if (e->visitLinks) {
for (Cell<Link>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) { for (List<Link*>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
visit(c, cell->value); visit(c, cell->item);
} }
e->visitLinks = 0; e->visitLinks = 0;
} }
@ -1997,7 +1997,7 @@ saveState(Context* c)
appendDummy(c); appendDummy(c);
} }
unsigned elementCount = frameFootprint(c, c->stack) + count(c->saved); unsigned elementCount = frameFootprint(c, c->stack) + c->saved->count();
ForkState* state = new ForkState* state = new
(c->zone->allocate (c->zone->allocate
@ -2014,8 +2014,8 @@ saveState(Context* c)
addForkElement(c, e.value, state, count++); addForkElement(c, e.value, state, count++);
} }
for (Cell<Value>* sv = c->saved; sv; sv = sv->next) { for (List<Value*>* sv = c->saved; sv; sv = sv->next) {
addForkElement(c, sv->value, state, count++); addForkElement(c, sv->item, state, count++);
} }
state->readCount = count; state->readCount = count;

View File

@ -13,6 +13,7 @@
#include <avian/vm/codegen/assembler.h> #include <avian/vm/codegen/assembler.h>
#include <avian/vm/codegen/compiler.h> #include <avian/vm/codegen/compiler.h>
#include <avian/util/list.h>
#include "regalloc.h" #include "regalloc.h"
@ -38,29 +39,10 @@ class MySubroutine;
class Block; class Block;
template<class T> template<class T>
class Cell { List<T>* reverseDestroy(List<T>* cell) {
public: List<T>* previous = 0;
Cell(Cell<T>* next, T* value): next(next), value(value) { }
Cell<T>* next;
T* value;
};
template<class T>
unsigned count(Cell<T>* c) {
unsigned count = 0;
while (c) {
++ count;
c = c->next;
}
return count;
}
template<class T>
Cell<T>* reverseDestroy(Cell<T>* cell) {
Cell<T>* previous = 0;
while (cell) { while (cell) {
Cell<T>* next = cell->next; List<T>* next = cell->next;
cell->next = previous; cell->next = previous;
previous = cell; previous = cell;
cell = next; cell = next;
@ -80,7 +62,7 @@ class Context {
Compiler::Client* client; Compiler::Client* client;
Stack* stack; Stack* stack;
Local* locals; Local* locals;
Cell<Value>* saved; List<Value*>* saved;
Event* predecessor; Event* predecessor;
LogicalInstruction** logicalCode; LogicalInstruction** logicalCode;
const RegisterFile* regFile; const RegisterFile* regFile;
@ -111,8 +93,8 @@ inline Aborter* getAborter(Context* c) {
} }
template<class T> template<class T>
Cell<T>* cons(Context* c, T* value, Cell<T>* next) { List<T>* cons(Context* c, const T& value, List<T>* next) {
return new (c->zone) Cell<T>(next, value); return new (c->zone) List<T>(value, next);
} }
} // namespace compiler } // namespace compiler

View File

@ -68,7 +68,7 @@ class Event {
Snapshot* snapshots; Snapshot* snapshots;
Link* predecessors; Link* predecessors;
Link* successors; Link* successors;
Cell<Link>* visitLinks; List<Link*>* visitLinks;
Block* block; Block* block;
LogicalInstruction* logicalInstruction; LogicalInstruction* logicalInstruction;
unsigned readCount; unsigned readCount;

View File

@ -26,7 +26,7 @@ class ForkElement {
class ForkState: public Compiler::State { class ForkState: public Compiler::State {
public: public:
ForkState(Stack* stack, Local* locals, Cell<Value>* saved, Event* predecessor, ForkState(Stack* stack, Local* locals, List<Value*>* saved, Event* predecessor,
unsigned logicalIp): unsigned logicalIp):
stack(stack), stack(stack),
locals(locals), locals(locals),
@ -38,7 +38,7 @@ class ForkState: public Compiler::State {
Stack* stack; Stack* stack;
Local* locals; Local* locals;
Cell<Value>* saved; List<Value*>* saved;
Event* predecessor; Event* predecessor;
unsigned logicalIp; unsigned logicalIp;
unsigned readCount; unsigned readCount;

View File

@ -66,8 +66,8 @@ bool MultiRead::intersect(SiteMask* mask, unsigned depth) {
bool result = false; bool result = false;
if (not visited) { if (not visited) {
visited = true; visited = true;
for (Cell<Read>** cell = &reads; *cell;) { for (List<Read*>** cell = &reads; *cell;) {
Read* r = (*cell)->value; Read* r = (*cell)->item;
bool valid = r->intersect(mask, depth + 1); bool valid = r->intersect(mask, depth + 1);
if (valid) { if (valid) {
result = true; result = true;
@ -89,8 +89,8 @@ bool MultiRead::valid() {
bool result = false; bool result = false;
if (not visited) { if (not visited) {
visited = true; visited = true;
for (Cell<Read>** cell = &reads; *cell;) { for (List<Read*>** cell = &reads; *cell;) {
Read* r = (*cell)->value; Read* r = (*cell)->item;
if (r->valid()) { if (r->valid()) {
result = true; result = true;
cell = &((*cell)->next); cell = &((*cell)->next);
@ -104,7 +104,7 @@ bool MultiRead::valid() {
} }
void MultiRead::append(Context* c, Read* r) { void MultiRead::append(Context* c, Read* r) {
Cell<Read>* cell = cons<Read>(c, r, 0); List<Read*>* cell = cons<Read*>(c, r, 0);
if (lastRead == 0) { if (lastRead == 0) {
reads = cell; reads = cell;
} else { } else {
@ -114,7 +114,7 @@ void MultiRead::append(Context* c, Read* r) {
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this); // fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
lastTarget->value = r; lastTarget->item = r;
} }
Read* MultiRead::next(Context* c) { Read* MultiRead::next(Context* c) {
@ -122,7 +122,7 @@ Read* MultiRead::next(Context* c) {
} }
void MultiRead::allocateTarget(Context* c) { void MultiRead::allocateTarget(Context* c) {
Cell<Read>* cell = cons<Read>(c, 0, 0); List<Read*>* cell = cons<Read*>(c, 0, 0);
// fprintf(stderr, "allocate target for %p: %p\n", this, cell); // fprintf(stderr, "allocate target for %p: %p\n", this, cell);
@ -137,7 +137,7 @@ void MultiRead::allocateTarget(Context* c) {
Read* MultiRead::nextTarget() { Read* MultiRead::nextTarget() {
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget); // fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
Read* r = firstTarget->value; Read* r = firstTarget->item;
firstTarget = firstTarget->next; firstTarget = firstTarget->next;
return r; return r;
} }

View File

@ -88,10 +88,10 @@ class MultiRead: public Read {
Read* nextTarget(); Read* nextTarget();
Cell<Read>* reads; List<Read*>* reads;
Cell<Read>* lastRead; List<Read*>* lastRead;
Cell<Read>* firstTarget; List<Read*>* firstTarget;
Cell<Read>* lastTarget; List<Read*>* lastTarget;
bool visited; bool visited;
}; };

View File

@ -21,6 +21,7 @@
#include <avian/vm/codegen/targets.h> #include <avian/vm/codegen/targets.h>
#include <avian/util/runtime-array.h> #include <avian/util/runtime-array.h>
#include <avian/util/list.h>
using namespace vm; using namespace vm;
@ -211,17 +212,6 @@ class MyThread: public Thread {
bool methodIsMostRecent; bool methodIsMostRecent;
}; };
class ReferenceFrame {
public:
ReferenceFrame(ReferenceFrame* next, Reference* reference):
next(next),
reference(reference)
{ }
ReferenceFrame* next;
Reference* reference;
};
static void doTransition(MyThread* t, void* ip, void* stack, static void doTransition(MyThread* t, void* ip, void* stack,
object continuation, MyThread::CallTrace* trace) object continuation, MyThread::CallTrace* trace)
{ {
@ -301,7 +291,7 @@ class MyThread: public Thread {
Context* transition; Context* transition;
TraceContext* traceContext; TraceContext* traceContext;
uintptr_t stackLimit; uintptr_t stackLimit;
ReferenceFrame* referenceFrame; List<Reference*>* referenceFrame;
bool methodLockIsClean; bool methodLockIsClean;
}; };
@ -9061,8 +9051,8 @@ class MyProcessor: public Processor {
MyThread* t = static_cast<MyThread*>(vmt); MyThread* t = static_cast<MyThread*>(vmt);
t->referenceFrame = new t->referenceFrame = new
(t->m->heap->allocate(sizeof(MyThread::ReferenceFrame))) (t->m->heap->allocate(sizeof(List<Reference*>)))
MyThread::ReferenceFrame(t->referenceFrame, t->reference); List<Reference*>(t->reference, t->referenceFrame);
return true; return true;
} }
@ -9072,13 +9062,13 @@ class MyProcessor: public Processor {
{ {
MyThread* t = static_cast<MyThread*>(vmt); MyThread* t = static_cast<MyThread*>(vmt);
MyThread::ReferenceFrame* f = t->referenceFrame; List<Reference*>* f = t->referenceFrame;
t->referenceFrame = f->next; t->referenceFrame = f->next;
while (t->reference != f->reference) { while (t->reference != f->item) {
vm::dispose(t, t->reference); vm::dispose(t, t->reference);
} }
t->m->heap->free(f, sizeof(MyThread::ReferenceFrame)); t->m->heap->free(f, sizeof(List<Reference*>));
} }
virtual object virtual object

View File

@ -11,6 +11,7 @@
#include <avian/vm/system/system.h> #include <avian/vm/system/system.h>
#include <avian/util/string.h> #include <avian/util/string.h>
#include <avian/util/runtime-array.h> #include <avian/util/runtime-array.h>
#include <avian/util/list.h>
#include "avian/zlib-custom.h" #include "avian/zlib-custom.h"
#include "avian/finder.h" #include "avian/finder.h"
@ -241,15 +242,14 @@ class JarIndex {
Deflated = 8 Deflated = 8
}; };
class Node { class Entry {
public: public:
Node(uint32_t hash, const uint8_t* entry, Node* next): Entry(uint32_t hash, const uint8_t* entry):
hash(hash), entry(entry), next(next) hash(hash),
{ } entry(entry) {}
uint32_t hash; uint32_t hash;
const uint8_t* entry; const uint8_t* entry;
Node* next;
}; };
JarIndex(System* s, Allocator* allocator, unsigned capacity): JarIndex(System* s, Allocator* allocator, unsigned capacity):
@ -257,14 +257,14 @@ class JarIndex {
allocator(allocator), allocator(allocator),
capacity(capacity), capacity(capacity),
position(0), position(0),
nodes(static_cast<Node*>(allocator->allocate(sizeof(Node) * capacity))) nodes(static_cast<List<Entry>*>(allocator->allocate(sizeof(List<Entry>) * capacity)))
{ {
memset(table, 0, sizeof(Node*) * capacity); memset(table, 0, sizeof(List<Entry>*) * capacity);
} }
static JarIndex* make(System* s, Allocator* allocator, unsigned capacity) { static JarIndex* make(System* s, Allocator* allocator, unsigned capacity) {
return new return new
(allocator->allocate(sizeof(JarIndex) + (sizeof(Node*) * capacity))) (allocator->allocate(sizeof(JarIndex) + (sizeof(List<Entry>*) * capacity)))
JarIndex(s, allocator, capacity); JarIndex(s, allocator, capacity);
} }
@ -283,7 +283,7 @@ class JarIndex {
while (p < end) { while (p < end) {
if (signature(p) == EntrySignature) { if (signature(p) == EntrySignature) {
index = index->add(hash(fileName(p), fileNameLength(p)), p); index = index->add(Entry(hash(fileName(p), fileNameLength(p)), p));
p = endOfEntry(p); p = endOfEntry(p);
} else { } else {
@ -298,27 +298,27 @@ class JarIndex {
return index; return index;
} }
JarIndex* add(uint32_t hash, const uint8_t* entry) { JarIndex* add(const Entry& entry) {
if (position < capacity) { if (position < capacity) {
unsigned i = hash & (capacity - 1); unsigned i = entry.hash & (capacity - 1);
table[i] = new (nodes + (position++)) Node(hash, entry, table[i]); table[i] = new (nodes + (position++)) List<Entry>(entry, table[i]);
return this; return this;
} else { } else {
JarIndex* index = make(s, allocator, capacity * 2); JarIndex* index = make(s, allocator, capacity * 2);
for (unsigned i = 0; i < capacity; ++i) { for (unsigned i = 0; i < capacity; ++i) {
index->add(nodes[i].hash, nodes[i].entry); index->add(nodes[i].item);
} }
index->add(hash, entry); index->add(entry);
dispose(); dispose();
return index; return index;
} }
} }
Node* findNode(const char* name) { List<Entry>* findNode(const char* name) {
unsigned length = strlen(name); unsigned length = strlen(name);
unsigned i = hash(name) & (capacity - 1); unsigned i = hash(name) & (capacity - 1);
for (Node* n = table[i]; n; n = n->next) { for (List<Entry>* n = table[i]; n; n = n->next) {
const uint8_t* p = n->entry; const uint8_t* p = n->item.entry;
if (equal(name, length, fileName(p), fileNameLength(p))) { if (equal(name, length, fileName(p), fileNameLength(p))) {
return n; return n;
} }
@ -327,9 +327,9 @@ class JarIndex {
} }
System::Region* find(const char* name, const uint8_t* start) { System::Region* find(const char* name, const uint8_t* start) {
Node* n = findNode(name); List<Entry>* n = findNode(name);
if (n) { if (n) {
const uint8_t* p = n->entry; const uint8_t* p = n->item.entry;
switch (compressionMethod(p)) { switch (compressionMethod(p)) {
case Stored: { case Stored: {
return new (allocator->allocate(sizeof(PointerRegion))) return new (allocator->allocate(sizeof(PointerRegion)))
@ -372,9 +372,9 @@ class JarIndex {
System::FileType stat(const char* name, unsigned* length, bool tryDirectory) System::FileType stat(const char* name, unsigned* length, bool tryDirectory)
{ {
Node* node = findNode(name); List<Entry>* node = findNode(name);
if (node) { if (node) {
*length = uncompressedSize(node->entry); *length = uncompressedSize(node->item.entry);
return System::TypeFile; return System::TypeFile;
} else if (tryDirectory) { } else if (tryDirectory) {
*length = 0; *length = 0;
@ -399,8 +399,8 @@ class JarIndex {
} }
void dispose() { void dispose() {
allocator->free(nodes, sizeof(Node) * capacity); allocator->free(nodes, sizeof(List<Entry>) * capacity);
allocator->free(this, sizeof(*this) + (sizeof(Node*) * capacity)); allocator->free(this, sizeof(*this) + (sizeof(List<Entry>*) * capacity));
} }
System* s; System* s;
@ -408,8 +408,8 @@ class JarIndex {
unsigned capacity; unsigned capacity;
unsigned position; unsigned position;
Node* nodes; List<Entry>* nodes;
Node* table[0]; List<Entry>* table[0];
}; };
class JarElement: public Element { class JarElement: public Element {
@ -422,9 +422,9 @@ class JarElement: public Element {
virtual const char* next(unsigned* size) { virtual const char* next(unsigned* size) {
if (position < index->position) { if (position < index->position) {
JarIndex::Node* n = index->nodes + (position++); List<JarIndex::Entry>* n = index->nodes + (position++);
*size = fileNameLength(n->entry); *size = fileNameLength(n->item.entry);
return reinterpret_cast<const char*>(fileName(n->entry)); return reinterpret_cast<const char*>(fileName(n->item.entry));
} else { } else {
return 0; return 0;
} }

View File

@ -17,6 +17,7 @@
#include "avian/arch.h" #include "avian/arch.h"
#include <avian/util/runtime-array.h> #include <avian/util/runtime-array.h>
#include <avian/util/list.h>
using namespace vm; using namespace vm;
@ -30,16 +31,6 @@ const unsigned FrameFootprint = 4;
class Thread: public vm::Thread { class Thread: public vm::Thread {
public: public:
class ReferenceFrame {
public:
ReferenceFrame(ReferenceFrame* next, unsigned sp):
next(next),
sp(sp)
{ }
ReferenceFrame* next;
unsigned sp;
};
Thread(Machine* m, object javaThread, vm::Thread* parent): Thread(Machine* m, object javaThread, vm::Thread* parent):
vm::Thread(m, javaThread, parent), vm::Thread(m, javaThread, parent),
@ -47,14 +38,14 @@ class Thread: public vm::Thread {
sp(0), sp(0),
frame(-1), frame(-1),
code(0), code(0),
referenceFrame(0) stackPointers(0)
{ } { }
unsigned ip; unsigned ip;
unsigned sp; unsigned sp;
int frame; int frame;
object code; object code;
ReferenceFrame* referenceFrame; List<unsigned>* stackPointers;
uintptr_t stack[0]; uintptr_t stack[0];
}; };
@ -3079,9 +3070,8 @@ class MyProcessor: public Processor {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
if (t->sp + capacity < stackSizeInWords(t) / 2) { if (t->sp + capacity < stackSizeInWords(t) / 2) {
t->referenceFrame = new t->stackPointers = new(t->m->heap)
(t->m->heap->allocate(sizeof(Thread::ReferenceFrame))) List<unsigned>(t->sp, t->stackPointers);
Thread::ReferenceFrame(t->referenceFrame, t->sp);
return true; return true;
} else { } else {
@ -3094,11 +3084,11 @@ class MyProcessor: public Processor {
{ {
Thread* t = static_cast<Thread*>(vmt); Thread* t = static_cast<Thread*>(vmt);
Thread::ReferenceFrame* f = t->referenceFrame; List<unsigned>* f = t->stackPointers;
t->referenceFrame = f->next; t->stackPointers = f->next;
t->sp = f->sp; t->sp = f->item;
t->m->heap->free(f, sizeof(Thread::ReferenceFrame)); t->m->heap->free(f, sizeof(List<unsigned>));
} }
virtual object virtual object

View File

@ -9,6 +9,7 @@
details. */ details. */
#include "avian/util.h" #include "avian/util.h"
#include <avian/util/list.h>
using namespace vm; using namespace vm;
@ -16,13 +17,6 @@ namespace {
class TreeContext { class TreeContext {
public: public:
class Path {
public:
Path(object node, Path* next): node(node), next(next) { }
object node;
Path* next;
};
class MyProtector: public Thread::Protector { class MyProtector: public Thread::Protector {
public: public:
@ -34,8 +28,8 @@ class TreeContext {
v->visit(&(context->root)); v->visit(&(context->root));
v->visit(&(context->node)); v->visit(&(context->node));
for (Path* p = context->ancestors; p; p = p->next) { for (List<object>* p = context->ancestors; p; p = p->next) {
v->visit(&(p->node)); v->visit(&(p->item));
} }
} }
@ -50,15 +44,15 @@ class TreeContext {
Zone* zone; Zone* zone;
object root; object root;
object node; object node;
Path* ancestors; List<object>* ancestors;
MyProtector protector; MyProtector protector;
bool fresh; bool fresh;
}; };
TreeContext::Path* List<object>*
path(TreeContext* c, object node, TreeContext::Path* next) path(TreeContext* c, object node, List<object>* next)
{ {
return new(c->zone) TreeContext::Path(node, next); return new(c->zone) List<object>(node, next);
} }
inline object inline object
@ -212,99 +206,99 @@ treeAdd(Thread* t, TreeContext* c)
// rebalance // rebalance
setTreeNodeRed(t, new_, true); setTreeNodeRed(t, new_, true);
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->node)) { while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
if (c->ancestors->node if (c->ancestors->item
== treeNodeLeft(t, c->ancestors->next->node)) == treeNodeLeft(t, c->ancestors->next->item))
{ {
if (treeNodeRed if (treeNodeRed
(t, treeNodeRight(t, c->ancestors->next->node))) (t, treeNodeRight(t, c->ancestors->next->item)))
{ {
setTreeNodeRed(t, c->ancestors->node, false); setTreeNodeRed(t, c->ancestors->item, false);
object n = cloneTreeNode object n = cloneTreeNode
(t, treeNodeRight(t, c->ancestors->next->node)); (t, treeNodeRight(t, c->ancestors->next->item));
set(t, c->ancestors->next->node, TreeNodeRight, n); set(t, c->ancestors->next->item, TreeNodeRight, n);
setTreeNodeRed(t, treeNodeRight(t, c->ancestors->next->node), false); setTreeNodeRed(t, treeNodeRight(t, c->ancestors->next->item), false);
setTreeNodeRed(t, c->ancestors->next->node, true); setTreeNodeRed(t, c->ancestors->next->item, true);
new_ = c->ancestors->next->node; new_ = c->ancestors->next->item;
c->ancestors = c->ancestors->next->next; c->ancestors = c->ancestors->next->next;
} else { } else {
if (new_ == treeNodeRight(t, c->ancestors->node)) { if (new_ == treeNodeRight(t, c->ancestors->item)) {
new_ = c->ancestors->node; new_ = c->ancestors->item;
c->ancestors = c->ancestors->next; c->ancestors = c->ancestors->next;
object n = leftRotate(t, new_); object n = leftRotate(t, new_);
if (new_ == treeNodeRight(t, c->ancestors->node)) { if (new_ == treeNodeRight(t, c->ancestors->item)) {
set(t, c->ancestors->node, TreeNodeRight, n); set(t, c->ancestors->item, TreeNodeRight, n);
} else { } else {
set(t, c->ancestors->node, TreeNodeLeft, n); set(t, c->ancestors->item, TreeNodeLeft, n);
} }
c->ancestors = path(c, n, c->ancestors); c->ancestors = path(c, n, c->ancestors);
} }
setTreeNodeRed(t, c->ancestors->node, false); setTreeNodeRed(t, c->ancestors->item, false);
setTreeNodeRed(t, c->ancestors->next->node, true); setTreeNodeRed(t, c->ancestors->next->item, true);
object n = rightRotate(t, c->ancestors->next->node); object n = rightRotate(t, c->ancestors->next->item);
if (c->ancestors->next->next == 0) { if (c->ancestors->next->next == 0) {
newRoot = n; newRoot = n;
} else if (treeNodeRight(t, c->ancestors->next->next->node) } else if (treeNodeRight(t, c->ancestors->next->next->item)
== c->ancestors->next->node) == c->ancestors->next->item)
{ {
set(t, c->ancestors->next->next->node, TreeNodeRight, n); set(t, c->ancestors->next->next->item, TreeNodeRight, n);
} else { } else {
set(t, c->ancestors->next->next->node, TreeNodeLeft, n); set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
} }
// done // done
} }
} else { // this is just the reverse of the code above (right and } else { // this is just the reverse of the code above (right and
// left swapped): // left swapped):
if (treeNodeRed if (treeNodeRed
(t, treeNodeLeft(t, c->ancestors->next->node))) (t, treeNodeLeft(t, c->ancestors->next->item)))
{ {
setTreeNodeRed(t, c->ancestors->node, false); setTreeNodeRed(t, c->ancestors->item, false);
object n = cloneTreeNode object n = cloneTreeNode
(t, treeNodeLeft(t, c->ancestors->next->node)); (t, treeNodeLeft(t, c->ancestors->next->item));
set(t, c->ancestors->next->node, TreeNodeLeft, n); set(t, c->ancestors->next->item, TreeNodeLeft, n);
setTreeNodeRed(t, treeNodeLeft(t, c->ancestors->next->node), false); setTreeNodeRed(t, treeNodeLeft(t, c->ancestors->next->item), false);
setTreeNodeRed(t, c->ancestors->next->node, true); setTreeNodeRed(t, c->ancestors->next->item, true);
new_ = c->ancestors->next->node; new_ = c->ancestors->next->item;
c->ancestors = c->ancestors->next->next; c->ancestors = c->ancestors->next->next;
} else { } else {
if (new_ == treeNodeLeft(t, c->ancestors->node)) { if (new_ == treeNodeLeft(t, c->ancestors->item)) {
new_ = c->ancestors->node; new_ = c->ancestors->item;
c->ancestors = c->ancestors->next; c->ancestors = c->ancestors->next;
object n = rightRotate(t, new_); object n = rightRotate(t, new_);
if (new_ == treeNodeLeft(t, c->ancestors->node)) { if (new_ == treeNodeLeft(t, c->ancestors->item)) {
set(t, c->ancestors->node, TreeNodeLeft, n); set(t, c->ancestors->item, TreeNodeLeft, n);
} else { } else {
set(t, c->ancestors->node, TreeNodeRight, n); set(t, c->ancestors->item, TreeNodeRight, n);
} }
c->ancestors = path(c, n, c->ancestors); c->ancestors = path(c, n, c->ancestors);
} }
setTreeNodeRed(t, c->ancestors->node, false); setTreeNodeRed(t, c->ancestors->item, false);
setTreeNodeRed(t, c->ancestors->next->node, true); setTreeNodeRed(t, c->ancestors->next->item, true);
object n = leftRotate(t, c->ancestors->next->node); object n = leftRotate(t, c->ancestors->next->item);
if (c->ancestors->next->next == 0) { if (c->ancestors->next->next == 0) {
newRoot = n; newRoot = n;
} else if (treeNodeLeft(t, c->ancestors->next->next->node) } else if (treeNodeLeft(t, c->ancestors->next->next->item)
== c->ancestors->next->node) == c->ancestors->next->item)
{ {
set(t, c->ancestors->next->next->node, TreeNodeLeft, n); set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
} else { } else {
set(t, c->ancestors->next->next->node, TreeNodeRight, n); set(t, c->ancestors->next->next->item, TreeNodeRight, n);
} }
// done // done
} }