-
Notifications
You must be signed in to change notification settings - Fork 0
/
unrolled_int_linked_list.c
149 lines (132 loc) · 2.93 KB
/
unrolled_int_linked_list.c
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#ifndef MAX_ELEMENTS
#define MAX_ELEMENTS 128
#endif
#define MEMORY_POOL_SIZE 25600
#define MAX_NUM_MEMORY_POOLS 1000
/*
* Unrolled integer linked list
*
* This linked list implimentation is read and write
* only. No delete operations are implimented to make
* my life eaiser.
*
* This is an attempt at a cache and locality friendly,
* reasonably space-efficient way to store a sparce
* matrix of keyword search hits.
*
*/
struct Node **_npools;
int _num_node_pools = 0;
int _current_node_count = 0;
int nodes_in_use = 0;
// Unrolled Linked List Node
struct Node
{
int numElements;
int array[MAX_ELEMENTS];
struct Node *next;
};
// Allocate a node pool
void _allocateNewPool()
{
_npools[_num_node_pools++] = malloc(MEMORY_POOL_SIZE * sizeof(struct Node));
_current_node_count = 0;
}
// Init node pool array and allocate first pool
void allocateNodePools()
{
// Allocate our pool of nodes
_num_node_pools = 0;
_current_node_count = 0;
_npools = (struct Node **) malloc(MAX_NUM_MEMORY_POOLS * sizeof(struct Node *));
_allocateNewPool();
}
// Deal out space for a node from contiguous memory pool
struct Node* node_alloc()
{
if(_current_node_count == MEMORY_POOL_SIZE)
{
_allocateNewPool();
}
nodes_in_use++;
return &(_npools[_num_node_pools - 1][_current_node_count++]);
}
// Cleanup after ourselves
void destroyNodePools()
{
int i;
for(i = 0; i < _num_node_pools; i++)
{
free(_npools[i]);
_npools[i] = NULL;
}
free(_npools);
_npools = NULL;
_num_node_pools = 0;
_current_node_count = 0;
nodes_in_use = 0;
}
// Print function for testing
void printUnrolledList(struct Node *n)
{
while (n != NULL)
{
int i;
for (i = 0; i < n->numElements; i++)
{
printf("%d, ", n->array[i]);
}
printf("\n");
n = n->next;
}
}
// Find number of elements stored
int getLength(struct Node *n)
{
int len = 0;
while(n != NULL)
{
len += n->numElements;
n = n->next;
}
return len;
}
// Covert linked list to array
void toArray(struct Node *n, int **array, int *length)
{
*length = getLength(n);
*array = (int *) malloc(*length * sizeof(int));
int pos = 0;
while (n != NULL)
{
memcpy(*array + pos, n->array, n->numElements * sizeof(int));
pos += n->numElements;
n = n->next;
}
}
// Add an integer to the list, returning the current node
// if not yet full or the new node if one is created
struct Node* add(struct Node *n, int x)
{
// We are given an empty list, so create the head node
if(n == NULL)
{
struct Node* new_head_node = NULL;
new_head_node = node_alloc();
return add(new_head_node, x);
}
// We are given a full list, so create a new node insert into it
if(n->numElements == MAX_ELEMENTS)
{
struct Node* new_node = NULL;
new_node = node_alloc();
n->next = new_node;
return add(new_node, x);
}
n->array[n->numElements] = x;
n->numElements += 1;
return n;
}