-
Notifications
You must be signed in to change notification settings - Fork 5
/
OLCB_Alias_Cache.h
144 lines (130 loc) · 3.36 KB
/
OLCB_Alias_Cache.h
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
#ifndef __OLCB_ALIAS_CACHE_H__
#define __OLCB_ALIAS_CACHE_H__
/********
OLCB_Alias_Cache is a class that caches the aliases of all virtual nodes hosted in this
board, as well as the most recently accessed NodeIDs elsewhere on the network.
It watches for messages that add, delete, or modify the can aliases of any node.
This class is here so that CAN aliases can be handled transparently, without any knowledge
or dependencies by the end user of the library.
Used by OLCB_Link
********/
class OLCB_Alias_Cache;
#if defined(__AVR__)
#include <stdlib.h>
#if defined(OLCB_DEBUG)
#include "Arduino.h"
#endif
#endif
#include <string.h>
#include "OLCB_NodeID.h"
class OLCB_Alias_Cache
{
public:
OLCB_Alias_Cache() : _size(0)
{
}
void initialize(uint8_t newSize) //must be AT LEAST the number of virtual nodes plus 1; the larger the more efficient sending addressed outbound messages will be
{
if(_size)
{
//if already inited, release existing memory? TODO
}
_size = newSize;
#if defined(__arm__)
_nids = new OLCB_NodeID[_size];
_hits = new uint8_t[_size];
#elif defined(__AVR__)
_nids = (OLCB_NodeID*)malloc(sizeof(OLCB_NodeID)*_size);
_hits = (uint8_t*)malloc(sizeof(uint8_t)*_size);
#endif
for(uint8_t i = 0; i < _size; ++i)
{
_nids[i].set(0,0,0,0,0,0);
_nids[i].alias = 0;
_hits[i] = 0;
}
}
void add(OLCB_NodeID *nid)
{
//Serial.println("In AliasCache->add()");
//find the least used entry, while making sure the alias isn't already cached.
if(!nid->alias) //No alias? Nothing to cache!
{
//Serial.println("No alias, no cache!");
return;
}
//else
//Serial.print("Cacheing alias "); //Serial.println(nid->alias,DEC);
uint8_t leasthits = 255;
uint8_t index = 0;
for(uint8_t i=0; i < _size; ++i)
{
if(_nids[i] == *nid)
{
//already cached; return.
//Serial.println("What do you know? Already in the cache!");
return;
}
if(_hits[i] < leasthits)
{
leasthits = _hits[i];
index = i;
}
}
//Serial.print("Cacheing it in index "); //Serial.println(index, DEC);
memcpy(&(_nids[index]), nid, sizeof(OLCB_NodeID));
_hits[index] = 1;
//Serial.println("Leaving add()");
}
bool getAliasByNID(OLCB_NodeID *nid)
{
//Serial.println("Looking for alias for:");
//nid->print();
for(uint8_t i = 0; i < _size; ++i)
{
if(_nids[i] == *nid)
{
if(_hits[i] < 255) ++_hits[i];
nid->alias = _nids[i].alias;
return true;
}
}
//Serial.println("Not in alias cache");
return false;
}
bool getNIDByAlias(OLCB_NodeID *nid)
{
for(uint8_t i = 0; i < _size; ++i)
{
if(_nids[i].alias == nid->alias)
{
if(_hits[i] < 255) ++_hits[i];
memcpy(&(nid->val), &(_nids[i].val), 6);
return true;
}
}
return false;
}
bool removeByAlias(uint16_t alias)
{
//Serial.print("alias helper: ");
for(uint8_t i=0; i < _size; ++i)
{
if(_nids[i].alias == alias)
{
//Serial.print("removing alias at loc ");
//Serial.print(i, DEC);
_nids[i].set(0,0,0,0,0,0);
_hits[i] = 0;
return true;
}
}
//Serial.println();
return false; //not in cache
}
private:
uint8_t _size;
OLCB_NodeID* _nids;
uint8_t* _hits;
};
#endif