ERIS CORE
svcDataDictionary.cpp
Go to the documentation of this file.
1 #include "svcDataDictionary.h"
2 
3 /**
4  * @file svcDataDictionary.cpp
5  * @author Brian Monkaba (brian.monkaba@gmail.com)
6  * @brief Data Dictionary service
7  * provides an interface to a data dictionary service
8  * the service shall provide a CRUD (create,read,update,destroy) interface
9  * data shall be globally readable
10  * create operation shall require a pointer to the owner
11  * update and destroy operations can only be made by the owner
12  * the owner pointer shall never be dereferenced or accessed by the service; it only serves as an ID
13  * NULL pointers are OK. They can be utilized to create globally modifiable (update,destroy) records
14  *
15  *
16  * @version 0.1
17  * @date 2021-08-12
18  *
19  * @copyright Copyright (c) 2021
20  *
21  */
22 
23 bool SvcDataDictionary::copyKey(const char* key){
24  if (next == DATADICT_KEYVALUE_PAIRS) return false;
25  return safer_strncpy(record[next].key,key,DATADICT_MAX_KEY_LEN);
26 }
27 
29  next=0;
31  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
32  record[i].owner = 0;
33  record[i].val.int32_val = 0;
36  record[i].key_hash = 48879; //0xBEEF
37  #ifdef DATADICT_USE_MALLOC
38  record[i].key = (char*)extmem_malloc(DATADICT_MAX_KEY_LEN+1);
39  #else
40  memset(record[i].key,0,sizeof(record[i].key));
41  #endif
42  }
43 }
44 
45 uint32_t FASTRUN SvcDataDictionary::hash(const char* s){
46  //uint32 djb2 string hash
47  uint32_t h = 5381;
48  int c;
49  while (c = (*s++)){h = ((h << 5) + h) + c;}
50  return h;
51 }
52 
53 bool SvcDataDictionary::create(const char* key,int32_t val,uint32_t* owner){
54  if (!copyKey(key)) return false;
55  record[next].val.int32_val = val;
56  record[next].owner = owner;
58  record[next].key_hash = hash(key);
59  next++;
60  return true;
61 }
62 
63 bool FLASHMEM SvcDataDictionary::create(const char* key,int32_t val){
64  if (!copyKey(key)) return false;
65  record[next].val.int32_val = val;
66  record[next].owner = 0;
69  record[next].key_hash = hash(key);
70  next++;
71  return true;
72 }
73 
74 bool FLASHMEM SvcDataDictionary::create(const char* key,float32_t val){
75  if (!copyKey(key)) return false;
76  record[next].val.float32_val = val;
77  record[next].owner = 0;
80  record[next].key_hash = hash(key);
81  next++;
82  return true;
83 }
84 
85 int32_t FASTRUN SvcDataDictionary::read(const char* key){
86  uint32_t h;
87  h = hash(key);
88  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
89  //key found
90  if (record[i].key_hash == h) return record[i].val.int32_val;
91  }
92  //key not found
93  return 0;
94 }
95 
96 float32_t FASTRUN SvcDataDictionary::readf(const char* key){
97  uint32_t h;
98  h = hash(key);
99  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
100  //key found
101  if (record[i].key_hash == h) return record[i].val.float32_val;
102  }
103  //key not found
104  return 0;
105 }
106 
107 bool SvcDataDictionary::update(const char* key,int32_t val,uint32_t* owner){
108  uint32_t h;
109  h = hash(key);
110 
111  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
112  //key found
113  if (record[i].key_hash == h){
114  //if ((0==strncmp(record[i].key,key,DATADICT_MAX_KEY_LEN))){
115  if (record[next].owner == owner && record[next].data_type == DDDT_INT32){
116  record[i].val.int32_val = val;
117  //arm_dcache_flush_delete(&record[i], sizeof(record[i]));
118  return true;
119  } else return false;
120  }
121  }
122  //key not found - try to create a new record
123  return create(key, val, owner);
124 }
125 
126 bool SvcDataDictionary::update(const char* key,float32_t val,uint32_t* owner){
127  uint32_t h;
128  h = hash(key);
129 
130  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
131  //key found
132  if (record[i].key_hash == h){
133  //if ((0==strncmp(record[i].key,key,DATADICT_MAX_KEY_LEN))){
134  if (record[next].owner == owner && record[next].data_type == DDDT_FLOAT32){
135  record[i].val.float32_val = val;
136  //arm_dcache_flush_delete(&record[i], sizeof(record[i]));
137  return true;
138  } else return false;
139  }
140  }
141  //key not found - try to create a new record
142  return create(key, val, owner);
143 }
144 
145 bool FASTRUN SvcDataDictionary::update(const char* key,int32_t val){
146  uint32_t h;
147  h = hash(key);
148 
149  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
150  //key found
151  if (record[i].key_hash == h){
152  //if ((0==strncmp(record[i].key,key,DATADICT_MAX_KEY_LEN))){
153  if (record[i].record_type == DDRT_READWRITE && record[i].data_type == DDDT_INT32){
154  record[i].val.int32_val = val;
155  //arm_dcache_flush_delete(&record[i], sizeof(record[i]));
156  return true;
157  } else return false;
158  }
159  }
160  //key not found - try to create a new record
161  return create(key, val);
162 }
163 
164 bool FASTRUN SvcDataDictionary::update(const char* key,float32_t val){
165  uint32_t h;
166  h = hash(key);
167 
168  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
169  //key found
170  if (record[i].key_hash == h){
171  //if ((0==strncmp(record[i].key,key,DATADICT_MAX_KEY_LEN))){
172  if (record[i].record_type == DDRT_READWRITE && record[i].data_type == DDDT_FLOAT32){
173  record[i].val.float32_val = val;
174  //arm_dcache_flush_delete(&record[i], sizeof(record[i]));
175  return true;
176  } else return false;
177  }
178  }
179  //key not found - try to create a new record
180  return create(key, val);
181 }
182 
183 bool SvcDataDictionary::increment(const char* key){
184  uint32_t h;
185  h = hash(key);
186 
187  int index = -1;
188  for(int i=0;i<DATADICT_KEYVALUE_PAIRS;i++){
189  //key found
190  if (record[i].key_hash == h){
191  //if ((0==strncmp(record[i].key,key,DATADICT_MAX_KEY_LEN))){
192  index = i;
193  break;
194  }
195  }
196  if (index == -1){
197  if (!create(key,(int32_t)0)) return false;
198  index = next -1;
199  }
200  if (record[index].data_type == DDDT_INT32){
201  record[index].val.int32_val++;
202  }else if (record[index].data_type == DDDT_FLOAT32){
203  record[index].val.float32_val++;
204  }
205  return true;
206 }
207 
208 //serial interface
210 
211 }
212 
214  //todo: print out in JSON format
215  //Serial.flush();
217  sci->print(F("DD {"));
218  uint16_t from, to;
219  from = dd_transmitt_block++ * 16; //block size
220  to = dd_transmitt_block * 16;
221  if (to >= next){
222  to = next;
223  dd_transmitt_block = 0;
224  }
225 
226  for(int i=from;i<to;i++){
227  if (record[i].data_type == DDDT_INT32){
228  sci->printf("\"%s\":%d",record[i].key,record[i].val.int32_val);
229  }else if (record[i].data_type == DDDT_FLOAT32){
230  sci->printf("\"%s\":%f",record[i].key,record[i].val.float32_val);
231  }
232  if (i != to-1) sci->print(",");
233  }
234  sci->println("}");
235  sci->sendLZ4Message();
236  }
237 }
238 
SvcSerialCommandInterface sci
Definition: ErisCore.cpp:22
const char PROGMEM s[][16]
Definition: Eris.h:246
bool safer_strncpy(char *dest, const char *source, uint16_t dest_size)
a safer strncpy
Definition: ErisUtils.cpp:20
@ DDRT_READWRITE
@ DDRT_READ
@ DDDT_FLOAT32
@ DDDT_INT32
Data Dictionary service provides an interface to a data dictionary service the service shall provide ...
int32_t read(const char *key)
returns the int32_t value of the record
bool create(const char *key, int32_t val, uint32_t *owner)
create a record with ownership
svcDataDictionaryRecord record[DATADICT_KEYVALUE_PAIRS]
bool copyKey(const char *key)
float32_t readf(const char *key)
returns the float32_t value of the record
bool increment(const char *key)
increments the value of a global record creates a new record if one does not exist and initializes ...
bool update(const char *key, int32_t val, uint32_t *owner)
update the value of an owned record creates a new record if one does not exist and initializes its ...
uint32_t hash(const char *s)
hashing function used to accelerate searches
void printStats()
printStats function
void printDictionary(SvcSerialCommandInterface *sci)
prints the dictionary to the SvcSerialCommandInterface
bool requestStartLZ4Message()
request to start a lz4 compressed message starts the message and returns true if available returns f...
void sendLZ4Message()
Calling this function signals the end of a compressed message. The txBuffer contents are lz4 compres...
Serial communication service and interface Serial commands (rx): .
svcDataDictionaryRecordType record_type
svcDataDictionaryDataType data_type