mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-10 21:33:38 +00:00
Fixed on Linux, so db is opened exclusively, and fails/exits if it can't do it
Updated from SHA256 to SHA384 Added helper to see if db exist Fixed deprecation problem on windows Added an explicit unlock Added fix, to prevent memory corruption if a db record is corrupt
This commit is contained in:
@@ -119,14 +119,17 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
|
|||||||
char data[4096];
|
char data[4096];
|
||||||
char result[SHA384HASHSIZE];
|
char result[SHA384HASHSIZE];
|
||||||
int i, bytesLeft;
|
int i, bytesLeft;
|
||||||
ILibSimpleDataStore_RecordNode *node = (ILibSimpleDataStore_RecordNode*)(root->scratchPad );
|
ILibSimpleDataStore_RecordNode *node;
|
||||||
|
|
||||||
|
if (root == NULL) return NULL;
|
||||||
|
node = (ILibSimpleDataStore_RecordNode*)(root->scratchPad);
|
||||||
|
|
||||||
// If the current position is the end of the file, exit now.
|
// If the current position is the end of the file, exit now.
|
||||||
if (ILibSimpleDataStore_GetPosition(root->dataFile) == root->fileSize) { return NULL; }
|
if (ILibSimpleDataStore_GetPosition(root->dataFile) == root->fileSize) return NULL;
|
||||||
|
|
||||||
// Read sizeof(ILibSimpleDataStore_RecordNode) bytes to get record Size
|
// Read sizeof(ILibSimpleDataStore_RecordNode) bytes to get record Size
|
||||||
i = (int)fread((void*)node, 1, sizeof(ILibSimpleDataStore_RecordNode), root->dataFile);
|
i = (int)fread((void*)node, 1, sizeof(ILibSimpleDataStore_RecordNode), root->dataFile);
|
||||||
if (i < sizeof(ILibSimpleDataStore_RecordNode)) { return NULL; }
|
if (i < sizeof(ILibSimpleDataStore_RecordNode)) return NULL;
|
||||||
|
|
||||||
// Correct the struct, valueHash stays the same
|
// Correct the struct, valueHash stays the same
|
||||||
node->nodeSize = (int)ntohl(node->nodeSize);
|
node->nodeSize = (int)ntohl(node->nodeSize);
|
||||||
@@ -134,9 +137,15 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
|
|||||||
node->valueLength = (int)ntohl(node->valueLength);
|
node->valueLength = (int)ntohl(node->valueLength);
|
||||||
node->valueOffset = ILibSimpleDataStore_GetPosition(root->dataFile) + (DS_Long)node->keyLen;
|
node->valueOffset = ILibSimpleDataStore_GetPosition(root->dataFile) + (DS_Long)node->keyLen;
|
||||||
|
|
||||||
|
if (node->keyLen > (sizeof(ILibScratchPad) - sizeof(ILibSimpleDataStore_RecordNode)))
|
||||||
|
{
|
||||||
|
// Invalid record
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
// Read the key name
|
// Read the key name
|
||||||
i = (int)fread((char*)node + sizeof(ILibSimpleDataStore_RecordNode), 1, node->keyLen, root->dataFile);
|
i = (int)fread((char*)node + sizeof(ILibSimpleDataStore_RecordNode), 1, node->keyLen, root->dataFile);
|
||||||
if (i != node->keyLen) { return NULL; } // Reading Key Failed
|
if (i != node->keyLen) return NULL; // Reading Key Failed
|
||||||
|
|
||||||
// Validate Data, in 4k chunks at a time
|
// Validate Data, in 4k chunks at a time
|
||||||
bytesLeft = node->valueLength;
|
bytesLeft = node->valueLength;
|
||||||
@@ -154,9 +163,7 @@ ILibSimpleDataStore_RecordNode* ILibSimpleDataStore_ReadNextRecord(ILibSimpleDat
|
|||||||
if (node->valueLength > 0)
|
if (node->valueLength > 0)
|
||||||
{
|
{
|
||||||
// Check the hash
|
// Check the hash
|
||||||
if (memcmp(node->valueHash, result, SHA384HASHSIZE) == 0) {
|
if (memcmp(node->valueHash, result, SHA384HASHSIZE) == 0) { return node; } // Data is correct
|
||||||
return node; // Data is correct
|
|
||||||
}
|
|
||||||
return NULL; // Data is corrupt
|
return NULL; // Data is corrupt
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
@@ -180,6 +187,7 @@ void ILibSimpleDataStore_RebuildKeyTable(ILibSimpleDataStore_Root *root)
|
|||||||
ILibSimpleDataStore_RecordNode *node = NULL;
|
ILibSimpleDataStore_RecordNode *node = NULL;
|
||||||
ILibSimpleDataStore_TableEntry *entry;
|
ILibSimpleDataStore_TableEntry *entry;
|
||||||
|
|
||||||
|
if (root == NULL) return;
|
||||||
ILibHashtable_ClearEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root); // Wipe the key table, we will rebulit it
|
ILibHashtable_ClearEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root); // Wipe the key table, we will rebulit it
|
||||||
fseek(root->dataFile, 0, SEEK_SET); // See the start of the file
|
fseek(root->dataFile, 0, SEEK_SET); // See the start of the file
|
||||||
root->fileSize = -1; // Indicate we can't write to the data store
|
root->fileSize = -1; // Indicate we can't write to the data store
|
||||||
@@ -265,9 +273,16 @@ __EXPORT_TYPE ILibSimpleDataStore ILibSimpleDataStore_CreateEx(char* filePath, i
|
|||||||
__EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore)
|
__EXPORT_TYPE void ILibSimpleDataStore_Close(ILibSimpleDataStore dataStore)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
|
|
||||||
|
if (root == NULL) return;
|
||||||
ILibHashtable_DestroyEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root);
|
ILibHashtable_DestroyEx(root->keyTable, ILibSimpleDataStore_TableClear_Sink, root);
|
||||||
|
|
||||||
free(root->filePath);
|
free(root->filePath);
|
||||||
|
|
||||||
|
#ifdef _POSIX
|
||||||
|
flock(fileno(root->dataFile), LOCK_UN);
|
||||||
|
#endif
|
||||||
|
|
||||||
fclose(root->dataFile);
|
fclose(root->dataFile);
|
||||||
free(root);
|
free(root);
|
||||||
}
|
}
|
||||||
@@ -277,7 +292,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_PutEx(ILibSimpleDataStore dataStore, char*
|
|||||||
{
|
{
|
||||||
char hash[SHA384HASHSIZE];
|
char hash[SHA384HASHSIZE];
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
|
ILibSimpleDataStore_TableEntry *entry;
|
||||||
|
|
||||||
|
if (root == NULL) return 0;
|
||||||
|
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
|
||||||
ILibSimpleDataStore_SHA384(value, valueLen, hash); // Hash the value
|
ILibSimpleDataStore_SHA384(value, valueLen, hash); // Hash the value
|
||||||
|
|
||||||
// Create a new record for the key and value
|
// Create a new record for the key and value
|
||||||
@@ -301,7 +319,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_GetEx(ILibSimpleDataStore dataStore, char*
|
|||||||
{
|
{
|
||||||
char hash[SHA384HASHSIZE];
|
char hash[SHA384HASHSIZE];
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
|
ILibSimpleDataStore_TableEntry *entry;
|
||||||
|
|
||||||
|
if (root == NULL) return 0;
|
||||||
|
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
|
||||||
|
|
||||||
if (entry == NULL) return 0; // If there is no in-memory entry for this key, return zero now.
|
if (entry == NULL) return 0; // If there is no in-memory entry for this key, return zero now.
|
||||||
if ((buffer != NULL) && (bufferLen >= entry->valueLength)) // If the buffer is not null and can hold the value, place the value in the buffer.
|
if ((buffer != NULL) && (bufferLen >= entry->valueLength)) // If the buffer is not null and can hold the value, place the value in the buffer.
|
||||||
@@ -319,7 +340,10 @@ __EXPORT_TYPE int ILibSimpleDataStore_GetEx(ILibSimpleDataStore dataStore, char*
|
|||||||
__EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
|
__EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
|
ILibSimpleDataStore_TableEntry *entry;
|
||||||
|
|
||||||
|
if (root == NULL) return NULL;
|
||||||
|
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Get(root->keyTable, NULL, key, keyLen);
|
||||||
|
|
||||||
if (entry == NULL) return NULL; // If there is no in-memory entry for this key, return zero now.
|
if (entry == NULL) return NULL; // If there is no in-memory entry for this key, return zero now.
|
||||||
return entry->valueHash;
|
return entry->valueHash;
|
||||||
@@ -329,7 +353,10 @@ __EXPORT_TYPE char* ILibSimpleDataStore_GetHashEx(ILibSimpleDataStore dataStore,
|
|||||||
__EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
|
__EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, char* key, int keyLen)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
ILibSimpleDataStore_TableEntry *entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Remove(root->keyTable, NULL, key, keyLen);
|
ILibSimpleDataStore_TableEntry *entry;
|
||||||
|
|
||||||
|
if (root == NULL) return 0;
|
||||||
|
entry = (ILibSimpleDataStore_TableEntry*)ILibHashtable_Remove(root->keyTable, NULL, key, keyLen);
|
||||||
if (entry != NULL) { ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, NULL, 0, NULL); free(entry); return 1; }
|
if (entry != NULL) { ILibSimpleDataStore_WriteRecord(root->dataFile, key, keyLen, NULL, 0, NULL); free(entry); return 1; }
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -338,6 +365,7 @@ __EXPORT_TYPE int ILibSimpleDataStore_DeleteEx(ILibSimpleDataStore dataStore, ch
|
|||||||
__EXPORT_TYPE void ILibSimpleDataStore_Lock(ILibSimpleDataStore dataStore)
|
__EXPORT_TYPE void ILibSimpleDataStore_Lock(ILibSimpleDataStore dataStore)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
|
if (root == NULL) return;
|
||||||
ILibHashtable_Lock(root->keyTable);
|
ILibHashtable_Lock(root->keyTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +373,7 @@ __EXPORT_TYPE void ILibSimpleDataStore_Lock(ILibSimpleDataStore dataStore)
|
|||||||
__EXPORT_TYPE void ILibSimpleDataStore_UnLock(ILibSimpleDataStore dataStore)
|
__EXPORT_TYPE void ILibSimpleDataStore_UnLock(ILibSimpleDataStore dataStore)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
|
if (root == NULL) return;
|
||||||
ILibHashtable_UnLock(root->keyTable);
|
ILibHashtable_UnLock(root->keyTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -361,6 +390,7 @@ void ILibSimpleDataStore_Compact_EnumerateSink(ILibHashtable sender, void *Key1,
|
|||||||
int totalBytesWritten = 0;
|
int totalBytesWritten = 0;
|
||||||
int bytesWritten = 0;
|
int bytesWritten = 0;
|
||||||
|
|
||||||
|
if (root == NULL) return;
|
||||||
if (root->error != 0) return; // There was an error, ABORT!
|
if (root->error != 0) return; // There was an error, ABORT!
|
||||||
|
|
||||||
offset = ILibSimpleDataStore_WriteRecord(compacted, Key2, Key2Len, NULL, entry->valueLength, entry->valueHash);
|
offset = ILibSimpleDataStore_WriteRecord(compacted, Key2, Key2Len, NULL, entry->valueLength, entry->valueHash);
|
||||||
@@ -410,7 +440,8 @@ __EXPORT_TYPE void ILibSimpleDataStore_EnumerateKeys(ILibSimpleDataStore dataSto
|
|||||||
{
|
{
|
||||||
void* users[3];
|
void* users[3];
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
|
if (root == NULL) return;
|
||||||
|
|
||||||
users[0] = (void*)handler;
|
users[0] = (void*)handler;
|
||||||
users[1] = (void*)dataStore;
|
users[1] = (void*)dataStore;
|
||||||
users[2] = (void*)user;
|
users[2] = (void*)user;
|
||||||
@@ -422,13 +453,16 @@ __EXPORT_TYPE void ILibSimpleDataStore_EnumerateKeys(ILibSimpleDataStore dataSto
|
|||||||
__EXPORT_TYPE int ILibSimpleDataStore_Compact(ILibSimpleDataStore dataStore)
|
__EXPORT_TYPE int ILibSimpleDataStore_Compact(ILibSimpleDataStore dataStore)
|
||||||
{
|
{
|
||||||
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
ILibSimpleDataStore_Root *root = (ILibSimpleDataStore_Root*)dataStore;
|
||||||
char* tmp = ILibString_Cat(root->filePath, -1, ".tmp", -1); // Create the name of the temporary data store
|
char* tmp;
|
||||||
FILE* compacted;
|
FILE* compacted;
|
||||||
void* state[2];
|
void* state[2];
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
|
if (root == NULL) return 1; // Error
|
||||||
|
tmp = ILibString_Cat(root->filePath, -1, ".tmp", -1); // Create the name of the temporary data store
|
||||||
|
|
||||||
// Start by opening a temporary .tmp file. Will be used to write the compacted data store.
|
// Start by opening a temporary .tmp file. Will be used to write the compacted data store.
|
||||||
if ((compacted = ILibSimpleDataStore_OpenFileEx(tmp, 1)) == NULL) { free(tmp); return 1; }
|
if ((compacted = ILibSimpleDataStore_OpenFileEx(tmp, 1)) == NULL) { free(tmp); return 1; }
|
||||||
|
|
||||||
// Enumerate all keys and write them all into the temporary data store
|
// Enumerate all keys and write them all into the temporary data store
|
||||||
state[0] = root;
|
state[0] = root;
|
||||||
|
|||||||
Reference in New Issue
Block a user