File: ObjMap.cpp

package info (click to toggle)
storm-lang 0.7.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,028 kB
  • sloc: ansic: 261,471; cpp: 140,432; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (104 lines) | stat: -rw-r--r-- 2,062 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "stdafx.h"
#include "ObjMap.h"

namespace storm {

	RawObjMap::RawObjMap(Gc &gc) : gc(gc), root(null), data(null), capacity(0), filled(0) {}

	RawObjMap::~RawObjMap() {
		clear();
	}

	void RawObjMap::clear() {
		Gc::destroyRoot(root);
		root = null;
		delete []data;
		data = null;
		capacity = 0;
		filled = 0;
	}

	void RawObjMap::put(void *from, void *to) {
		if (capacity == filled)
			grow();

		Item i = { from, to };
		data[filled++] = i;
	}

	void RawObjMap::grow() {
		nat nCap = capacity * 2;
		if (capacity == 0)
			nCap = 8;

		Item *nData = new Item[nCap];
		memset(nData, 0, sizeof(Item)*nCap);
		Gc::Root *nRoot = gc.createRoot(nData, nCap*2);

		if (data) {
			for (nat i = 0; i < filled; i++)
				nData[i] = data[i];

			gc.destroyRoot(root);
			delete []data;
		}

		data = nData;
		capacity = nCap;
		root = nRoot;
	}

	struct RawObjMap::Predicate {
		bool operator()(const Item &a, const Item &b) const {
			return size_t(a.from) < size_t(b.from);
		}
		bool operator()(const Item &a, void *b) const {
			return size_t(a.from) < size_t(b);
		}
	};

	void RawObjMap::sort() {
		if (data) {
			std::sort(data, data + filled, Predicate());

			// Handle transitive dependencies. O(n log n) assuming we don't have very long chains
			// (which are not very common).
			for (nat i = 0; i < filled; i++) {
				void *p = data[i].to;
				while (void *next = find(p))
					p = next;

				data[i].to = p;
			}
		}
	}

	void *RawObjMap::find(void *obj) {
		Item *end = data + filled;
		Item *found = std::lower_bound(data, end, obj, Predicate());
		if (found == end)
			return null;

		if (found->from == obj)
			return found->to;
		else
			return null;
	}

	RawObjMap::Item RawObjMap::findBefore(void *obj) {
		Item *end = data + filled;
		Item *found = std::lower_bound(data, end, obj, Predicate());

		// Exact match?
		if (found != end && found->from == obj)
			return *found;

		// Otherwise, look at the previous element if there is one:
		if (found != data)
			return *(found - 1);

		Item empty = { null, null };
		return empty;
	}

}