-
Notifications
You must be signed in to change notification settings - Fork 247
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What does this function? #80
Comments
@MadDogMayCry0 Underlying array in the hashmap only grows, it does not shrink. So, you want it shrink if many keys are deleted? It's not possible right now but we can add it, probably sc_map_init...() can accept another parameter, something like
|
@tezc
Yea, i want to a litle bit optimising an array after that, to speed up "foreach" :) |
struct sc_map_str map;
sc_map_init_str(&map, 0, 0);
sc_map_put_str(&map, "jack", "chicago");
sc_map_put_str(&map, "jane", "new york");
sc_map_put_str(&map, "janie", "atlanta");
printf("load factor :%f \n", (double) map.size / (double) map.cap); |
Are you sure this is a bottleneck? You may actually hurt performance by shrinking it. Shrinking takes some time and when you load data back, it needs to expand again, shrinking and expanding might consume more CPU cycles than just iterating on an array sequentially. So, just fyi, most softwares are okay without shrinking. People often want shrinking data structures to save some memory. |
I try to use it on ESP32 Microcontroller, and it's not the rest to optimizing something. I doing this only when array returns me 0 items inside of it, and app did deleted more as 1000 items before. if(sc_map_size_64s(&map) == 0){
//Refresh tree
sc_map_term_64s(&map);
sc_map_init_64s(&map, 0, 0);
} |
Ah okay I see, probably this is important in microcontroller world. I'll take a look later today, we can add auto shrinking without too much change anyway. |
@tezc |
@MadDogMayCry0 Sorry, couldn't finalize this. Looks like auto shrink brings some complexity and some performance overhead. (This hashmap is being used in a very performance sensitive apps). So, I need to take another look, hopefully this weekend. Meanwhile, I thought maybe we add another function So, situation is:
Meanwhile, maybe you can try that version in the PR. Is it good enough for your use case? This is the branch: https://github.com/tezc/sc/tree/map-shrink/map |
@tezc char tel[24];
char msg[256];
input_read(tel,msg);
sc_map_put_64s(&map, i,tel);
sc_map_put_64s(&arr, i,msg);
i++; and after uint32_t key;
const char *val;
sc_map_foreach (&arr, key, val) {
printf("%d %s\r\n",key,val);
} i have clones from last each input. For example 3 inputs and the last one was "sdjahf lkjsahdflkjhsadlfkjhsalkjd"
when i put input to const char * ptr; const char * ptr = malloc(strlen(msg)+1);
strcpy(ptr,msg);
sc_map_put_64s(&arr, ii,ptr); but now i got memory leak. Please tell me, how can I understand how many bytes I can put in a hash table, for example, with 100kb of RAM? I'm using a function that shows me the out of bounds, but I need to know how much more data i have before left. Thank you. |
@tezc char tel[24];
char msg[256];
input_read(tel,msg);
sc_map_put_64s(&map, i,tel);
sc_map_put_64s(&arr, i,msg);
i++; and after uint32_t key;
const char *val;
sc_map_foreach (&arr, key, val) {
printf("%d %s\r\n",key,val);
} i have clones from last each input. For example 3 inputs and the last one was "sdjahf lkjsahdflkjhsadlfkjhsalkjd"
when i put input to const char * ptr; const char * ptr = malloc(strlen(msg)+1);
strcpy(ptr,msg);
sc_map_put_64s(&arr, ii,ptr); but now i got memory leak. |
UPD. const char **ptr[1024]={0};
char msg[128];
usr_input(msg,128);
ptr[i] = (char*)malloc(strlen(msg)+1);
strcpy(ptr[i],msg);
sc_map_put_64s(&map, i, ptr[i]); and when i delete the element from SC i can free PTR value = sc_map_del_64s(&map, i);
free(ptr[i]); Do i right or is there a right way? |
Yes, looks like you were using stack allocated values and that was causing problems. Last snippet looks okay. I'd just check two things: See the if checks below: const char **ptr[1024]={0};
char msg[128];
usr_input(msg,128);
ptr[i] = (char*)malloc(strlen(msg)+1);
strcpy(ptr[i],msg);
prev_value = sc_map_put_64s(&map, i, ptr[i]);
if (sc_map_found(&map)) {
free(prev_value);
}
value = sc_map_del_64s(&map, i);
// Free the memory only if key `i` exists.
if (sc_map_found(&map)) {
free(ptr[i]);
} I don't know what you are trying to do but maybe you don't need ptr array at all: char msg[128];
usr_input(msg,128);
char *value = malloc(strlen(msg) + 1);
strcpy(value, msg);
char *prev_value = sc_map_put_64s(&map, i, value);
if (sc_map_found(&map)) {
// We are overwriting the key, free the value.
free(prev_value);
}
// -----------------------------
char *value = sc_map_del_64s(&map, i);
// Free the memory only if key `i` exists.
if (sc_map_found(&map)) {
free(value);
} |
@tezc void map_put(sc_map_64s *map,int key,char *val){
char *ptr = (char*)malloc(strlen(val)+1);
strcpy(ptr,val);
char * value = (char*)sc_map_put_64s(&map, key, ptr);
if (sc_map_found(&map)){
free(value);
}
} but i get error
Pls help :) |
void map_put(struct sc_map_64s *map, int key, char *val)
{
char *ptr = malloc(strlen(val) + 1);
strcpy(ptr, val);
char *value = (char *) sc_map_put_64s(map, key, ptr);
if (sc_map_found(map)) {
free(value);
}
} @MadDogMayCry0 You forgot |
@tezc sc_map_foreach(&port_list, key, val) {
break;
} did'nt works. 2 - it is possable somehow to get first element without to use foreach when key is not determined? |
@MadDogMayCry0 Oops, this is a bug :/ I see all our use cases either use Options: 1- const char *getFirstValue()
{
const char* key, val;
sc_map_foreach(&port_list, key, val) {
return val;
}
return NULL;
} 2- const char *getFirstValue()
{
const char* key, val;
sc_map_foreach(&port_list, key, val) {
goto found;
}
found:
return val;
} 3- I just wrote this fix but couldn't try it thoroughly(not sure if I broke anything else), maybe you can replace #define sc_map_foreach(map, K, V) \
for (int64_t __i = -1, __b = 0; !__b && __i < (map)->cap; __i++) \
for ((V) = (map)->mem[__i].value, (K) = (map)->mem[__i].key, \
__b = 1; \
__b && ((__i == -1 && (map)->used) || (K) != 0) ? 1 : (__b = 0); __b = 0) I'll take a look at this issue whenever I have some spare time. Until then, these workarounds should work. (sc_map_foreach(), sc_map_foreach_key(), sc_map_foreach_value(), all sufffer from this issue and needs to be fixed). Regarding, random element, it'd actually do same thing with the for each loop, so, if you wrap it similar to above, you can get a random element. Btw, just be sure map is the data structure you want. If you want to just get a random element, you can try a |
@tezc #define sc_map_foreach(map, K, V) \
for (int64_t __i = -1, __b = 0; !__b && __i < (map)->cap; __i++) \
for ((V) = (map)->mem[__i].value, (K) = (map)->mem[__i].key, \
__b = 1; \
__b && ((__i == -1 && (map)->used) || (K) != 0) ? 1 : (__b = 0); __b = 0) and return too. Thank You! |
@tezc
sc_map_remap_
???
What is the better way update memory usage after many attemtps with deliting and adding keys and values?
This time i try to use this sheme
but maby exists better way?
The text was updated successfully, but these errors were encountered: