Skip to content

Commit a3b80d4

Browse files
committed
Add skeleton and utils for hashmap library
1 parent 43c5610 commit a3b80d4

10 files changed

Lines changed: 890 additions & 2 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* @vm_libhashmap.c
3+
*
4+
* @brief Stack VM
5+
* @details
6+
* This is based on other projects:
7+
* Tiny language: https://github.com/goodpaul6/Tiny
8+
* Others (see individual files)
9+
*
10+
* please contact their authors for more information.
11+
*
12+
* @author Emiliano Augusto Gonzalez (egonzalez . hiperion @ gmail . com)
13+
* @version 2.0
14+
* @date 2024
15+
* @copyright MIT License
16+
* @see https://github.com/hiperiondev/stack_vm
17+
*/
18+
19+
#include <stdlib.h>
20+
21+
#include "hashtable.h"
22+
#include "vm_libhashmap.h"
23+
#include "vm.h"
24+
25+
vm_errors_t lib_entry_hashtable(vm_thread_t **thread, uint8_t call_type, uint32_t lib_idx, uint32_t arg) {
26+
if (*thread == NULL)
27+
return VM_ERR_FAIL;
28+
29+
vm_errors_t res = VM_ERR_OK;
30+
switch (call_type) {
31+
// vm cases
32+
case VM_EDFAT_NEW: {
33+
NEW_HEAP_REF(obj, arg);
34+
obj->lib_obj.addr = NULL;
35+
obj->lib_obj.identifier = HASHTABLE_LIBRARY_IDENTIFIER;
36+
STKDROPSND(thread);
37+
}
38+
break;
39+
40+
case VM_EDFAT_PUSH: {
41+
42+
}
43+
break;
44+
45+
case VM_EDFAT_CMP: {
46+
47+
}
48+
break;
49+
50+
case VM_EDFAT_GC: {
51+
free(vm_heap_load((*thread)->heap, arg)->lib_obj.addr);
52+
}
53+
break;
54+
55+
case VM_EDFAT_TOTYPE: {
56+
57+
}
58+
break;
59+
}
60+
61+
return res;
62+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* @vm_libhashmap.h
3+
*
4+
* @brief Stack VM
5+
* @details
6+
* This is based on other projects:
7+
* Tiny language: https://github.com/goodpaul6/Tiny
8+
* Others (see individual files)
9+
*
10+
* please contact their authors for more information.
11+
*
12+
* @author Emiliano Augusto Gonzalez (egonzalez . hiperion @ gmail . com)
13+
* @version 2.0
14+
* @date 2024
15+
* @copyright MIT License
16+
* @see https://github.com/hiperiondev/stack_vm
17+
*/
18+
19+
20+
#ifndef VM_LIBHASHMAP_H_
21+
#define VM_LIBHASHMAP_H_
22+
23+
#include "hashtable.h"
24+
#include "vm.h"
25+
26+
#define HASHTABLE_LIBRARY_IDENTIFIER 0x00000010
27+
28+
vm_errors_t lib_entry_hashtable(vm_thread_t **thread, uint8_t call_type, uint32_t lib_idx, uint32_t arg);
29+
30+
#endif /* VM_LIBHASHMAP_H_ */

vm_libraries/libstring/vm_libstring.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* @libstring.c
2+
* @vm_libstring.c
33
*
44
* @brief Stack VM
55
* @details

vm_libraries/libstring/vm_libstring.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* @libstring.h
2+
* @vm_libstring.h
33
*
44
* @brief Stack VM
55
* @details

vm_libraries/utils/hashtable.c

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/*
2+
* @hashtable.c
3+
*
4+
* @brief Stack VM
5+
* @details
6+
* This is based on other projects:
7+
* https://github.com/r-bauer/hashTable
8+
*
9+
* please contact their authors for more information.
10+
*
11+
* @author Emiliano Augusto Gonzalez (egonzalez . hiperion @ gmail . com)
12+
* @date 2024
13+
* @copyright MIT License
14+
* @see https://github.com/hiperiondev/stack_vm
15+
*/
16+
17+
#include <stdint.h>
18+
#include <stdbool.h>
19+
#include <math.h>
20+
#include <stddef.h>
21+
#include <stdio.h>
22+
#include <stdlib.h>
23+
24+
#include "linked_list.h"
25+
#include "hashtable.h"
26+
27+
/////// HASHING //////
28+
29+
static uint16_t HashDiv(uint32_t dwKey, int iSize) {
30+
return (uint16_t) (dwKey % iSize);
31+
}
32+
33+
static uint16_t HashMul(uint32_t dwKey, int iSize) {
34+
double dFrac;
35+
36+
dFrac = fmod(dwKey * 0.618, 1);
37+
38+
return (uint16_t) (iSize * dFrac);
39+
}
40+
41+
static uint32_t HashElf(const uint8_t *ptrData, int iLen) {
42+
uint32_t dwKey = 0, dwTmp;
43+
44+
for (; iLen > 0; --iLen) {
45+
dwKey = (dwKey << 4) + *ptrData++;
46+
if ((dwTmp = dwKey & 0xF0000000))
47+
dwKey ^= dwTmp >> 24;
48+
dwKey &= ~dwTmp;
49+
}
50+
51+
return dwKey;
52+
}
53+
54+
uint16_t HashData(hashtable_t *pHT, void *pData) {
55+
uint32_t dwKey;
56+
uint16_t wIndex;
57+
uint16_t (*fHash)(uint32_t, int);
58+
59+
dwKey = HashElf(pData, pHT->fDataLen(pData));
60+
fHash = (pHT->iSize & 1) ? HashDiv : HashMul;
61+
wIndex = fHash(dwKey, pHT->iSize);
62+
63+
return wIndex;
64+
}
65+
66+
static bool CreateTable(node_t* **ptrTable, int iSize) {
67+
*ptrTable = calloc(iSize, sizeof(node_t*));
68+
69+
return (*ptrTable == NULL ? false : true);
70+
}
71+
72+
////////////////////
73+
74+
hashtable_t* InitHashTable(void* (*fCreateData)(void*), bool (*fDeleteData)(void*), uint32_t (*fDuplicatedNode)(node_t*, node_t*),
75+
uint32_t (*fNodeDataCmp)(void*, void*), uint32_t iTableSize, uint32_t (*fDataLen)(void*)) {
76+
hashtable_t *pHT = NULL;
77+
78+
pHT = (hashtable_t*) malloc(sizeof(hashtable_t));
79+
80+
if (pHT) {
81+
pHT->iSize = iTableSize;
82+
pHT->fDataLen = fDataLen;
83+
84+
if (CreateTable(&pHT->ptrTable, pHT->iSize)) {
85+
pHT->ptrList = CreateLList(fCreateData, fDeleteData, fDuplicatedNode, fNodeDataCmp);
86+
87+
if (pHT->ptrList) {
88+
return (pHT);
89+
} else {
90+
free(pHT->ptrTable);
91+
}
92+
}
93+
}
94+
95+
free(pHT);
96+
97+
return NULL;
98+
}
99+
100+
bool AddDataToTable(hashtable_t *pHT, void *pData) {
101+
uint16_t wIndex;
102+
103+
if (pHT == NULL)
104+
return false;
105+
106+
wIndex = HashData(pHT, pData);
107+
pHT->ptrList->slkHead = pHT->ptrTable[wIndex];
108+
109+
if (AddNodeAscend(pHT->ptrList, pData) == false)
110+
return false;
111+
112+
pHT->ptrTable[wIndex] = pHT->ptrList->slkHead;
113+
114+
return true;
115+
}
116+
117+
node_t* FindDataInTable(hashtable_t *pHT, void *pData) {
118+
uint16_t wIndex;
119+
void *pInfo;
120+
node_t* slk;
121+
122+
if (pHT == NULL)
123+
return NULL;
124+
125+
wIndex = HashData(pHT, pData);
126+
pHT->ptrList->slkHead = pHT->ptrTable[wIndex];
127+
pInfo = pHT->ptrList->fCreateData(pData);
128+
slk = FindNodeAscend(pHT->ptrList, pInfo);
129+
pHT->ptrList->fDeleteData(pInfo);
130+
131+
return slk;
132+
}
133+
134+
bool DelDataInTable(hashtable_t *pHT, void *pData) {
135+
uint16_t wIndex;
136+
void *pInfo;
137+
node_t* slk;
138+
bool bOk;
139+
140+
wIndex = HashData(pHT, pData);
141+
pHT->ptrList->slkHead = pHT->ptrTable[wIndex];
142+
pInfo = pHT->ptrList->fCreateData(pData);
143+
slk = FindNodeAscend(pHT->ptrList, pInfo);
144+
pHT->ptrList->fDeleteData(pInfo);
145+
146+
if (slk) {
147+
if (slk->prior == NULL)
148+
slk = pHT->ptrList->slkHead;
149+
150+
if (slk->next == NULL)
151+
slk = pHT->ptrList->slkTail;
152+
153+
bOk = DeleteNode(pHT->ptrList, slk);
154+
pHT->ptrTable[wIndex] = pHT->ptrList->slkHead;
155+
} else
156+
bOk = false;
157+
158+
return bOk;
159+
}
160+
161+
bool EndHashTable(hashtable_t *pHT) {
162+
int iCnt;
163+
node_t* pCurr, *pBak;
164+
165+
if (pHT == NULL)
166+
return false;
167+
168+
for (iCnt = 0; iCnt < pHT->iSize; ++iCnt) {
169+
pCurr = pHT->ptrList->slkHead = pHT->ptrTable[iCnt];
170+
171+
if (pCurr != NULL) {
172+
while (pCurr != NULL) {
173+
pBak = pCurr;
174+
pCurr = pCurr->next;
175+
if (pCurr == NULL)
176+
pHT->ptrList->slkTail = pBak;
177+
DeleteNode(pHT->ptrList, pBak);
178+
}
179+
}
180+
}
181+
182+
free(pHT->ptrList);
183+
free(pHT);
184+
185+
return true;
186+
}

vm_libraries/utils/hashtable.h

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* @hashtable.h
3+
*
4+
* @brief Stack VM
5+
* @details
6+
* This is based on other projects:
7+
* https://github.com/r-bauer/hashTable
8+
*
9+
* please contact their authors for more information.
10+
*
11+
* @author Emiliano Augusto Gonzalez (egonzalez . hiperion @ gmail . com)
12+
* @date 2024
13+
* @copyright MIT License
14+
* @see https://github.com/hiperiondev/stack_vm
15+
*/
16+
17+
#ifndef __HASHTABLE_H__
18+
#define __HASHTABLE_H__
19+
20+
#include <stdint.h>
21+
#include <stdbool.h>
22+
23+
#include "linked_list.h"
24+
25+
/**
26+
* @struct hashtable_s
27+
* @brief Chained hash table
28+
*
29+
*/
30+
typedef struct hashtable_s {
31+
list_t *ptrList;
32+
node_t* *ptrTable;
33+
uint32_t iSize;
34+
uint32_t (*fDataLen)(void*);
35+
} hashtable_t;
36+
37+
/**
38+
* @fn hashtable_t* InitHashTable(void* (*fCreateData)(void*), bool (*fDeleteData)(void*), uint32_t (*fDuplicatedNode)(node_t*, node_t*), uint32_t (*fNodeDataCmp)(void*, void*), uint32_t iTableSize, uint32_t (*fDataLen)(void*))
39+
* @brief
40+
*
41+
* @param fCreateData Creates data
42+
* @param fDeleteData Delete data
43+
* @param fDuplicatedNode Duplicate data
44+
* @param fNodeDataCmp Compare data
45+
* @param iTableSize Table size
46+
* @param fDataLen Data size
47+
* @return Table pointer
48+
*/
49+
hashtable_t* InitHashTable(void* (*fCreateData)(void*), bool (*fDeleteData)(void*), uint32_t (*fDuplicatedNode)(node_t*, node_t*), uint32_t (*fNodeDataCmp)(void*, void*), uint32_t iTableSize, uint32_t (*fDataLen)(void*));
50+
51+
/**
52+
* @fn bool AddDataToTable(hashtable_t*, void*)
53+
* @brief
54+
*
55+
* @param pHT
56+
* @param pData
57+
* @return
58+
*/
59+
bool AddDataToTable(hashtable_t *pHT, void *pData);
60+
61+
/**
62+
* @fn node_t FindDataInTable*(hashtable_t*, void*)
63+
* @brief
64+
*
65+
* @param
66+
* @param
67+
* @return
68+
*/
69+
node_t* FindDataInTable(hashtable_t*, void*);
70+
71+
/**
72+
* @fn bool DelDataInTable(hashtable_t*, void*)
73+
* @brief
74+
*
75+
* @param pHT
76+
* @param pData
77+
* @return
78+
*/
79+
bool DelDataInTable(hashtable_t *pHT, void *pData);
80+
81+
/**
82+
* @fn bool EndHashTable(hashtable_t*)
83+
* @brief
84+
*
85+
* @param pHT
86+
* @return
87+
*/
88+
bool EndHashTable(hashtable_t *pHT);
89+
90+
#endif /* __HASHTABLE_H__ */

0 commit comments

Comments
 (0)