mirror of
https://github.com/corda/corda.git
synced 2025-01-03 19:54:13 +00:00
consolidate many implicit list types into one
This commit is contained in:
parent
2cb606babd
commit
06432253ba
35
include/avian/util/list.h
Normal file
35
include/avian/util/list.h
Normal 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
|
@ -1634,8 +1634,8 @@ captureBranchSnapshots(Context* c, Event* e)
|
||||
e->snapshots = makeSnapshots(c, el.value, e->snapshots);
|
||||
}
|
||||
|
||||
for (Cell<Value>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
|
||||
e->snapshots = makeSnapshots(c, sv->value, e->snapshots);
|
||||
for (List<Value*>* sv = e->successors->forkState->saved; sv; sv = sv->next) {
|
||||
e->snapshots = makeSnapshots(c, sv->item, e->snapshots);
|
||||
}
|
||||
|
||||
if (DebugControl) {
|
||||
@ -1925,8 +1925,8 @@ compile(Context* c, uintptr_t stackOverflowHandler, unsigned stackLimitOffset)
|
||||
}
|
||||
|
||||
if (e->visitLinks) {
|
||||
for (Cell<Link>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
|
||||
visit(c, cell->value);
|
||||
for (List<Link*>* cell = reverseDestroy(e->visitLinks); cell; cell = cell->next) {
|
||||
visit(c, cell->item);
|
||||
}
|
||||
e->visitLinks = 0;
|
||||
}
|
||||
@ -1997,7 +1997,7 @@ saveState(Context* c)
|
||||
appendDummy(c);
|
||||
}
|
||||
|
||||
unsigned elementCount = frameFootprint(c, c->stack) + count(c->saved);
|
||||
unsigned elementCount = frameFootprint(c, c->stack) + c->saved->count();
|
||||
|
||||
ForkState* state = new
|
||||
(c->zone->allocate
|
||||
@ -2014,8 +2014,8 @@ saveState(Context* c)
|
||||
addForkElement(c, e.value, state, count++);
|
||||
}
|
||||
|
||||
for (Cell<Value>* sv = c->saved; sv; sv = sv->next) {
|
||||
addForkElement(c, sv->value, state, count++);
|
||||
for (List<Value*>* sv = c->saved; sv; sv = sv->next) {
|
||||
addForkElement(c, sv->item, state, count++);
|
||||
}
|
||||
|
||||
state->readCount = count;
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <avian/vm/codegen/assembler.h>
|
||||
#include <avian/vm/codegen/compiler.h>
|
||||
#include <avian/util/list.h>
|
||||
|
||||
#include "regalloc.h"
|
||||
|
||||
@ -38,29 +39,10 @@ class MySubroutine;
|
||||
class Block;
|
||||
|
||||
template<class T>
|
||||
class Cell {
|
||||
public:
|
||||
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;
|
||||
List<T>* reverseDestroy(List<T>* cell) {
|
||||
List<T>* previous = 0;
|
||||
while (cell) {
|
||||
Cell<T>* next = cell->next;
|
||||
List<T>* next = cell->next;
|
||||
cell->next = previous;
|
||||
previous = cell;
|
||||
cell = next;
|
||||
@ -80,7 +62,7 @@ class Context {
|
||||
Compiler::Client* client;
|
||||
Stack* stack;
|
||||
Local* locals;
|
||||
Cell<Value>* saved;
|
||||
List<Value*>* saved;
|
||||
Event* predecessor;
|
||||
LogicalInstruction** logicalCode;
|
||||
const RegisterFile* regFile;
|
||||
@ -111,8 +93,8 @@ inline Aborter* getAborter(Context* c) {
|
||||
}
|
||||
|
||||
template<class T>
|
||||
Cell<T>* cons(Context* c, T* value, Cell<T>* next) {
|
||||
return new (c->zone) Cell<T>(next, value);
|
||||
List<T>* cons(Context* c, const T& value, List<T>* next) {
|
||||
return new (c->zone) List<T>(value, next);
|
||||
}
|
||||
|
||||
} // namespace compiler
|
||||
|
@ -68,7 +68,7 @@ class Event {
|
||||
Snapshot* snapshots;
|
||||
Link* predecessors;
|
||||
Link* successors;
|
||||
Cell<Link>* visitLinks;
|
||||
List<Link*>* visitLinks;
|
||||
Block* block;
|
||||
LogicalInstruction* logicalInstruction;
|
||||
unsigned readCount;
|
||||
|
@ -26,7 +26,7 @@ class ForkElement {
|
||||
|
||||
class ForkState: public Compiler::State {
|
||||
public:
|
||||
ForkState(Stack* stack, Local* locals, Cell<Value>* saved, Event* predecessor,
|
||||
ForkState(Stack* stack, Local* locals, List<Value*>* saved, Event* predecessor,
|
||||
unsigned logicalIp):
|
||||
stack(stack),
|
||||
locals(locals),
|
||||
@ -38,7 +38,7 @@ class ForkState: public Compiler::State {
|
||||
|
||||
Stack* stack;
|
||||
Local* locals;
|
||||
Cell<Value>* saved;
|
||||
List<Value*>* saved;
|
||||
Event* predecessor;
|
||||
unsigned logicalIp;
|
||||
unsigned readCount;
|
||||
|
@ -66,8 +66,8 @@ bool MultiRead::intersect(SiteMask* mask, unsigned depth) {
|
||||
bool result = false;
|
||||
if (not visited) {
|
||||
visited = true;
|
||||
for (Cell<Read>** cell = &reads; *cell;) {
|
||||
Read* r = (*cell)->value;
|
||||
for (List<Read*>** cell = &reads; *cell;) {
|
||||
Read* r = (*cell)->item;
|
||||
bool valid = r->intersect(mask, depth + 1);
|
||||
if (valid) {
|
||||
result = true;
|
||||
@ -89,8 +89,8 @@ bool MultiRead::valid() {
|
||||
bool result = false;
|
||||
if (not visited) {
|
||||
visited = true;
|
||||
for (Cell<Read>** cell = &reads; *cell;) {
|
||||
Read* r = (*cell)->value;
|
||||
for (List<Read*>** cell = &reads; *cell;) {
|
||||
Read* r = (*cell)->item;
|
||||
if (r->valid()) {
|
||||
result = true;
|
||||
cell = &((*cell)->next);
|
||||
@ -104,7 +104,7 @@ bool MultiRead::valid() {
|
||||
}
|
||||
|
||||
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) {
|
||||
reads = cell;
|
||||
} else {
|
||||
@ -114,7 +114,7 @@ void MultiRead::append(Context* c, Read* r) {
|
||||
|
||||
// fprintf(stderr, "append %p to %p for %p\n", r, lastTarget, this);
|
||||
|
||||
lastTarget->value = r;
|
||||
lastTarget->item = r;
|
||||
}
|
||||
|
||||
Read* MultiRead::next(Context* c) {
|
||||
@ -122,7 +122,7 @@ Read* MultiRead::next(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);
|
||||
|
||||
@ -137,7 +137,7 @@ void MultiRead::allocateTarget(Context* c) {
|
||||
Read* MultiRead::nextTarget() {
|
||||
// fprintf(stderr, "next target for %p: %p\n", this, firstTarget);
|
||||
|
||||
Read* r = firstTarget->value;
|
||||
Read* r = firstTarget->item;
|
||||
firstTarget = firstTarget->next;
|
||||
return r;
|
||||
}
|
||||
|
@ -88,10 +88,10 @@ class MultiRead: public Read {
|
||||
|
||||
Read* nextTarget();
|
||||
|
||||
Cell<Read>* reads;
|
||||
Cell<Read>* lastRead;
|
||||
Cell<Read>* firstTarget;
|
||||
Cell<Read>* lastTarget;
|
||||
List<Read*>* reads;
|
||||
List<Read*>* lastRead;
|
||||
List<Read*>* firstTarget;
|
||||
List<Read*>* lastTarget;
|
||||
bool visited;
|
||||
};
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <avian/vm/codegen/targets.h>
|
||||
|
||||
#include <avian/util/runtime-array.h>
|
||||
#include <avian/util/list.h>
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -211,17 +212,6 @@ class MyThread: public Thread {
|
||||
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,
|
||||
object continuation, MyThread::CallTrace* trace)
|
||||
{
|
||||
@ -301,7 +291,7 @@ class MyThread: public Thread {
|
||||
Context* transition;
|
||||
TraceContext* traceContext;
|
||||
uintptr_t stackLimit;
|
||||
ReferenceFrame* referenceFrame;
|
||||
List<Reference*>* referenceFrame;
|
||||
bool methodLockIsClean;
|
||||
};
|
||||
|
||||
@ -9061,8 +9051,8 @@ class MyProcessor: public Processor {
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
t->referenceFrame = new
|
||||
(t->m->heap->allocate(sizeof(MyThread::ReferenceFrame)))
|
||||
MyThread::ReferenceFrame(t->referenceFrame, t->reference);
|
||||
(t->m->heap->allocate(sizeof(List<Reference*>)))
|
||||
List<Reference*>(t->reference, t->referenceFrame);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -9072,13 +9062,13 @@ class MyProcessor: public Processor {
|
||||
{
|
||||
MyThread* t = static_cast<MyThread*>(vmt);
|
||||
|
||||
MyThread::ReferenceFrame* f = t->referenceFrame;
|
||||
List<Reference*>* f = t->referenceFrame;
|
||||
t->referenceFrame = f->next;
|
||||
while (t->reference != f->reference) {
|
||||
while (t->reference != f->item) {
|
||||
vm::dispose(t, t->reference);
|
||||
}
|
||||
|
||||
t->m->heap->free(f, sizeof(MyThread::ReferenceFrame));
|
||||
t->m->heap->free(f, sizeof(List<Reference*>));
|
||||
}
|
||||
|
||||
virtual object
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <avian/vm/system/system.h>
|
||||
#include <avian/util/string.h>
|
||||
#include <avian/util/runtime-array.h>
|
||||
#include <avian/util/list.h>
|
||||
|
||||
#include "avian/zlib-custom.h"
|
||||
#include "avian/finder.h"
|
||||
@ -241,15 +242,14 @@ class JarIndex {
|
||||
Deflated = 8
|
||||
};
|
||||
|
||||
class Node {
|
||||
public:
|
||||
Node(uint32_t hash, const uint8_t* entry, Node* next):
|
||||
hash(hash), entry(entry), next(next)
|
||||
{ }
|
||||
class Entry {
|
||||
public:
|
||||
Entry(uint32_t hash, const uint8_t* entry):
|
||||
hash(hash),
|
||||
entry(entry) {}
|
||||
|
||||
uint32_t hash;
|
||||
const uint8_t* entry;
|
||||
Node* next;
|
||||
};
|
||||
|
||||
JarIndex(System* s, Allocator* allocator, unsigned capacity):
|
||||
@ -257,14 +257,14 @@ class JarIndex {
|
||||
allocator(allocator),
|
||||
capacity(capacity),
|
||||
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) {
|
||||
return new
|
||||
(allocator->allocate(sizeof(JarIndex) + (sizeof(Node*) * capacity)))
|
||||
(allocator->allocate(sizeof(JarIndex) + (sizeof(List<Entry>*) * capacity)))
|
||||
JarIndex(s, allocator, capacity);
|
||||
}
|
||||
|
||||
@ -279,46 +279,46 @@ class JarIndex {
|
||||
// Find end of central directory record
|
||||
while (p > start) {
|
||||
if (signature(p) == CentralDirectorySignature) {
|
||||
p = region->start() + centralDirectoryOffset(p);
|
||||
|
||||
while (p < end) {
|
||||
if (signature(p) == EntrySignature) {
|
||||
index = index->add(hash(fileName(p), fileNameLength(p)), p);
|
||||
p = region->start() + centralDirectoryOffset(p);
|
||||
|
||||
p = endOfEntry(p);
|
||||
} else {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
while (p < end) {
|
||||
if (signature(p) == EntrySignature) {
|
||||
index = index->add(Entry(hash(fileName(p), fileNameLength(p)), p));
|
||||
|
||||
p = endOfEntry(p);
|
||||
} else {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p--;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
JarIndex* add(uint32_t hash, const uint8_t* entry) {
|
||||
JarIndex* add(const Entry& entry) {
|
||||
if (position < capacity) {
|
||||
unsigned i = hash & (capacity - 1);
|
||||
table[i] = new (nodes + (position++)) Node(hash, entry, table[i]);
|
||||
unsigned i = entry.hash & (capacity - 1);
|
||||
table[i] = new (nodes + (position++)) List<Entry>(entry, table[i]);
|
||||
return this;
|
||||
} else {
|
||||
JarIndex* index = make(s, allocator, capacity * 2);
|
||||
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();
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
Node* findNode(const char* name) {
|
||||
List<Entry>* findNode(const char* name) {
|
||||
unsigned length = strlen(name);
|
||||
unsigned i = hash(name) & (capacity - 1);
|
||||
for (Node* n = table[i]; n; n = n->next) {
|
||||
const uint8_t* p = n->entry;
|
||||
for (List<Entry>* n = table[i]; n; n = n->next) {
|
||||
const uint8_t* p = n->item.entry;
|
||||
if (equal(name, length, fileName(p), fileNameLength(p))) {
|
||||
return n;
|
||||
}
|
||||
@ -327,14 +327,14 @@ class JarIndex {
|
||||
}
|
||||
|
||||
System::Region* find(const char* name, const uint8_t* start) {
|
||||
Node* n = findNode(name);
|
||||
List<Entry>* n = findNode(name);
|
||||
if (n) {
|
||||
const uint8_t* p = n->entry;
|
||||
const uint8_t* p = n->item.entry;
|
||||
switch (compressionMethod(p)) {
|
||||
case Stored: {
|
||||
return new (allocator->allocate(sizeof(PointerRegion)))
|
||||
PointerRegion(s, allocator, fileData(start + localHeaderOffset(p)),
|
||||
compressedSize(p));
|
||||
compressedSize(p));
|
||||
} break;
|
||||
|
||||
case Deflated: {
|
||||
@ -345,7 +345,7 @@ class JarIndex {
|
||||
z_stream zStream; memset(&zStream, 0, sizeof(z_stream));
|
||||
|
||||
zStream.next_in = const_cast<uint8_t*>(fileData(start +
|
||||
localHeaderOffset(p)));
|
||||
localHeaderOffset(p)));
|
||||
zStream.avail_in = compressedSize(p);
|
||||
zStream.next_out = region->data;
|
||||
zStream.avail_out = region->length();
|
||||
@ -372,9 +372,9 @@ class JarIndex {
|
||||
|
||||
System::FileType stat(const char* name, unsigned* length, bool tryDirectory)
|
||||
{
|
||||
Node* node = findNode(name);
|
||||
List<Entry>* node = findNode(name);
|
||||
if (node) {
|
||||
*length = uncompressedSize(node->entry);
|
||||
*length = uncompressedSize(node->item.entry);
|
||||
return System::TypeFile;
|
||||
} else if (tryDirectory) {
|
||||
*length = 0;
|
||||
@ -399,8 +399,8 @@ class JarIndex {
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
allocator->free(nodes, sizeof(Node) * capacity);
|
||||
allocator->free(this, sizeof(*this) + (sizeof(Node*) * capacity));
|
||||
allocator->free(nodes, sizeof(List<Entry>) * capacity);
|
||||
allocator->free(this, sizeof(*this) + (sizeof(List<Entry>*) * capacity));
|
||||
}
|
||||
|
||||
System* s;
|
||||
@ -408,8 +408,8 @@ class JarIndex {
|
||||
unsigned capacity;
|
||||
unsigned position;
|
||||
|
||||
Node* nodes;
|
||||
Node* table[0];
|
||||
List<Entry>* nodes;
|
||||
List<Entry>* table[0];
|
||||
};
|
||||
|
||||
class JarElement: public Element {
|
||||
@ -422,9 +422,9 @@ class JarElement: public Element {
|
||||
|
||||
virtual const char* next(unsigned* size) {
|
||||
if (position < index->position) {
|
||||
JarIndex::Node* n = index->nodes + (position++);
|
||||
*size = fileNameLength(n->entry);
|
||||
return reinterpret_cast<const char*>(fileName(n->entry));
|
||||
List<JarIndex::Entry>* n = index->nodes + (position++);
|
||||
*size = fileNameLength(n->item.entry);
|
||||
return reinterpret_cast<const char*>(fileName(n->item.entry));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "avian/arch.h"
|
||||
|
||||
#include <avian/util/runtime-array.h>
|
||||
#include <avian/util/list.h>
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -30,16 +31,6 @@ const unsigned FrameFootprint = 4;
|
||||
|
||||
class Thread: public vm::Thread {
|
||||
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):
|
||||
vm::Thread(m, javaThread, parent),
|
||||
@ -47,14 +38,14 @@ class Thread: public vm::Thread {
|
||||
sp(0),
|
||||
frame(-1),
|
||||
code(0),
|
||||
referenceFrame(0)
|
||||
stackPointers(0)
|
||||
{ }
|
||||
|
||||
unsigned ip;
|
||||
unsigned sp;
|
||||
int frame;
|
||||
object code;
|
||||
ReferenceFrame* referenceFrame;
|
||||
List<unsigned>* stackPointers;
|
||||
uintptr_t stack[0];
|
||||
};
|
||||
|
||||
@ -3079,9 +3070,8 @@ class MyProcessor: public Processor {
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
if (t->sp + capacity < stackSizeInWords(t) / 2) {
|
||||
t->referenceFrame = new
|
||||
(t->m->heap->allocate(sizeof(Thread::ReferenceFrame)))
|
||||
Thread::ReferenceFrame(t->referenceFrame, t->sp);
|
||||
t->stackPointers = new(t->m->heap)
|
||||
List<unsigned>(t->sp, t->stackPointers);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
@ -3094,11 +3084,11 @@ class MyProcessor: public Processor {
|
||||
{
|
||||
Thread* t = static_cast<Thread*>(vmt);
|
||||
|
||||
Thread::ReferenceFrame* f = t->referenceFrame;
|
||||
t->referenceFrame = f->next;
|
||||
t->sp = f->sp;
|
||||
List<unsigned>* f = t->stackPointers;
|
||||
t->stackPointers = f->next;
|
||||
t->sp = f->item;
|
||||
|
||||
t->m->heap->free(f, sizeof(Thread::ReferenceFrame));
|
||||
t->m->heap->free(f, sizeof(List<unsigned>));
|
||||
}
|
||||
|
||||
virtual object
|
||||
|
102
src/util.cpp
102
src/util.cpp
@ -9,6 +9,7 @@
|
||||
details. */
|
||||
|
||||
#include "avian/util.h"
|
||||
#include <avian/util/list.h>
|
||||
|
||||
using namespace vm;
|
||||
|
||||
@ -16,13 +17,6 @@ namespace {
|
||||
|
||||
class TreeContext {
|
||||
public:
|
||||
class Path {
|
||||
public:
|
||||
Path(object node, Path* next): node(node), next(next) { }
|
||||
|
||||
object node;
|
||||
Path* next;
|
||||
};
|
||||
|
||||
class MyProtector: public Thread::Protector {
|
||||
public:
|
||||
@ -34,8 +28,8 @@ class TreeContext {
|
||||
v->visit(&(context->root));
|
||||
v->visit(&(context->node));
|
||||
|
||||
for (Path* p = context->ancestors; p; p = p->next) {
|
||||
v->visit(&(p->node));
|
||||
for (List<object>* p = context->ancestors; p; p = p->next) {
|
||||
v->visit(&(p->item));
|
||||
}
|
||||
}
|
||||
|
||||
@ -50,15 +44,15 @@ class TreeContext {
|
||||
Zone* zone;
|
||||
object root;
|
||||
object node;
|
||||
Path* ancestors;
|
||||
List<object>* ancestors;
|
||||
MyProtector protector;
|
||||
bool fresh;
|
||||
};
|
||||
|
||||
TreeContext::Path*
|
||||
path(TreeContext* c, object node, TreeContext::Path* next)
|
||||
List<object>*
|
||||
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
|
||||
@ -212,99 +206,99 @@ treeAdd(Thread* t, TreeContext* c)
|
||||
|
||||
// rebalance
|
||||
setTreeNodeRed(t, new_, true);
|
||||
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->node)) {
|
||||
if (c->ancestors->node
|
||||
== treeNodeLeft(t, c->ancestors->next->node))
|
||||
while (c->ancestors != 0 and treeNodeRed(t, c->ancestors->item)) {
|
||||
if (c->ancestors->item
|
||||
== treeNodeLeft(t, c->ancestors->next->item))
|
||||
{
|
||||
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
|
||||
(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;
|
||||
} else {
|
||||
if (new_ == treeNodeRight(t, c->ancestors->node)) {
|
||||
new_ = c->ancestors->node;
|
||||
if (new_ == treeNodeRight(t, c->ancestors->item)) {
|
||||
new_ = c->ancestors->item;
|
||||
c->ancestors = c->ancestors->next;
|
||||
|
||||
object n = leftRotate(t, new_);
|
||||
|
||||
if (new_ == treeNodeRight(t, c->ancestors->node)) {
|
||||
set(t, c->ancestors->node, TreeNodeRight, n);
|
||||
if (new_ == treeNodeRight(t, c->ancestors->item)) {
|
||||
set(t, c->ancestors->item, TreeNodeRight, n);
|
||||
} else {
|
||||
set(t, c->ancestors->node, TreeNodeLeft, n);
|
||||
set(t, c->ancestors->item, TreeNodeLeft, n);
|
||||
}
|
||||
c->ancestors = path(c, n, c->ancestors);
|
||||
}
|
||||
setTreeNodeRed(t, c->ancestors->node, false);
|
||||
setTreeNodeRed(t, c->ancestors->next->node, true);
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
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) {
|
||||
newRoot = n;
|
||||
} else if (treeNodeRight(t, c->ancestors->next->next->node)
|
||||
== c->ancestors->next->node)
|
||||
} else if (treeNodeRight(t, c->ancestors->next->next->item)
|
||||
== c->ancestors->next->item)
|
||||
{
|
||||
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
|
||||
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
|
||||
} else {
|
||||
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
|
||||
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
|
||||
}
|
||||
// done
|
||||
}
|
||||
} else { // this is just the reverse of the code above (right and
|
||||
// left swapped):
|
||||
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
|
||||
(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;
|
||||
} else {
|
||||
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
|
||||
new_ = c->ancestors->node;
|
||||
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
|
||||
new_ = c->ancestors->item;
|
||||
c->ancestors = c->ancestors->next;
|
||||
|
||||
object n = rightRotate(t, new_);
|
||||
|
||||
if (new_ == treeNodeLeft(t, c->ancestors->node)) {
|
||||
set(t, c->ancestors->node, TreeNodeLeft, n);
|
||||
if (new_ == treeNodeLeft(t, c->ancestors->item)) {
|
||||
set(t, c->ancestors->item, TreeNodeLeft, n);
|
||||
} else {
|
||||
set(t, c->ancestors->node, TreeNodeRight, n);
|
||||
set(t, c->ancestors->item, TreeNodeRight, n);
|
||||
}
|
||||
c->ancestors = path(c, n, c->ancestors);
|
||||
}
|
||||
setTreeNodeRed(t, c->ancestors->node, false);
|
||||
setTreeNodeRed(t, c->ancestors->next->node, true);
|
||||
setTreeNodeRed(t, c->ancestors->item, false);
|
||||
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) {
|
||||
newRoot = n;
|
||||
} else if (treeNodeLeft(t, c->ancestors->next->next->node)
|
||||
== c->ancestors->next->node)
|
||||
} else if (treeNodeLeft(t, c->ancestors->next->next->item)
|
||||
== c->ancestors->next->item)
|
||||
{
|
||||
set(t, c->ancestors->next->next->node, TreeNodeLeft, n);
|
||||
set(t, c->ancestors->next->next->item, TreeNodeLeft, n);
|
||||
} else {
|
||||
set(t, c->ancestors->next->next->node, TreeNodeRight, n);
|
||||
set(t, c->ancestors->next->next->item, TreeNodeRight, n);
|
||||
}
|
||||
// done
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user