aboutsummaryrefslogtreecommitdiff
path: root/ic-reals-6.3/base/nodeId.c
blob: 035fa49dc7b22ee9f03da54f4a3140ed83a2c456 (plain)
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
/*
 * Copyright (C) 2000, Imperial College
 *
 * This file is part of the Imperial College Exact Real Arithmetic Library.
 * See the copyright notice included in the distribution for conditions
 * of use.
 */

#include <stdio.h>
#include "real.h"
#include "real-impl.h"

/*
 * For debugging purposes, we assign a unique identifier to each object in
 * the heap. This identifier is invariant under copying in garbage collection.
 * Also the names of the nodes in daVinci are strings formed from the 
 * assigned nodeId.
 */
int nodeId = 1;

/*
 * For debugging purposes, nodes are assigned id's which (unlike the address
 * of the node) is invariant under garbage collection.
 *
 * This file allocates ids and provides a function for mapping ids to
 * heap addresses.
 */
void
newNodeId(Generic *node)
{
	void addHashTableEntry(Generic *);

	node->tag.nodeId = nodeId++;
	addHashTableEntry(node);
}
 
/*
 * We use a naive hash table to map node identifiers to heap cells.
 */
typedef struct HTE {
	struct HTE *next;
	Generic *node;
} HashTableEntry;

/*
 * The following must be an integer power of 2
 */
#define HASH_TABLE_SIZE 512
#define HASH_TABLE_MASK (HASH_TABLE_SIZE - 1)

static HashTableEntry *hashTable[HASH_TABLE_SIZE] = {NULL};

void
addHashTableEntry(Generic *node)
{
	HashTableEntry *new;
	
	if ((new = (HashTableEntry *) malloc(sizeof(HashTableEntry))) == NULL)
		Error(FATAL, E_INT, "addHashTableEntry", "malloc failed");

	new->node = node;
	new->next = hashTable[node->tag.nodeId & HASH_TABLE_MASK];
	hashTable[node->tag.nodeId & HASH_TABLE_MASK] = new;
}

Generic *
mapNodeIdToHeapCell(int nodeId)
{
	HashTableEntry *p;

	p = hashTable[nodeId & HASH_TABLE_MASK];

	while (p != NULL) {
		if (p->node->tag.nodeId == nodeId)
			return p->node;
		else
			p = p->next;
	}
	Error(FATAL, E_INT, "mapNodeIdToHeapCell", "failed to find nodeId %d", nodeId);
	return NULL;
}