This repository has been archived by the owner on Nov 29, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathNames.cpp
103 lines (83 loc) · 2.27 KB
/
Names.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
/* simple fixed size hashtable with no chaining for use on constrained devices */
#include <Arduino.h>
#include "Strings.h"
#include "Names.h"
Names::Names()
{
this->entries = 0;
memset(&table[0], 0, sizeof(HashEntry) * HASH_TABLE_SIZE);
}
float Names::used()
{
// return percentage table is filled
return 100.0 * entries / (1.0 * HASH_TABLE_SIZE);
}
void Names::print()
{
Serial.print(F("Hash table has "));
Serial.print(entries);
Serial.print(F(" entries, "));
Serial.print(used());
Serial.println(F("% full"));
for (int i = HASH_TABLE_SIZE; i > 0; )
{
HashEntry *entry = table + (--i);
if (entry->name)
{
char *p = (char *)entry->name;
Serial.print(" ");
for (int j = entry->length; j; --j)
Serial.print(Strings::get_char(p++));
Serial.print(" : ");
Serial.println(entry->symbol);
}
}
}
unsigned int Names::hash(const char *name, unsigned int length)
{
// Jenkins One-at-a-Time hash
unsigned h = 0;
while (length--)
{
h += (unsigned char)Strings::get_char(name++);
h += ( h << 10 );
h ^= ( h >> 6 );
}
h += ( h << 3 );
h ^= ( h >> 11 );
h += ( h << 15 );
return h;
}
#if defined(pgm_read_byte)
unsigned int Names::symbol(const __FlashStringHelper *name)
{
return symbol(((const char *)name)+PROGMEM_BOUNDARY);
}
#endif
unsigned int Names::symbol(const char *name)
{
return symbol(name, Strings::strlen(name));
}
unsigned int Names::symbol(const char *name, unsigned int length)
{
unsigned int i = HASH_TABLE_SIZE;
unsigned int hashval = hash(name, length);
unsigned int index = hashval % HASH_TABLE_SIZE;
HashEntry *entry = 0;
while (i-- && (entry = table+index, entry->name))
{
// symbol already defined
if (!Strings::strcmp(entry->name, entry->length, name, length))
return entry->symbol;
index = ++index % HASH_TABLE_SIZE;
}
// need to define new symbol
if (i && entry)
{
entry->name = name;
entry->length = length;
entry->symbol = entries++;
return entry->symbol;
}
return 0;
}