kolibrios-fun/programs/cmm/lib/array.h
Kirill Lipatov (Leency) 8d15602e0a cmm/lib/collection: remove restriction of maximum elements
webview: remove restriction of links count
eolite: remove restriction of max elements in list + 6 times speed up the open of big folders!

git-svn-id: svn://kolibrios.org@7972 a494cfbc-eb01-0410-851d-a64ba20cac60
2020-05-23 11:26:58 +00:00

186 lines
4.1 KiB
C

// Author: Pavel Iakovlev by. pavelyakov
#ifndef INCLUDE_ARRAY_H
#define INCLUDE_ARRAY_H
#include "../lib/crc32.h"
// Array memory: [dword key][byte flags][dword left][dword right][dword value] -> 17 bytes = 1 position
// If key don't exists then value == 0
:struct Array
{
dword memory;
dword offsetMemory;
dword lenInitSize;
dword recursiveIndex(dword i, address);
byte set(dword key, data);
dword get(dword key);
void reallocMemory(dword newSize);
//dword del(dword key);
byte init(dword size);
};
:void Array::reallocMemory(dword newSize)
{
newSize *= 17;
memory = realloc(memory, newSize);
lenInitSize = newSize;
}
:dword Array::recursiveIndex(dword key, address)
{
dword flags = 0;
IF (DSDWORD[address] == key) RETURN address;
flags = DSBYTE[address + 4];
//IF (flags & 100b) RETURN address; // if delete
IF (flags & 010b) && (DSDWORD[address] < key) RETURN recursiveIndex(key, DSDWORD[address + 5]); // left tree
IF (flags & 001b) && (DSDWORD[address] > key) RETURN recursiveIndex(key, DSDWORD[address + 9]); // right tree
RETURN address;
}
:byte Array::init(dword size)
{
dword pointer = 0;
if (!size) size = 240;
IF(!memory)
{
lenInitSize = size * 17;
memory = malloc(lenInitSize);
pointer = memory;
DSDWORD[pointer] = 0; pointer += 4;
DSBYTE[pointer] = 0; pointer += 1;
DSDWORD[pointer] = 0;pointer += 4;
DSDWORD[pointer] = 0;pointer += 4;
DSDWORD[pointer] = 0;
offsetMemory = 17;
RETURN 0xFF;
}
IF(size > lenInitSize)
{
reallocMemory(size);
RETURN 0xFF;
}
RETURN 0;
}
:byte Array::set(dword key, data)
{
dword address = 0;
dword newOffset = 0;
IF(offsetMemory > lenInitSize) reallocMemory(offsetMemory << 1);
address = recursiveIndex(key, memory);
/*IF(DSBYTE[address + 4] & 100b)
{
IF(DSDWORD[address] < key)
{
DSBYTE[address + 4] |= 10b;
DSDWORD[address + 5] = newOffset;
}
ELSE IF(DSDWORD[address] > key)
{
DSBYTE[address + 4] |= 01b;
DSDWORD[address + 9] = newOffset;
}
ELSE
{
DSDWORD[address + 13] = data;
RETURN 0xFF;
}
}*/
newOffset = memory + offsetMemory;
IF(DSDWORD[address] < key)
{
DSBYTE[address + 4] |= 010b; // set flag left address
DSDWORD[address + 5] = newOffset;
}
ELSE IF(DSDWORD[address] > key)
{
DSBYTE[address + 4] |= 001b; // set flag right address
DSDWORD[address + 9] = newOffset;
}
ELSE
{
DSDWORD[address + 13] = data;
RETURN 0xFF;
}
DSDWORD[newOffset] = key; newOffset+=4;
DSBYTE[newOffset] = 0; newOffset+=1;
DSDWORD[newOffset] = 0; newOffset+=4;
DSDWORD[newOffset] = 0; newOffset+=4;
DSDWORD[newOffset] = data;
offsetMemory += 17;
RETURN 0xFF;
}
:dword Array::get(dword key)
{
EBX = recursiveIndex(key, memory);
IF(DSDWORD[EBX] != key) RETURN 0;
IF(DSBYTE[EBX + 4] & 100b) RETURN 0;
RETURN DSDWORD[EBX + 13];
}
/*:dword Array::del(dword key)
{
dword address = 0;
address = recursiveIndex(key, memory);
IF(DSDWORD[address] != key) RETURN 0;
DSBYTE[address + 4] |= 100b;
RETURN 0xFF;
}*/
:struct Dictionary
{
Array array;
dword hash(dword text);
byte set(dword key, value);
dword get(dword key);
byte init(dword size);
};
:dword Dictionary::hash(dword text)
{
RETURN crc32(text, strlen(text));
/*
dword checkSum1 = 1;
dword checkSum2 = 0;
dword beginAddress = 0;
beginAddress = text;
WHILE(DSBYTE[text])
{
checkSum1 += DSBYTE[text];
checkSum2 += checkSum1;
text++;
}
//IF(h1 > 0x03FFF) RETURN h1 << 8 ^ h2;
//IF(h2 > 0x3FFFF) RETURN h1 << 8 ^ h2;
EAX = text - beginAddress;
EAX <<= 23;
RETURN EAX | checkSum2;
*/
}
:byte Dictionary::set(dword key, value)
{
RETURN array.set(hash(key),value);
}
:dword Dictionary::get(dword key)
{
RETURN array.get(hash(key));
}
:byte Dictionary::init(dword size)
{
RETURN array.init(size);
}
:dword indexArray(dword address, key)
{
dword offset = key&0x1FF;
dword offsetAddress = offset*4+address;
IF (key==offset) RETURN 4*0x200+offsetAddress;
IF (!DSDWORD[offsetAddress]) DSDWORD[offsetAddress] = malloc(0x1000);
RETURN indexArray(DSDWORD[offsetAddress], key>>9);
}
#endif