-
Notifications
You must be signed in to change notification settings - Fork 0
/
pf_hashtable.cpp
167 lines (143 loc) · 3.62 KB
/
pf_hashtable.cpp
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
//
// File: pf_hashtable.cc
// Description: PF_HashTable class implementation
// Authors: Hugo Rivero ([email protected])
// Dallan Quass ([email protected])
//
#include "pf_internal.h"
#include "pf_hashtable.h"
//
// PF_HashTable
//
// Desc: Constructor for PF_HashTable object, which allows search, insert,
// and delete of hash table entries.
// In: numBuckets - number of hash table buckets
//
PF_HashTable::PF_HashTable(int _numBuckets)
{
// Initialize numBuckets local variable from parameter
this->numBuckets = _numBuckets;
// Allocate memory for hash table
hashTable = new PF_HashEntry* [numBuckets];
// Initialize all buckets to empty
for (int i = 0; i < numBuckets; i++)
hashTable[i] = NULL;
}
//
// ~PF_HashTable
//
// Desc: Destructor
//
PF_HashTable::~PF_HashTable()
{
// Clear out all buckets
for (int i = 0; i < numBuckets; i++) {
// Delete all entries in the bucket
PF_HashEntry *entry = hashTable[i];
while (entry != NULL) {
PF_HashEntry *next = entry->next;
delete entry;
entry = next;
}
}
// Finally delete the hash table
delete[] hashTable;
}
//
// Find
//
// Desc: Find a hash table entry.
// In: fd - file descriptor
// pageNum - page number
// Out: slot - set to slot associated with fd and pageNum
// Ret: PF return code
//
RC PF_HashTable::Find(int fd, PageNum pageNum, int &slot)
{
// Get which bucket it should be in
int bucket = Hash(fd, pageNum);
if (bucket<0)
return (PF_HASHNOTFOUND);
// Go through the linked list of this bucket
for (PF_HashEntry *entry = hashTable[bucket];
entry != NULL;
entry = entry->next) {
if (entry->fd == fd && entry->pageNum == pageNum) {
// Found it
slot = entry->slot;
return (0);
}
}
// Didn't find it
return (PF_HASHNOTFOUND);
}
//
// Insert
//
// Desc: Insert a hash table entry
// In: fd - file descriptor
// pagenum - page number
// slot - slot associated with fd and pageNum
// Ret: PF return code
//
RC PF_HashTable::Insert(int fd, PageNum pageNum, int slot)
{
// Get which bucket it should be in
int bucket = Hash(fd, pageNum);
// Check entry doesn't already exist in the bucket
PF_HashEntry *entry;
for (entry = hashTable[bucket];
entry != NULL;
entry = entry->next) {
if (entry->fd == fd && entry->pageNum == pageNum)
return (PF_HASHPAGEEXIST);
}
// Allocate memory for new hash entry
if ((entry = new PF_HashEntry) == NULL)
return (PF_NOMEM);
// Insert entry at head of list for this bucket
entry->fd = fd;
entry->pageNum = pageNum;
entry->slot = slot;
entry->next = hashTable[bucket];
entry->prev = NULL;
if (hashTable[bucket] != NULL)
hashTable[bucket]->prev = entry;
hashTable[bucket] = entry;
// Return ok
return (0);
}
//
// Delete
//
// Desc: Delete a hash table entry
// In: fd - file descriptor
// pagenum - page number
// Ret: PF return code
//
RC PF_HashTable::Delete(int fd, PageNum pageNum)
{
// Get which bucket it should be in
int bucket = Hash(fd, pageNum);
// Find the entry is in this bucket
PF_HashEntry *entry;
for (entry = hashTable[bucket];
entry != NULL;
entry = entry->next) {
if (entry->fd == fd && entry->pageNum == pageNum)
break;
}
// Did we find hash entry?
if (entry == NULL)
return (PF_HASHNOTFOUND);
// Remove this entry
if (entry == hashTable[bucket])
hashTable[bucket] = entry->next;
if (entry->prev != NULL)
entry->prev->next = entry->next;
if (entry->next != NULL)
entry->next->prev = entry->prev;
delete entry;
// Return ook
return (0);
}