79 Commits

Author SHA1 Message Date
38a339fb1c Tagged 1.71 2006-07-19 20:14:28 +00:00
8a2d750970 removed some amd64 files :o 2006-04-03 02:42:20 +00:00
46b70bdfba updated to April 2006-04-02 19:27:18 +00:00
15e137e266 time test 2006-04-02 18:50:35 +00:00
93c8bd0253 fixed potential exploit (thanks twisted) 2006-04-01 05:50:33 +00:00
10a935790c a clean yam is a happy yam. 2006-03-31 21:59:52 +00:00
68208d73d7 made sure vars are reset 2006-03-30 20:45:22 +00:00
b57367dd30 abort() now cancels a callfunc 2006-03-30 20:42:11 +00:00
9eb9839a46 bumped version numbers 2006-03-30 04:25:57 +00:00
deccf7816c added rmdir() 2006-03-30 00:48:58 +00:00
fe971497cc synced to dll 2006-03-30 00:31:45 +00:00
8c2be55233 added ClientUserInfoChanged forward 2006-03-30 00:31:33 +00:00
ab443e8254 fixed a few buffer overflow errors 2006-03-30 00:13:38 +00:00
16e53eded8 synced to dll 2006-03-29 23:57:54 +00:00
a7acf05bfc added more strings 2006-03-29 23:57:42 +00:00
5e22cd5f0a Fixed bug at27323 (AndraX2000) 2006-03-29 23:33:38 +00:00
92be7f6791 synced to core 2006-03-29 22:58:11 +00:00
94c449936d added getc,ungetc,putc 2006-03-29 22:56:18 +00:00
89c58265aa page numbering does not appear with no pages 2006-03-29 22:48:45 +00:00
3783e34a70 Fixed a bug where handlers wouldn't work if they were in the 0th slot 2006-03-29 22:42:03 +00:00
414ecdfffa fixed crash when creating a new binlog file 2006-03-24 19:29:49 +00:00
76afa40270 fixed bug 2006-03-23 15:01:15 +00:00
17bbc37638 fixed binlog max size name 2006-03-23 10:11:09 +00:00
4b0b3c0c7c bumped version 2006-03-20 22:58:27 +00:00
006b4bd49a added syncpoints to all stats scripts 2006-03-20 19:40:58 +00:00
5395fc1280 updated constants 2006-03-20 19:36:57 +00:00
a293e23fe2 renamed time to gl_time
updated makefile
2006-03-20 18:45:53 +00:00
68e729721d ~(, ,)o <-- wtf another turtle?! 2006-03-20 18:38:29 +00:00
4f5c16c278 added support for new tr and kvd hooking/calling 2006-03-20 18:23:03 +00:00
c15a86b454 added new TR/KVD stuffs 2006-03-20 18:08:51 +00:00
51c8724cff added more hud syncpoints 2006-03-20 01:43:44 +00:00
ccb3b4fbb3 experimental fix for improving hud sync 2006-03-20 01:03:30 +00:00
83bf0d7b2a ~(, ,)o <-- turtle 2006-03-19 21:52:25 +00:00
f55a8c54cc binlog reader no longer logs plugin database in a separate file 2006-03-19 21:41:11 +00:00
dc9350fcc5 committed changes for new file format 2006-03-19 21:40:24 +00:00
ef5437fec3 a working adminslots 2006-03-19 21:25:18 +00:00
0999db0203 fixed bug at26073 2006-03-19 20:48:37 +00:00
d84ef62e6c little optimization from PM 2006-03-19 20:39:25 +00:00
b5e8bc9ec1 fixed bug at26868 2006-03-19 20:14:24 +00:00
ccaa4434ad committed new language code 2006-03-19 19:26:29 +00:00
555ac1c7f3 fixed corrupt file loads smashing the stack
added compile of support code
2006-03-18 22:10:05 +00:00
b9788b7e1b *** empty log message *** 2006-03-18 21:38:28 +00:00
c6e332a0f5 linux+amd64 compat 2006-03-18 20:59:38 +00:00
007d41b5af Bumped version number to 1.71
Added a hint concerning binary logging to metamod's plugins.ini
2006-03-18 20:03:34 +00:00
a1956bc83b added cpuid helper func 2006-03-18 08:56:58 +00:00
ff61158491 fix for binary db not being created on maxsize overflow 2006-03-17 23:29:33 +00:00
2c5520cad0 added optimization tweaker
added binary log maxsize support
2006-03-17 22:50:13 +00:00
4bcb0fcb13 new localinfo crap 2006-03-17 22:10:16 +00:00
6ef670878d committed binary 2006-03-17 18:26:21 +00:00
89e13334ae uses stringbuilder instead of alloc+concat for speed now 2006-03-16 19:29:46 +00:00
82fe1e10d9 Fleshed out log and database readers, began basics of GUI 2006-03-16 06:40:18 +00:00
e067a980be implemented a lot more binary opcodes
bumped versions
2006-03-16 06:36:01 +00:00
e98fbc47e8 added new binary logging option 2006-03-16 04:36:55 +00:00
b6fa60b0bd Modified to fix memory leaks and improve speed 2006-03-16 02:11:48 +00:00
7e97156fc4 added arrayset native 2006-03-16 00:13:13 +00:00
7190d933b4 fixed bug at26204 2006-03-15 16:14:32 +00:00
3699796bc6 finalized file format
added register op (working)
added msvc8 stuff (4better || 4worse)
2006-03-15 13:43:06 +00:00
e208ff0664 quick import of file structure 2006-03-15 13:42:25 +00:00
adc2a7d169 initial import of binary logger support code 2006-03-14 19:36:18 +00:00
dc8e162e26 added menu_cancel 2006-03-14 17:50:38 +00:00
522511d059 implemented menu_cancel 2006-03-14 17:49:29 +00:00
d5152fedc4 added glb.cpp 2006-03-14 17:21:35 +00:00
d7bef2ae4b added get_global() 2006-03-14 17:15:52 +00:00
9283cbe1c2 added request at26450 2006-03-14 16:55:06 +00:00
7dae023a98 fixed bug at26580 2006-03-14 10:01:35 +00:00
9c88ce1394 fixed bug at26581 2006-03-14 09:59:28 +00:00
4cb8d4adc7 *** empty log message *** 2006-03-14 02:54:54 +00:00
5c88803942 New update! 3.1 is liiiive!
Error handling:
Array now has sufficiently advanced error handling to remove most, if not all, disable_checks.

Extention:
With the metaprogramming techniques, new types can be added easily.

Speed:
With the new changes I've made to Judy, the Array module has far exceeded the speed of any traditional datatype
2006-03-14 02:54:24 +00:00
4457b0d879 Obsolete due to update 2006-03-14 02:50:30 +00:00
58415dcfb9 Obsolete due to new updates 2006-03-14 02:49:02 +00:00
76c216d07e added request at26533 (Brad) 2006-03-13 22:43:55 +00:00
aa3582a2f3 removed patch for autochanneler (bug at26176) 2006-03-13 14:37:23 +00:00
d80b59e639 vers bump 2006-03-13 14:35:46 +00:00
880cb401fb fixed bug at26340 (NiLuJe) 2006-03-13 14:35:26 +00:00
2e0dcb860a fixed dynamic ExecuteForward not returning a valid result and patching the forward id 2006-03-10 19:04:04 +00:00
a9684fb81d fixed bug at26189 2006-03-07 12:58:39 +00:00
f2b8b82515 Component update (whoa I hate delphi reinstallations)
Added another feature for the Code-Explorer
2006-03-06 19:47:22 +00:00
eb7a49f6d4 fixed awful cvar bug, amx_reservedslots (which wasn't registered by the plugin) was used in the code instead of amx_reservation 2006-03-06 15:27:30 +00:00
982b22ab20 fixed bug in split() 2006-03-06 14:54:12 +00:00
276 changed files with 10338 additions and 74899 deletions

View File

@ -31,6 +31,7 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "debugger.h" #include "debugger.h"
#include "binlog.h"
CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes) CForward::CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam *paramTypes)
{ {
@ -124,6 +125,9 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
// exec // exec
cell retVal; cell retVal;
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
#endif
int err = amx_Exec(amx, &retVal, iter->func); int err = amx_Exec(amx, &retVal, iter->func);
// log runtime error, if any // log runtime error, if any
@ -284,6 +288,9 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
// exec // exec
cell retVal; cell retVal;
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
#endif
int err = amx_Exec(m_Amx, &retVal, m_Func); int err = amx_Exec(m_Amx, &retVal, m_Func);
if (err != AMX_ERR_NONE) if (err != AMX_ERR_NONE)

View File

@ -47,41 +47,6 @@
#define INSERT_STRING 3 #define INSERT_STRING 3
#define INSERT_NEWLINE 4 #define INSERT_NEWLINE 4
// dictionary format is Fast-Format-Hash-Lookup, v6
#define MAGIC_HDR 0x4646484C
#define FFHL_VERSION 6
#define FFHL_MIN_VERSION 6
/*version history:
* 1 (BAILOPAN) - Simplest form possible, no reverse
* 2 (BAILOPAN) - One language per file with full reverse
* 3 (PM OnoTo) - 2^32 languages per file with full reverse
* 4 (BAILOPAN) - Optimized by separating and relocating tables (normalization)
* 5 (BAILOPAN) - Removed hash storage
* 6 (BAILOPAN) - Arbitrary bump to force reparse.
FORMAT:
Magic 4bytes
Version 1byte
Number of Keys 4bytes
Number of Languages 4bytes
LANG INFO TABLE[]
Language Name 2bytes
Offset 4bytes
KEY TABLE[]
Key Lookup Offset 4bytes
LANGUAGES TABLE[]
Language[]
Definitions 4bytes
Key # 4bytes (0-index into key table)
Def Offset 4bytes
KEY LOOKUP TABLE[]
Key length 1byte
Key string variable
DEF LOOKUP TABLE[]
Def length 2bytes
Def string variable
*/
template<> template<>
int Compare<String>(const String &k1, const String &k2) int Compare<String>(const String &k1, const String &k2)
{ {
@ -249,76 +214,11 @@ const char * CLangMngr::CLang::GetDef(int key, int &status)
return def.definition->c_str(); return def.definition->c_str();
} }
// Assumes fp is set to the right position
bool CLangMngr::CLang::SaveDefinitions(FILE *fp, uint32_t &curOffset)
{
unsigned short defLen = 0;
String *pdef;
THash<int, defentry>::iterator iter;
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
{
pdef = iter->val.definition;
if (!pdef)
continue;
defLen = pdef->size();
fwrite((void *)&defLen, sizeof(unsigned short), 1, fp);
curOffset += sizeof(unsigned short);
fwrite(pdef->c_str(), sizeof(char), defLen, fp);
curOffset += defLen;
}
return true;
}
int CLangMngr::CLang::Entries() int CLangMngr::CLang::Entries()
{ {
return m_entries; return m_entries;
} }
// Assumes fp is set to the right position
bool CLangMngr::CLang::Save(FILE *fp, int &defOffset, uint32_t &curOffset)
{
uint32_t keynum = 0;
uint32_t size = 0;
String *pdef;
//:TODO: remove this loop and assertion, use m_entries for size
THash<int, defentry>::iterator iter;
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
{
if (iter->val.definition)
size++;
}
assert(size == m_entries);
fwrite((void*)&size, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
for (iter=m_LookUpTable.begin(); iter!=m_LookUpTable.end(); iter++)
{
keynum = iter->key;
pdef = iter->val.definition;
if (!pdef)
continue;
fwrite((void *)&keynum, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
fwrite((void *)&defOffset, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
defOffset += sizeof(short);
defOffset += pdef->size();
}
return true;
}
// assumes fp is set to the right position
bool CLangMngr::CLang::Load(FILE *fp)
{
return true;
}
/******** CLangMngr *********/ /******** CLangMngr *********/
inline String &make_string(const char *str) inline String &make_string(const char *str)
@ -381,35 +281,6 @@ char * CLangMngr::FormatAmxString(AMX *amx, cell *params, int parm, int &len)
return outbuf; return outbuf;
} }
const char *CLangMngr::Format(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
const char *retVal = FormatString(fmt, ap);
va_end(ap);
return retVal;
}
#undef CHECK_PTR
#undef CHECK_OUTPR
#undef ZEROTERM
#undef NEXT_PARAM
#define CHECK_PTR(ptr, start, bufsize) if ((ptr) - (start) >= (bufsize)) { \
AMXXLOG_Log("[AMXX] Buffer overflow in formatting"); \
outbuf[0] = 0; \
return outbuf; }
#define CHECK_OUTPTR(offset) CHECK_PTR(outptr+offset, outbuf, sizeof(outbuf))
#define ZEROTERM(buf) buf[(sizeof(buf)/sizeof(buf[0]))-1]=0;
#define NEXT_PARAM()
//this is not implemented....
char *CLangMngr::FormatString(const char *fmt, va_list &ap)
{
return "";
}
void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef> &tmpVec) void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef> &tmpVec)
{ {
CLang * language = GetLang(lang); CLang * language = GetLang(lang);
@ -638,286 +509,6 @@ void CLangMngr::InvalidateCache()
FileList.clear(); FileList.clear();
} }
bool CLangMngr::Save(const char *filename)
{
FILE *fp = fopen(filename, "wb");
if (!fp)
return false;
uint32_t magic = MAGIC_HDR;
unsigned char version = FFHL_VERSION;
uint32_t langNum = m_Languages.size();
const char *langName = 0;
uint32_t curOffset = 0;
uint32_t keyNum = KeyList.size();
uint32_t ktbSize = KeyList.size() * sizeof(uint32_t);
uint32_t ltbSize = m_Languages.size() * ((sizeof(char)*2) + sizeof(uint32_t));
fwrite((void *)&magic, sizeof(uint32_t), 1, fp);
fwrite((void *)&version, sizeof(unsigned char), 1, fp);
fwrite((void *)&keyNum, sizeof(uint32_t), 1, fp);
fwrite((void *)&langNum, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
curOffset += sizeof(unsigned char);
curOffset += sizeof(uint32_t);
curOffset += sizeof(uint32_t);
uint32_t langOffset = curOffset + ktbSize + ltbSize;
for (unsigned int i = 0; i < m_Languages.size(); i++)
{
langName = m_Languages[i]->GetName();
fwrite(langName, sizeof(char), 2, fp);
curOffset += sizeof(char) * 2;
fwrite((void *)&langOffset, sizeof(uint32_t), 1, fp);
langOffset += sizeof(uint32_t) + (m_Languages[i]->Entries() * (sizeof(uint32_t) * 2));
curOffset += sizeof(uint32_t);
}
//Note - langOffset now points to the start of key lookup table
uint32_t keyHash = 0;
uint32_t keyOffset = langOffset;
for (unsigned int i = 0; i < KeyList.size(); i++)
{
fwrite((void*)&keyOffset, sizeof(uint32_t), 1, fp);
curOffset += sizeof(uint32_t);
keyOffset += sizeof(char);
keyOffset += KeyList[i]->size();
}
//Note - now keyOffset points toward the start of the def table
int defOffset = keyOffset;
for (unsigned int i = 0; i < m_Languages.size(); i++)
{
m_Languages[i]->Save(fp, defOffset, curOffset);
}
//Now, defOffset points toward the END of the file
//curoffset should point toward the key table, so...
unsigned char keyLen = 0;
for (unsigned int i = 0; i < KeyList.size(); i++)
{
keyLen = KeyList[i]->size();
fwrite((void*)&keyLen, sizeof(unsigned char), 1, fp);
curOffset += sizeof(unsigned char);
fwrite(KeyList[i]->c_str(), sizeof(char), keyLen, fp);
curOffset += sizeof(char) * keyLen;
}
//Finally, write the def table
// It's assumed no orders changed...
for (unsigned int i = 0; i < m_Languages.size(); i++)
{
m_Languages[i]->SaveDefinitions(fp, curOffset);
}
fclose(fp);
//done!
return true;
}
bool CLangMngr::SaveCache(const char *filename)
{
FILE *fp = fopen(filename, "wb");
if (!fp)
{
return false;
}
CVector<md5Pair *>::iterator i;
short dictCount = FileList.size();
char len = 0;
fwrite((void *)&dictCount, sizeof(short), 1, fp);
for (i = FileList.begin(); i != FileList.end(); i++)
{
len = (*i)->file.size();
fwrite((void *)&len, sizeof(char), 1, fp);
fwrite((*i)->file.c_str(), sizeof(char), len, fp);
fwrite((*i)->val.c_str(), sizeof(char), 32, fp);
}
fclose(fp);
return true;
}
#define CACHEREAD(expr, type) \
if (! (expr==1) ) { \
FileList.clear(); \
fclose(fp); \
return false; \
}
#define CACHEREAD_S(expr, size) \
if (! (expr==size) ) { \
FileList.clear(); \
fclose(fp); \
return false; \
}
bool CLangMngr::LoadCache(const char *filename)
{
FILE *fp = fopen(filename, "rb");
if (!fp)
{
return false;
}
short dictCount = 0;
char len = 0;
char buf[255];
char md5[34];
CACHEREAD(fread((void*)&dictCount, sizeof(short), 1, fp), short);
md5Pair *p = 0;
for (int i = 1; i <= dictCount; i++)
{
CACHEREAD(fread((void*)&len, sizeof(char), 1, fp), char);
CACHEREAD_S(fread(buf, sizeof(char), len, fp), len);
buf[len] = 0;
CACHEREAD_S(fread(md5, sizeof(char), 32, fp), 32);
md5[32] = 0;
p = new md5Pair;
p->file.assign(buf);
p->val.assign(md5);
FileList.push_back(p);
p = 0;
}
fclose(fp);
return true;
}
#define DATREAD(expr, type) \
if (! (expr==1) ) { \
Clear(); \
fclose(fp); \
return false; \
}
#define DATREAD_S(expr, size) \
if (! (expr==size) ) { \
Clear(); \
fclose(fp); \
return false; \
}
bool CLangMngr::Load(const char *filename)
{
Clear();
FILE *fp = fopen(filename, "rb");
if (!fp)
return false;
uint32_t magic = 0;
uint32_t langCount = 0;
uint32_t keycount = 0;
char version = 0;
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
rewind(fp);
DATREAD(fread((void*)&magic, sizeof(uint32_t), 1, fp), uint32_t);
if (magic != MAGIC_HDR)
return false;
DATREAD(fread((void*)&version, sizeof(char), 1, fp), char);
if (version > FFHL_VERSION || version < FFHL_MIN_VERSION)
return false;
DATREAD(fread((void*)&keycount, sizeof(uint32_t), 1, fp), uint32_t);
DATREAD(fread((void*)&langCount, sizeof(uint32_t), 1, fp), uint32_t);
uint32_t *LangOffsets = new uint32_t[langCount];
char langname[3];
for (unsigned int i = 0; i < langCount; i++)
{
DATREAD_S(fread(langname, sizeof(char), 2, fp), 2);
langname[2] = 0;
GetLang(langname); //this will initialize for us
DATREAD(fread((void *)&(LangOffsets[i]), sizeof(uint32_t), 1, fp), uint32_t);
}
//we should now be at the key table
int ktbOffset = ftell(fp);
unsigned char keylen;
char keybuf[255];
uint32_t bogus;
uint32_t keyoffset, save;
String _tmpkey;
for (unsigned i = 0; i < keycount; i++)
{
if (version == 4)
fread((void*)&(bogus), sizeof(uint32_t), 1, fp);
DATREAD(fread((void*)&keyoffset, sizeof(uint32_t), 1, fp), uint32_t);
if (keyoffset > size-sizeof(uint32_t))
{
Clear();
fclose(fp);
return false;
}
save = ftell(fp);
fseek(fp, keyoffset, SEEK_SET);
DATREAD(fread((void*)&keylen, sizeof(char), 1, fp), char);
DATREAD_S(fread(keybuf, sizeof(char), keylen, fp), keylen);
keybuf[keylen] = 0;
_tmpkey.assign(keybuf);
AddKeyEntry(_tmpkey);
fseek(fp, save, SEEK_SET); //bring back to next key
}
//we should now be at the languages table
uint32_t numentries;
uint32_t keynum;
uint32_t defoffset;
unsigned short deflen;
char valbuf[4096];
for (unsigned int i = 0; i < langCount; i++)
{
DATREAD(fread((void*)&numentries, sizeof(uint32_t), 1, fp), uint32_t);
for (unsigned int j = 0; j < numentries; j++)
{
DATREAD(fread((void *)&keynum, sizeof(uint32_t), 1, fp), uint32_t);
if (version == 4)
{
DATREAD(fread((void *)&bogus, sizeof(uint32_t), 1, fp), uint32_t);
}
DATREAD(fread((void *)&defoffset, sizeof(uint32_t), 1, fp), uint32_t);
if (defoffset > size-sizeof(uint32_t))
{
Clear();
fclose(fp);
return false;
}
save = ftell(fp);
fseek(fp, defoffset, SEEK_SET);
DATREAD(fread((void *)&deflen, sizeof(unsigned short), 1, fp), short);
//:TODO: possible string overflow here.
DATREAD_S(fread(valbuf, sizeof(char), deflen, fp), deflen);
valbuf[deflen] = 0;
m_Languages[i]->AddEntry(keynum, valbuf);
fseek(fp, save, SEEK_SET); //bring back to next entry
}
}
fclose(fp);
delete [] LangOffsets;
//we're done!
return true;
}
CLangMngr::~CLangMngr() CLangMngr::~CLangMngr()
{ {
Clear(); Clear();

View File

@ -111,11 +111,6 @@ class CLangMngr
// Get language name // Get language name
const char *GetName() { return m_LanguageName; } const char *GetName() { return m_LanguageName; }
// Save to file
bool Save(FILE *fp, int &defOffset, uint32_t &curOffset);
bool SaveDefinitions(FILE *fp, uint32_t &curOffset);
// Load
bool Load(FILE *fp);
void SetMngr(CLangMngr *l) { m_LMan = l; } void SetMngr(CLangMngr *l) { m_LMan = l; }
// Get number of entries // Get number of entries
int Entries(); int Entries();
@ -159,18 +154,8 @@ public:
int MergeDefinitionFile(const char *file); int MergeDefinitionFile(const char *file);
// Get a definition from a lang name and a key // Get a definition from a lang name and a key
const char *GetDef(const char *langName, const char *key, int &status); const char *GetDef(const char *langName, const char *key, int &status);
// Format a string
const char *Format(const char *src, ...);
// Format a string for an AMX plugin // Format a string for an AMX plugin
char *FormatAmxString(AMX *amx, cell *params, int parm, int &len); char *FormatAmxString(AMX *amx, cell *params, int parm, int &len);
char *FormatString(const char *fmt, va_list &ap);
// Save
bool Save(const char *filename);
// Load
bool Load(const char *filename);
// Cache
bool LoadCache(const char *filename);
bool SaveCache(const char *filename);
void InvalidateCache(); void InvalidateCache();
// Get index // Get index
int GetKeyEntry(String &key); int GetKeyEntry(String &key);

BIN
amxmodx/JIT/helpers-x86.o Normal file

Binary file not shown.

BIN
amxmodx/JIT/helpers-x86.obj Normal file

Binary file not shown.

View File

@ -45,6 +45,7 @@ ifeq "$(AMD64)" "true"
else else
BINARY = $(NAME)_i386.so BINARY = $(NAME)_i386.so
OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o OBJECTS += JIT/amxexecn.o JIT/amxjitsn.o JIT/natives-x86.o
OBJECTS += JIT/helpers-x86.o
CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32 CFLAGS += -DPAWN_CELL_SIZE=32 -DJIT -DASM32
OPT_FLAGS += -march=i586 OPT_FLAGS += -march=i586
endif endif

View File

@ -462,8 +462,24 @@ int AMXAPI amx_Callback(AMX *amx, cell index, cell *result, cell *params)
amx->error=AMX_ERR_NONE; amx->error=AMX_ERR_NONE;
#if defined BINLOG_ENABLED
binlogfuncs_t *logfuncs = (binlogfuncs_t *)amx->usertags[UT_BINLOGS];
if (logfuncs)
{
logfuncs->pfnLogNative(amx, index, (int)(params[0] / sizeof(cell)));
logfuncs->pfnLogParams(amx, params);
}
#endif //BINLOG_ENABLED
*result = f(amx,params); *result = f(amx,params);
#if defined BINLOG_ENABLED
if (logfuncs)
{
logfuncs->pfnLogReturn(amx, *result);
}
#endif
return amx->error; return amx->error;
} }
#endif /* defined AMX_INIT */ #endif /* defined AMX_INIT */

View File

@ -336,6 +336,7 @@ enum {
#define UT_NATIVE 3 #define UT_NATIVE 3
#define UT_OPTIMIZER 2 #define UT_OPTIMIZER 2
#define UT_BROWSEHOOK 1 #define UT_BROWSEHOOK 1
#define UT_BINLOGS 0
typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip); typedef void (*BROWSEHOOK)(AMX *amx, cell *oplist, cell *cip);
@ -440,6 +441,15 @@ int AMXAPI amx_GetStringOld(char *dest,const cell *source,int use_wchar);
#endif #endif
#endif #endif
#if defined BINLOG_ENABLED
typedef struct tagBINLOG
{
void (*pfnLogNative)(AMX *amx, int native, int params);
void (*pfnLogReturn)(AMX *amx, cell retval);
void (*pfnLogParams)(AMX *amx, cell *params);
} binlogfuncs_t;
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -33,6 +33,7 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "natives.h" #include "natives.h"
#include "debugger.h" #include "debugger.h"
#include "binlog.h"
static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_xvar_id(AMX *amx, cell *params)
{ {
@ -1019,9 +1020,17 @@ static cell AMX_NATIVE_CALL register_plugin(AMX *amx, cell *params) /* 3 param *
CPluginMngr::CPlugin* a = g_plugins.findPluginFast(amx); CPluginMngr::CPlugin* a = g_plugins.findPluginFast(amx);
int i; int i;
a->setTitle(get_amxstring(amx, params[1], 0, i)); char *title = get_amxstring(amx, params[1], 0, i);
a->setVersion(get_amxstring(amx, params[2], 0, i)); char *vers = get_amxstring(amx, params[2], 1, i);
a->setAuthor(get_amxstring(amx, params[3], 0, i)); char *author = get_amxstring(amx, params[3], 2, i);
#if defined BINLOG_ENABLED
g_BinLog.WriteOp(BinLog_Registered, a->getId(), title, vers);
#endif
a->setTitle(title);
a->setVersion(vers);
a->setAuthor(author);
return 1; return 1;
} }
@ -1954,6 +1963,8 @@ static cell AMX_NATIVE_CALL get_players(AMX *amx, cell *params) /* 4 param */
continue; continue;
if ((flags & 16) && (pPlayer->teamId != team)) if ((flags & 16) && (pPlayer->teamId != team))
continue; continue;
if ((flags & 128) && (pPlayer->pEdict->v.flags & FL_PROXY))
continue;
if (flags & 32) if (flags & 32)
{ {
if (flags & 64) if (flags & 64)
@ -3188,6 +3199,7 @@ static cell AMX_NATIVE_CALL callfunc_begin(AMX *amx, cell *params)
// set globals // set globals
g_CallFunc_Plugin = plugin; g_CallFunc_Plugin = plugin;
g_CallFunc_Func = func; g_CallFunc_Func = func;
g_CallFunc_CurParam = 0;
return 1; // success: 1 return 1; // success: 1
} }
@ -3205,6 +3217,13 @@ static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params)
if (!plugin) if (!plugin)
return -1; return -1;
if (g_CallFunc_Plugin)
{
// scripter's fault
LogError(amx, AMX_ERR_NATIVE, "callfunc_begin called without callfunc_end");
return 0;
}
if (params[1] < 0) if (params[1] < 0)
{ {
LogError(amx, AMX_ERR_NATIVE, "Public function %d is invalid", params[1]); LogError(amx, AMX_ERR_NATIVE, "Public function %d is invalid", params[1]);
@ -3216,6 +3235,7 @@ static cell AMX_NATIVE_CALL callfunc_begin_i(AMX *amx, cell *params)
g_CallFunc_Plugin = plugin; g_CallFunc_Plugin = plugin;
g_CallFunc_Func = params[1]; g_CallFunc_Func = params[1];
g_CallFunc_CurParam = 0;
return 1; return 1;
} }
@ -3686,6 +3706,10 @@ static cell AMX_NATIVE_CALL amx_abort(AMX *amx, cell *params)
if (pPlugin) if (pPlugin)
filename = pPlugin->getName(); filename = pPlugin->getName();
//we were in a callfunc?
if (g_CallFunc_Plugin == pPlugin)
g_CallFunc_Plugin = NULL;
if (fmt) if (fmt)
LogError(amx, err, "[%s] %s", filename, fmt); LogError(amx, err, "[%s] %s", filename, fmt);
else else
@ -3834,7 +3858,7 @@ static cell AMX_NATIVE_CALL ExecuteForward(AMX *amx, cell *params)
int id = static_cast<int>(params[1]); int id = static_cast<int>(params[1]);
int str_id = 0; int str_id = 0;
int len; int len;
cell *addr = get_amxaddr(amx, params[1]); cell *addr = get_amxaddr(amx, params[2]);
if (!g_forwards.isIdValid(id)) if (!g_forwards.isIdValid(id))
return 0; return 0;
@ -3891,8 +3915,7 @@ static cell AMX_NATIVE_CALL CreateHudSyncObj(AMX *amx, cell *params)
return static_cast<cell>(g_hudsync.size()); return static_cast<cell>(g_hudsync.size());
} }
hudtextparms_t temp_hud_stuff; void CheckAndClearPlayerHUD(CPlayer *player, int &channel, unsigned int sync_obj)
void CheckAndClearPlayerHUD(CPlayer *player, unsigned int channel, unsigned int sync_obj)
{ {
/** /**
* player and channel should be guaranteed to be good to go. * player and channel should be guaranteed to be good to go.
@ -3904,27 +3927,8 @@ void CheckAndClearPlayerHUD(CPlayer *player, unsigned int channel, unsigned int
//check if the last sync on this channel was this sync obj //check if the last sync on this channel was this sync obj
if (player->hudmap[last_channel] == sync_obj + 1) if (player->hudmap[last_channel] == sync_obj + 1)
{ {
//if so, we can safely CLEAR it. //if so, we can safely REUSE it
temp_hud_stuff.a1 = 0; channel = (int)last_channel;
temp_hud_stuff.a2 = 0;
temp_hud_stuff.r2 = 255;
temp_hud_stuff.g2 = 255;
temp_hud_stuff.b2 = 250;
temp_hud_stuff.r1 = 0;
temp_hud_stuff.g1 = 0;
temp_hud_stuff.b1 = 0;
temp_hud_stuff.x = 0.0f;
temp_hud_stuff.y = 0.0f;
temp_hud_stuff.effect = 0;
temp_hud_stuff.fxTime = 0.0f;
temp_hud_stuff.holdTime = 0.01;
temp_hud_stuff.fadeinTime = 0.0f;
temp_hud_stuff.fadeoutTime = 0.0f;
temp_hud_stuff.channel = last_channel;
static char msg[255];
msg[0] = '\0';
char *msg_ptr = UTIL_SplitHudMessage(msg);
UTIL_HudMessage(player->pEdict, temp_hud_stuff, msg_ptr);
} }
//set the new states //set the new states
@ -3934,6 +3938,7 @@ void CheckAndClearPlayerHUD(CPlayer *player, unsigned int channel, unsigned int
static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params) static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params)
{ {
int len = 0;
int index = params[1]; int index = params[1];
unsigned int sync_obj = static_cast<unsigned int>(params[2]) - 1; unsigned int sync_obj = static_cast<unsigned int>(params[2]) - 1;
@ -3943,19 +3948,24 @@ static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params)
return 0; return 0;
} }
cell *plist = g_hudsync[sync_obj]; g_langMngr.SetDefLang(params[1]);
if (index == 0) if (index == 0)
{ {
CPlayer *pPlayer; for (int i = 1; i <= gpGlobals->maxClients; ++i)
for (int i = 1; i <= gpGlobals->maxClients; i++)
{ {
pPlayer = GET_PLAYER_POINTER_I(i); CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
if (!pPlayer->ingame) int channel;
continue; if (pPlayer->ingame)
{
CheckAndClearPlayerHUD(pPlayer, plist[pPlayer->index], sync_obj); g_langMngr.SetDefLang(i);
channel = pPlayer->NextHUDChannel();
CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
pPlayer->channels[channel] = gpGlobals->time;
g_hudset.channel = channel;
UTIL_HudMessage(pPlayer->pEdict, g_hudset, "");
}
} }
} else { } else {
if (index < 1 || index > gpGlobals->maxClients) if (index < 1 || index > gpGlobals->maxClients)
@ -3968,11 +3978,15 @@ static cell AMX_NATIVE_CALL ClearSyncHud(AMX *amx, cell *params)
if (pPlayer->ingame) if (pPlayer->ingame)
{ {
CheckAndClearPlayerHUD(pPlayer, plist[pPlayer->index], sync_obj); int channel = pPlayer->NextHUDChannel();
CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
pPlayer->channels[channel] = gpGlobals->time;
g_hudset.channel = channel;
UTIL_HudMessage(pPlayer->pEdict, g_hudset, "");
} }
} }
return 1; return len;
} }
//params[1] - target //params[1] - target
@ -3999,12 +4013,14 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params)
{ {
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i); CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
int channel;
if (pPlayer->ingame) if (pPlayer->ingame)
{ {
g_langMngr.SetDefLang(i); g_langMngr.SetDefLang(i);
g_hudset.channel = pPlayer->NextHUDChannel(); channel = pPlayer->NextHUDChannel();
pPlayer->channels[g_hudset.channel] = gpGlobals->time; CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
CheckAndClearPlayerHUD(pPlayer, g_hudset.channel, sync_obj); pPlayer->channels[channel] = gpGlobals->time;
g_hudset.channel = channel;
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len)); message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len));
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message); UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
} }
@ -4020,9 +4036,10 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params)
if (pPlayer->ingame) if (pPlayer->ingame)
{ {
g_hudset.channel = pPlayer->NextHUDChannel(); int channel = pPlayer->NextHUDChannel();
pPlayer->channels[g_hudset.channel] = gpGlobals->time; CheckAndClearPlayerHUD(pPlayer, channel, sync_obj);
CheckAndClearPlayerHUD(pPlayer, g_hudset.channel, sync_obj); pPlayer->channels[channel] = gpGlobals->time;
g_hudset.channel = channel;
message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len)); message = UTIL_SplitHudMessage(format_amxstring(amx, params, 3, len));
UTIL_HudMessage(pPlayer->pEdict, g_hudset, message); UTIL_HudMessage(pPlayer->pEdict, g_hudset, message);
} }
@ -4031,9 +4048,17 @@ static cell AMX_NATIVE_CALL ShowSyncHudMsg(AMX *amx, cell *params)
return len; return len;
} }
static cell AMX_NATIVE_CALL arrayset(AMX *amx, cell *params)
{
memset(get_amxaddr(amx, params[1]), params[2], params[3] * sizeof(cell));
return 1;
}
AMX_NATIVE_INFO amxmodx_Natives[] = AMX_NATIVE_INFO amxmodx_Natives[] =
{ {
{"abort", amx_abort}, {"abort", amx_abort},
{"arrayset", arrayset},
{"get_addr_val", get_addr_val}, {"get_addr_val", get_addr_val},
{"get_var_addr", get_var_addr}, {"get_var_addr", get_var_addr},
{"set_addr_val", set_addr_val}, {"set_addr_val", set_addr_val},

View File

@ -67,7 +67,7 @@
#include "amxxlog.h" #include "amxxlog.h"
#define AMXXLOG_Log g_log.Log #define AMXXLOG_Log g_log.Log
#define AMX_VERSION "1.70" #define AMX_VERSION "1.71"
extern AMX_NATIVE_INFO core_Natives[]; extern AMX_NATIVE_INFO core_Natives[];
extern AMX_NATIVE_INFO time_Natives[]; extern AMX_NATIVE_INFO time_Natives[];

View File

@ -92,11 +92,13 @@ void CLog::CreateNewFile()
time(&td); time(&td);
tm *curTime = localtime(&td); tm *curTime = localtime(&td);
char file[256];
int i = 0; int i = 0;
while (true) while (true)
{ {
FILE *pTmpFile = fopen(m_LogFile.c_str(), "r"); // open for reading to check whether the file exists build_pathname_r(file, sizeof(file)-1, "%s/L%02d%02d%03d.log", g_log_dir.c_str(), curTime->tm_mon + 1, curTime->tm_mday, i);
FILE *pTmpFile = fopen(file, "r"); // open for reading to check whether the file exists
if (!pTmpFile) if (!pTmpFile)
break; break;
@ -104,6 +106,7 @@ void CLog::CreateNewFile()
fclose(pTmpFile); fclose(pTmpFile);
++i; ++i;
} }
m_LogFile.assign(file);
// Log logfile start // Log logfile start
FILE *fp = fopen(m_LogFile.c_str(), "w"); FILE *fp = fopen(m_LogFile.c_str(), "w");

260
amxmodx/binlog.cpp Normal file
View File

@ -0,0 +1,260 @@
#include <time.h>
#include "amxmodx.h"
#include "binlog.h"
#if defined BINLOG_ENABLED
BinLog g_BinLog;
int g_binlog_level = 0;
int g_binlog_maxsize = 0;
bool BinLog::Open()
{
const char *data = get_localinfo("amxmodx_datadir", "addons/amxmodx/data");
char path[255];
build_pathname_r(path, sizeof(path)-1, "%s/binlogs", data);
if (!DirExists(path))
{
mkdir(path
#if defined __linux__
, 0755
#endif
);
if (!DirExists(path))
return false;
}
char file[255];
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/lastlog", data);
unsigned int lastcntr = 0;
FILE *lastlog = fopen(file, "rb");
if (lastlog)
{
if (fread(&lastcntr, sizeof(int), 1, lastlog) != 1)
lastcntr = 0;
fclose(lastlog);
}
lastlog = fopen(file, "wb");
if (lastlog)
{
lastcntr++;
fwrite(&lastcntr, sizeof(int), 1, lastlog);
fclose(lastlog);
}
build_pathname_r(file, sizeof(file)-1, "%s/binlogs/binlog%04d.blg", data, lastcntr);
m_logfile.assign(file);
/**
* it's now safe to create the binary log
*/
FILE *fp = fopen(m_logfile.c_str(), "wb");
if (!fp)
return false;
int magic = BINLOG_MAGIC;
short vers = BINLOG_VERSION;
char c = sizeof(time_t);
fwrite(&magic, sizeof(int), 1, fp);
fwrite(&vers, sizeof(short), 1, fp);
fwrite(&c, sizeof(char), 1, fp);
WritePluginDB(fp);
fclose(fp);
m_state = true;
WriteOp(BinLog_Start, -1);
return true;
}
void BinLog::Close()
{
WriteOp(BinLog_End, -1);
m_state = false;
}
void BinLog::WriteOp(BinLogOp op, int plug, ...)
{
if (!m_state)
return;
FILE *fp = fopen(m_logfile.c_str(), "ab");
if (!fp)
return;
if (g_binlog_maxsize && op != BinLog_End)
{
fseek(fp, 0, SEEK_END);
if (ftell(fp) > (g_binlog_maxsize * (1024 * 1024)))
{
fclose(fp);
Close();
Open();
fp = fopen(m_logfile.c_str(), "ab");
if (!fp)
return;
}
}
unsigned char c = static_cast<char>(op);
time_t t = time(NULL);
float gt = gpGlobals->time;
fwrite(&c, sizeof(char), 1, fp);
fwrite(&t, sizeof(time_t), 1, fp);
fwrite(&gt, sizeof(float), 1, fp);
fwrite(&plug, sizeof(int), 1, fp);
va_list ap;
va_start(ap, plug);
switch (c)
{
case BinLog_Registered:
{
const char *title = va_arg(ap, const char *);
const char *vers = va_arg(ap, const char *);
c = (char)strlen(title);
fwrite(&c, sizeof(char), 1, fp);
fwrite(title, sizeof(char), c+1, fp);
c = (char)strlen(vers);
fwrite(&c, sizeof(char), 1 ,fp);
fwrite(vers, sizeof(char), c+1, fp);
break;
}
case BinLog_NativeCall:
{
int native = va_arg(ap, int);
int params = va_arg(ap, int);
fwrite(&native, sizeof(int), 1, fp);
fwrite(&params, sizeof(int), 1, fp);
break;
}
case BinLog_NativeRet:
{
cell retval = va_arg(ap, cell);
fwrite(&retval, sizeof(cell), 1, fp);
break;
}
case BinLog_NativeError:
{
int err = va_arg(ap, int);
const char *msg = va_arg(ap, const char *);
short len = (short)strlen(msg);
fwrite(&err, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(msg, sizeof(char), len+1, fp);
break;
}
case BinLog_CallPubFunc:
{
int num = va_arg(ap, int);
fwrite(&num, sizeof(int), 1, fp);
break;
}
case BinLog_SetLine:
{
int line = va_arg(ap, int);
fwrite(&line, sizeof(int), 1, fp);
break;
}
case BinLog_FormatString:
{
int param = va_arg(ap, int);
int maxlen = va_arg(ap, int);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&param, sizeof(int), 1, fp);
fwrite(&maxlen, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
case BinLog_NativeParams:
{
cell *params = va_arg(ap, cell *);
cell num = params[0] / sizeof(cell);
fwrite(&num, sizeof(cell), 1, fp);
for (cell i=1; i<=num; i++)
fwrite(&(params[i]), sizeof(cell), 1, fp);
break;
}
case BinLog_GetString:
{
cell addr = va_arg(ap, cell);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&addr, sizeof(cell), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
case BinLog_SetString:
{
cell addr = va_arg(ap, cell);
int maxlen = va_arg(ap, int);
const char *str = va_arg(ap, const char *);
short len = (short)strlen(str);
fwrite(&addr, sizeof(cell), 1, fp);
fwrite(&maxlen, sizeof(int), 1, fp);
fwrite(&len, sizeof(short), 1, fp);
fwrite(str, sizeof(char), len+1, fp);
break;
}
};
va_end(ap);
fclose(fp);
}
void BinLog::WritePluginDB(FILE *fp)
{
int num = g_plugins.getPluginsNum();
fwrite(&num, sizeof(int), 1, fp);
CPluginMngr::CPlugin *pl;
char c;
unsigned char len;
for (CPluginMngr::iterator iter = g_plugins.begin(); iter; ++iter)
{
pl = &(*iter);
if (pl->isValid())
c = 1;
else
c = 0;
if (c && pl->isDebug())
c = 2;
fwrite(&c, sizeof(char), 1, fp);
len = (char)strlen(pl->getName());
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(pl->getName(), sizeof(char), len, fp);
int natives, publics;
AMX *amx = pl->getAMX();
amx_NumNatives(amx, &natives);
amx_NumPublics(amx, &publics);
fwrite(&natives, sizeof(int), 1, fp);
fwrite(&publics, sizeof(int), 1, fp);
char name[34];
for (int i=0; i<natives; i++)
{
amx_GetNative(amx, i, name);
len = (char)strlen(name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(name, sizeof(char), len, fp);
}
for (int i=0; i<publics; i++)
{
amx_GetPublic(amx, i, name);
len = (char)strlen(name);
fwrite(&len, sizeof(char), 1, fp);
len++;
fwrite(name, sizeof(char), len, fp);
}
}
}
#endif //BINLOG_ENABLED

77
amxmodx/binlog.h Normal file
View File

@ -0,0 +1,77 @@
#ifndef _INCLUDE_BINLOG_H
#define _INCLUDE_BINLOG_H
#if defined BINLOG_ENABLED
#include "CString.h"
#define BINLOG_MAGIC 0x414D424C
#define BINLOG_VERSION 0x0200
/**
* Format of binlog:
* uint32 magic
* uint16 version
* uint8 sizeof(time_t)
* uint32 num plugins
* [
* uint8 status codes
* str[int8] filename
* uint32 num natives
* uint32 num publics
* [
* str[uint8] native name
* ]
* [
* str[uint8] public name
* ]
* ]
* [
* uint8 operation code
* time_t realtime
* float gametime
* int32 plugin id
* <extra info>
* ]
*/
enum BinLogOp
{
BinLog_Start=1,
BinLog_End,
BinLog_NativeCall, //<int32 native id> <int32_t num_params>
BinLog_NativeError, //<int32 errornum> <str[int16] string>
BinLog_NativeRet, //<cell value>
BinLog_CallPubFunc, //<int32 public id>
BinLog_SetLine, //<int32 line no#>
BinLog_Registered, //<string title> <string version>
BinLog_FormatString, //<int32 param#> <int32 maxlen> <str[int16] string>
BinLog_NativeParams, //<int32 num> <cell ...>
BinLog_GetString, //<cell addr> <string[int16]>
BinLog_SetString, //<cell addr> <int maxlen> <string[int16]>
};
class BinLog
{
public:
BinLog() : m_state(false)
{
};
public:
bool Open();
void Close();
void WriteOp(BinLogOp op, int plug, ...);
private:
void WritePluginDB(FILE *fp);
private:
String m_logfile;
bool m_state;
};
extern BinLog g_BinLog;
extern int g_binlog_level;
extern int g_binlog_maxsize;
#endif //BINLOG_ENABLED
#endif //_INCLUDE_BINLOG_H

View File

@ -31,6 +31,7 @@
#include "amxmodx.h" #include "amxmodx.h"
#include "debugger.h" #include "debugger.h"
#include "binlog.h"
#if !defined WIN32 && !defined _WIN32 #if !defined WIN32 && !defined _WIN32
#define _snprintf snprintf #define _snprintf snprintf
@ -307,6 +308,19 @@ void Debugger::StepI()
{ {
assert(m_Top >= 0 && m_Top < (int)m_pCalls.size()); assert(m_Top >= 0 && m_Top < (int)m_pCalls.size());
#if defined BINLOG_ENABLED
if (g_binlog_level & 32)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(m_pAmx);
if (pl)
{
long line;
dbg_LookupLine(m_pAmxDbg, m_pAmx->cip, &line);
g_BinLog.WriteOp(BinLog_SetLine, pl->getId(), (int)(line + 1));
}
}
#endif
m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip); m_pCalls[m_Top]->StepI(m_pAmx->frm, m_pAmx->cip);
} }
@ -633,7 +647,7 @@ int Handler::SetErrorHandler(const char *function)
error = amx_FindPublic(m_pAmx, function, &m_iErrFunc); error = amx_FindPublic(m_pAmx, function, &m_iErrFunc);
if (error != AMX_ERR_NONE && m_iErrFunc < 1) if (error != AMX_ERR_NONE && m_iErrFunc < 0)
m_iErrFunc = -1; m_iErrFunc = -1;
return error; return error;
@ -645,7 +659,7 @@ int Handler::SetModuleFilter(const char *function)
error = amx_FindPublic(m_pAmx, function, &m_iModFunc); error = amx_FindPublic(m_pAmx, function, &m_iModFunc);
if (error != AMX_ERR_NONE && m_iModFunc < 1) if (error != AMX_ERR_NONE && m_iModFunc < 0)
m_iModFunc = -1; m_iModFunc = -1;
return error; return error;
@ -681,7 +695,7 @@ const char *Handler::GetLastMsg()
int Handler::HandleModule(const char *module) int Handler::HandleModule(const char *module)
{ {
if (m_iModFunc < 1) if (m_iModFunc < 0)
return 0; return 0;
/** /**

View File

@ -307,27 +307,7 @@ static cell AMX_NATIVE_CALL dir_exists(AMX *amx, cell *params) /* 1 param */
char *sFile = get_amxstring(amx, params[1], 0, iLen); char *sFile = get_amxstring(amx, params[1], 0, iLen);
char *file = build_pathname("%s", sFile); char *file = build_pathname("%s", sFile);
#if defined WIN32 || defined _WIN32 return DirExists(file) ? 1 : 0;
DWORD attr = GetFileAttributes(file);
if (attr == INVALID_FILE_ATTRIBUTES)
return 0;
if (attr == FILE_ATTRIBUTE_DIRECTORY)
return 1;
return 0;
#else
struct stat s;
if (stat(file, &s) != 0)
return 0;
if (S_ISDIR(s.st_mode))
return 1;
return 0;
#endif
} }
static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */ static cell AMX_NATIVE_CALL file_size(AMX *amx, cell *params) /* 1 param */
@ -761,6 +741,54 @@ static cell AMX_NATIVE_CALL amx_get_dir(AMX *amx, cell *params)
#endif #endif
} }
//native fgetc( file );
static cell AMX_NATIVE_CALL amx_fgetc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fgetc(fp);
}
//native fputc( file, data );
static cell AMX_NATIVE_CALL amx_fputc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return fputc(static_cast<int>(params[2]), fp);
}
//native ungetc( file, data );
static cell AMX_NATIVE_CALL amx_ungetc(AMX *amx, cell *params)
{
FILE *fp = (FILE *)params[1];
if (!fp)
return 0;
return ungetc(static_cast<int>(params[2]), fp);
}
#if defined __linux__
#define _rmdir rmdir
#endif
static cell AMX_NATIVE_CALL amx_rmdir(AMX *amx, cell *params)
{
int len;
char* sFile = build_pathname("%s", get_amxstring(amx, params[1], 0, len));
if (_rmdir(sFile) != 0)
return 0;
return 1;
}
AMX_NATIVE_INFO file_Natives[] = AMX_NATIVE_INFO file_Natives[] =
{ {
{"delete_file", delete_file}, {"delete_file", delete_file},
@ -785,10 +813,14 @@ AMX_NATIVE_INFO file_Natives[] =
{"ftell", amx_ftell}, {"ftell", amx_ftell},
{"filesize", amx_filesize}, {"filesize", amx_filesize},
{"unlink", delete_file}, {"unlink", delete_file},
{"build_pathname", amx_build_pathname}, {"build_pathname", amx_build_pathname},
{"dir_exists", dir_exists}, {"dir_exists", dir_exists},
{"open_dir", amx_open_dir}, {"open_dir", amx_open_dir},
{"close_dir", amx_close_dir}, {"close_dir", amx_close_dir},
{"next_file", amx_get_dir}, {"next_file", amx_get_dir},
{"fgetc", amx_fgetc},
{"fputc", amx_fputc},
{"fungetc", amx_ungetc},
{"rmdir", amx_rmdir},
{NULL, NULL} {NULL, NULL}
}; };

51
amxmodx/helpers-x86.asm Normal file
View File

@ -0,0 +1,51 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; (C)2006 by David "BAILOPAN" Anderson ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;Licensed under the GNU General Public License, version 2
;;This is a portion of AMX Mod X
;; and is maintained by the AMX Mod X development team.
section .text
global amxx_CpuSupport, _amxx_CpuSupport
amxx_CpuSupport:
_amxx_CpuSupport:
push ebp
mov ebp, esp
push ebx
mov eax, 0
cpuid
cmp eax, 1
jl .fail
mov eax, 1
cpuid
;check if family == 5 or 4
and eax, 0780h ;family mask
shr eax, 7 ;family shift
cmp eax, 5
je .fail
cmp eax, 4
je .fail
;check if CMOV exists
shr edx, 15
and edx, 1
cmp edx, 0
je .fail
mov eax, 1
jmp .end
.fail:
xor eax, eax
.end
pop ebx
pop ebp
ret

View File

@ -39,6 +39,8 @@
#include "fakemeta.h" #include "fakemeta.h"
#include "newmenus.h" #include "newmenus.h"
#include "natives.h" #include "natives.h"
#include "binlog.h"
#include "optimizer.h"
plugin_info_t Plugin_info = plugin_info_t Plugin_info =
{ {
@ -242,15 +244,6 @@ int C_Spawn(edict_t *pent)
// ###### Initialize task manager // ###### Initialize task manager
g_tasksMngr.registerTimers(&gpGlobals->time, &mp_timelimit->value, &g_game_timeleft); g_tasksMngr.registerTimers(&gpGlobals->time, &mp_timelimit->value, &g_game_timeleft);
// ###### Load lang
char file[256];
if (!g_langMngr.Load(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxmodx_datadir", "addons/amxmodx/data"))))
{
g_langMngr.InvalidateCache();
} else {
g_langMngr.LoadCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
}
// ###### Initialize commands prefixes // ###### Initialize commands prefixes
g_commands.registerPrefix("amx"); g_commands.registerPrefix("amx");
g_commands.registerPrefix("amxx"); g_commands.registerPrefix("amxx");
@ -277,6 +270,7 @@ int C_Spawn(edict_t *pent)
CVAR_SET_STRING(init_amxmodx_modules.name, buffer); CVAR_SET_STRING(init_amxmodx_modules.name, buffer);
// ###### Load Vault // ###### Load Vault
char file[255];
g_vault.setSource(build_pathname_r(file, sizeof(file) - 1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini"))); g_vault.setSource(build_pathname_r(file, sizeof(file) - 1, "%s", get_localinfo("amxx_vault", "addons/amxmodx/configs/vault.ini")));
g_vault.loadVault(); g_vault.loadVault();
@ -298,6 +292,10 @@ int C_Spawn(edict_t *pent)
// Set server flags // Set server flags
memset(g_players[0].flags, -1, sizeof(g_players[0].flags)); memset(g_players[0].flags, -1, sizeof(g_players[0].flags));
g_opt_level = atoi(get_localinfo("optimizer", "7"));
if (!g_opt_level)
g_opt_level = 7;
// ###### Load AMX scripts // ###### Load AMX scripts
g_plugins.loadPluginsFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini")); g_plugins.loadPluginsFromFile(get_localinfo("amxx_plugins", "addons/amxmodx/configs/plugins.ini"));
g_plugins.Finalize(); g_plugins.Finalize();
@ -317,6 +315,15 @@ int C_Spawn(edict_t *pent)
FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE); FF_ClientAuthorized = registerForward("client_authorized", ET_IGNORE, FP_CELL, FP_DONE);
FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE); FF_ChangeLevel = registerForward("server_changelevel", ET_STOP, FP_STRING, FP_DONE);
#if defined BINLOG_ENABLED
if (!g_BinLog.Open())
{
LOG_ERROR(PLID, "Binary log failed to open.");
}
g_binlog_level = atoi(get_localinfo("bin_logging", "17"));
g_binlog_maxsize = atoi(get_localinfo("max_binlog_size", "20"));
#endif
modules_callPluginsLoaded(); modules_callPluginsLoaded();
// ###### Call precache forward function // ###### Call precache forward function
@ -430,11 +437,6 @@ void C_ServerActivate_Post(edict_t *pEdictList, int edictCount, int clientMax)
executeForwards(FF_PluginInit); executeForwards(FF_PluginInit);
executeForwards(FF_PluginCfg); executeForwards(FF_PluginCfg);
// ###### Save lang
char file[256];
g_langMngr.Save(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
// Correct time in Counter-Strike and other mods (except DOD) // Correct time in Counter-Strike and other mods (except DOD)
if (!g_bmod_dod) if (!g_bmod_dod)
g_game_timeleft = 0; g_game_timeleft = 0;
@ -505,12 +507,6 @@ void C_ServerDeactivate_Post()
g_plugins.clear(); g_plugins.clear();
ClearPluginLibraries(); ClearPluginLibraries();
char file[256];
g_langMngr.Save(build_pathname_r(file, sizeof(file) - 1, "%s/languages.dat", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.SaveCache(build_pathname_r(file, sizeof(file) - 1, "%s/dictionary.cache", get_localinfo("amxx_datadir", "addons/amxmodx/data")));
g_langMngr.Clear();
for (unsigned int i=0; i<g_hudsync.size(); i++) for (unsigned int i=0; i<g_hudsync.size(); i++)
delete [] g_hudsync[i]; delete [] g_hudsync[i];
g_hudsync.clear(); g_hudsync.clear();
@ -569,6 +565,10 @@ void C_ServerDeactivate_Post()
} }
#endif // MEMORY_TEST #endif // MEMORY_TEST
#if defined BINLOG_ENABLED
g_BinLog.Close();
#endif
g_initialized = false; g_initialized = false;
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
@ -1293,6 +1293,7 @@ C_DLLEXPORT int Meta_Detach(PLUG_LOADTIME now, PL_UNLOAD_REASON reason)
g_xvars.clear(); g_xvars.clear();
g_plugins.clear(); g_plugins.clear();
g_cvars.clear(); g_cvars.clear();
g_langMngr.Clear();
detachModules(); detachModules();

View File

@ -45,6 +45,7 @@
#include "natives.h" #include "natives.h"
#include "debugger.h" #include "debugger.h"
#include "optimizer.h" #include "optimizer.h"
#include "binlog.h"
CList<CModule, const char*> g_modules; CList<CModule, const char*> g_modules;
CList<CScript, AMX*> g_loadedscripts; CList<CScript, AMX*> g_loadedscripts;
@ -57,6 +58,30 @@ ModuleCallReason g_ModuleCallReason;
extern const char* no_function; // stupid work around extern const char* no_function; // stupid work around
bool DirExists(const char *dir)
{
#if defined WIN32 || defined _WIN32
DWORD attr = GetFileAttributes(dir);
if (attr == INVALID_FILE_ATTRIBUTES)
return false;
if (attr & FILE_ATTRIBUTE_DIRECTORY)
return true;
#else
struct stat s;
if (stat(dir, &s) != 0)
return false;
if (S_ISDIR(s.st_mode))
return true;
#endif
return false;
}
void report_error(int code, char* fmt, ...) void report_error(int code, char* fmt, ...)
{ {
va_list argptr; va_list argptr;
@ -101,6 +126,38 @@ void free_amxmemory(void **ptr)
*ptr = 0; *ptr = 0;
} }
#if defined BINLOG_ENABLED
void BinLog_LogNative(AMX *amx, int native, int params)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeCall, pl->getId(), native, params);
}
void BinLog_LogReturn(AMX *amx, cell retval)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeRet, pl->getId(), retval);
}
void BinLog_LogParams(AMX *amx, cell *params)
{
if (g_binlog_level & 8)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeParams, pl->getId(), params);
}
}
static binlogfuncs_t logfuncs =
{
BinLog_LogNative,
BinLog_LogReturn,
BinLog_LogParams
};
#endif
int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug) int load_amxscript(AMX *amx, void **program, const char *filename, char error[64], int debug)
{ {
*error = 0; *error = 0;
@ -210,7 +267,10 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
#endif #endif
} }
SetupOptimizer(amx); if (g_opt_level != 65536)
{
SetupOptimizer(amx);
}
if ((err = amx_Init(amx, *program)) != AMX_ERR_NONE) if ((err = amx_Init(amx, *program)) != AMX_ERR_NONE)
{ {
@ -227,6 +287,10 @@ int load_amxscript(AMX *amx, void **program, const char *filename, char error[64
Handler *pHandler = new Handler(amx); Handler *pHandler = new Handler(amx);
amx->userdata[UD_HANDLER] = (void *)pHandler; amx->userdata[UD_HANDLER] = (void *)pHandler;
#if defined BINLOG_ENABLED
amx->usertags[UT_BINLOGS] = (void *)&logfuncs;
#endif
if (will_be_debugged) if (will_be_debugged)
{ {
amx->flags |= AMX_FLAG_DEBUG; amx->flags |= AMX_FLAG_DEBUG;
@ -1375,6 +1439,12 @@ extern "C" void LogError(AMX *amx, int err, const char *fmt, ...)
va_end(ap); va_end(ap);
} }
#if defined BINLOG_ENABLED
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_NativeError, pl->getId(), err, msg_buffer);
#endif
//give the plugin first chance to handle any sort of error //give the plugin first chance to handle any sort of error
Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER]; Handler *pHandler = (Handler *)amx->userdata[UD_HANDLER];
@ -1433,12 +1503,7 @@ edict_t* MNF_GetPlayerEdict(int id)
const char *MNF_Format(const char *fmt, ...) const char *MNF_Format(const char *fmt, ...)
{ {
va_list ap; return "";
va_start(ap, fmt);
const char *retVal = g_langMngr.FormatString(fmt, ap);
va_end(ap);
return retVal;
} }
const char *MNF_GetPlayerTeam(int id) const char *MNF_GetPlayerTeam(int id)

View File

@ -78,6 +78,8 @@ class Debugger;
Debugger *DisableDebugHandler(AMX *amx); Debugger *DisableDebugHandler(AMX *amx);
void EnableDebugHandler(AMX *amx, Debugger *pd); void EnableDebugHandler(AMX *amx, Debugger *pd);
bool DirExists(const char *dir);
const char* GetFileName(AMX *amx); const char* GetFileName(AMX *amx);
#endif // __MODULES_H__ #endif // __MODULES_H__

View File

@ -7,8 +7,10 @@ Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug Debug = Debug
JITDebug = JITDebug JITDebug = JITDebug
JITDebugBinLog = JITDebugBinLog
JITMemtestRelease = JITMemtestRelease JITMemtestRelease = JITMemtestRelease
JITRelease = JITRelease JITRelease = JITRelease
JITReleaseBinLog = JITReleaseBinLog
MaximalSpeed = MaximalSpeed MaximalSpeed = MaximalSpeed
MemtestDebug = MemtestDebug MemtestDebug = MemtestDebug
MemtestRelease = MemtestRelease MemtestRelease = MemtestRelease
@ -19,10 +21,14 @@ Global
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug.Build.0 = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.ActiveCfg = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebugBinLog.Build.0 = JITDebugBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.ActiveCfg = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease.Build.0 = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.ActiveCfg = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITReleaseBinLog.Build.0 = JITReleaseBinLog|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.ActiveCfg = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed.Build.0 = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32 {2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug.ActiveCfg = MemtestDebug|Win32

View File

@ -326,7 +326,7 @@
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj" AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebug/amxmodx_mm.dll" OutputFile="jitdebug/amxmodx_mm.dll"
Version="0.1" Version="0.1"
LinkIncremental="1" LinkIncremental="2"
SuppressStartupBanner="TRUE" SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32" AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT" IgnoreDefaultLibraryNames="MSVCRT"
@ -580,6 +580,153 @@
<Tool <Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/> Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration> </Configuration>
<Configuration
Name="JITDebugBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;PAWN_CELL_SIZE=32;ASM32;JIT;BINLOG_ENABLED"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
StructMemberAlignment="3"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitdebugbinlog/amxmodx.pch"
AssemblerListingLocation=".\jitdebugbinlog/"
ObjectFile=".\jitdebugbinlog/"
ProgramDataBaseFileName=".\jitdebugbinlog/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitdebugbinlog/amxmodx_mm.dll"
Version="0.1"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitdebugbinlog/amxx_mm.pdb"
ImportLibrary=".\jitdebugbinlog/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\debug/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="JITReleaseBinLog|Win32"
OutputDirectory="$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="TRUE"
FavorSizeOrSpeed="1"
OmitFramePointers="TRUE"
OptimizeForProcessor="0"
AdditionalIncludeDirectories="..\..\metamod\metamod,..\..\hlsdk\sourcecode\common,..\..\hlsdk\sourcecode\engine,..\..\hlsdk\sourcecode\dlls,..\..\hlsdk\sourcecode\pm_shared,..\extra\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;amxmodx_EXPORTS;JIT;ASM32;PAWN_CELL_SIZE=32;BINLOG_ENABLED"
IgnoreStandardIncludePath="FALSE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderThrough="amxmodx.h"
PrecompiledHeaderFile=".\jitreleasebinlog/amxmodx.pch"
AssemblerListingLocation=".\jitreleasebinlog/"
ObjectFile=".\jitreleasebinlog/"
ProgramDataBaseFileName=".\jitreleasebinlog/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="..\zlib\zlib.lib ..\JIT\amxjitsn.obj ..\JIT\amxexecn.obj ..\JIT\natives-x86.obj"
OutputFile="jitreleasebinlog/amxmodx_mm.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\extra\lib_win32"
IgnoreDefaultLibraryNames="MSVCRT"
ModuleDefinitionFile=""
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\jitreleasebinlog/amxmodx_mm.pdb"
GenerateMapFile="TRUE"
ImportLibrary=".\jitreleasebinlog/amxx_mm.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\release/amxmodx.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations> </Configurations>
<References> <References>
</References> </References>
@ -608,6 +755,9 @@
<File <File
RelativePath="..\amxxlog.cpp"> RelativePath="..\amxxlog.cpp">
</File> </File>
<File
RelativePath="..\binlog.cpp">
</File>
<File <File
RelativePath="..\CCmd.cpp"> RelativePath="..\CCmd.cpp">
</File> </File>
@ -646,6 +796,12 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AssemblerOutput="0"/> AssemblerOutput="0"/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="0"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\CVault.cpp"> RelativePath="..\CVault.cpp">
@ -679,6 +835,12 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AssemblerOutput="4"/> AssemblerOutput="4"/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="4"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\md5.cpp"> RelativePath="..\md5.cpp">
@ -712,6 +874,12 @@
Name="VCCLCompilerTool" Name="VCCLCompilerTool"
AssemblerOutput="2"/> AssemblerOutput="2"/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32">
<Tool
Name="VCCLCompilerTool"
AssemblerOutput="2"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\strptime.cpp"> RelativePath="..\strptime.cpp">
@ -757,6 +925,18 @@
<Tool <Tool
Name="VCCLCompilerTool"/> Name="VCCLCompilerTool"/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="JITDebugBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File> </File>
</Filter> </Filter>
</Filter> </Filter>
@ -778,6 +958,9 @@
<File <File
RelativePath="..\amxxlog.h"> RelativePath="..\amxxlog.h">
</File> </File>
<File
RelativePath="..\binlog.h">
</File>
<File <File
RelativePath="..\CCmd.h"> RelativePath="..\CCmd.h">
</File> </File>
@ -901,12 +1084,22 @@
<File <File
RelativePath="..\amxjitsn.asm"> RelativePath="..\amxjitsn.asm">
</File> </File>
<File
RelativePath="..\helpers-x86.asm">
</File>
<File <File
RelativePath="..\natives-amd64.asm"> RelativePath="..\natives-amd64.asm">
</File> </File>
<File <File
RelativePath="..\natives-x86.asm"> RelativePath="..\natives-x86.asm">
</File> </File>
<Filter
Name="Builds"
Filter="">
<File
RelativePath="..\Jit\helpers-x86.obj">
</File>
</Filter>
</Filter> </Filter>
<Filter <Filter
Name="SDK" Name="SDK"
@ -961,6 +1154,18 @@
<Tool <Tool
Name="VCCLCompilerTool"/> Name="VCCLCompilerTool"/>
</FileConfiguration> </FileConfiguration>
<FileConfiguration
Name="JITDebugBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
<FileConfiguration
Name="JITReleaseBinLog|Win32"
ExcludedFromBuild="TRUE">
<Tool
Name="VCCLCompilerTool"/>
</FileConfiguration>
</File> </File>
<File <File
RelativePath="..\sdk\amxxmodule.h"> RelativePath="..\sdk\amxxmodule.h">

View File

@ -0,0 +1,37 @@
Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "amxmodx", "amxmodx_mm.vcproj", "{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
JITDebug|Win32 = JITDebug|Win32
JITMemtestRelease|Win32 = JITMemtestRelease|Win32
JITRelease|Win32 = JITRelease|Win32
MaximalSpeed|Win32 = MaximalSpeed|Win32
MemtestDebug|Win32 = MemtestDebug|Win32
MemtestRelease|Win32 = MemtestRelease|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug|Win32.ActiveCfg = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Debug|Win32.Build.0 = Debug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.ActiveCfg = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITDebug|Win32.Build.0 = JITDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease|Win32.ActiveCfg = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITMemtestRelease|Win32.Build.0 = JITMemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.ActiveCfg = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.JITRelease|Win32.Build.0 = JITRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed|Win32.ActiveCfg = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MaximalSpeed|Win32.Build.0 = MaximalSpeed|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug|Win32.ActiveCfg = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestDebug|Win32.Build.0 = MemtestDebug|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease|Win32.ActiveCfg = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.MemtestRelease|Win32.Build.0 = MemtestRelease|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release|Win32.ActiveCfg = Release|Win32
{2BF64D1A-AC89-41B0-9D02-FB8CB610F850}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff

View File

@ -221,10 +221,18 @@ const char *Menu::GetTextString(int player, page_t page, int &keys)
m_Text.clear(); m_Text.clear();
char buffer[255]; char buffer[255];
if (m_AutoColors) if (items_per_page && (pages != 1))
_snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages); {
else if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages); _snprintf(buffer, sizeof(buffer)-1, "\\y%s %d/%d\n\\w\n", m_Title.c_str(), page + 1, pages);
else
_snprintf(buffer, sizeof(buffer)-1, "%s %d/%d\n\n", m_Title.c_str(), page + 1, pages);
} else {
if (m_AutoColors)
_snprintf(buffer, sizeof(buffer)-1, "\\y%s\n\\w\n", m_Title.c_str());
else
_snprintf(buffer, sizeof(buffer)-1, "%s\n\n", m_Title.c_str());
}
m_Text.append(buffer); m_Text.append(buffer);
@ -751,6 +759,39 @@ static cell AMX_NATIVE_CALL menu_setprop(AMX *amx, cell *params)
return 0; } \ return 0; } \
Menu *pMenu = g_NewMenus[p]; Menu *pMenu = g_NewMenus[p];
static cell AMX_NATIVE_CALL menu_cancel(AMX *amx, cell *params)
{
int index = params[1];
if (index < 1 || index > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Player %d is not valid", index);
return 0;
}
CPlayer *player = GET_PLAYER_POINTER_I(index);
if (!player->ingame)
{
LogError(amx, AMX_ERR_NATIVE, "Played %d is not in game", index);
return 0;
}
int menu = player->newmenu;
if (menu < 0 || menu >= (int)g_NewMenus.size() || !g_NewMenus[menu])
return 0;
Menu *pMenu = g_NewMenus[menu];
player->newmenu = -1;
player->menu = 0;
executeForwards(pMenu->func,
static_cast<cell>(index),
static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT));
return 1;
}
static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params) static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
{ {
GETMENU_R(params[1]); GETMENU_R(params[1]);
@ -766,12 +807,12 @@ static cell AMX_NATIVE_CALL menu_destroy(AMX *amx, cell *params)
player = GET_PLAYER_POINTER_I(i); player = GET_PLAYER_POINTER_I(i);
if (player->newmenu == pMenu->thisId) if (player->newmenu == pMenu->thisId)
{ {
player->newmenu = -1;
player->menu = 0;
executeForwards(pMenu->func, executeForwards(pMenu->func,
static_cast<cell>(i), static_cast<cell>(i),
static_cast<cell>(pMenu->thisId), static_cast<cell>(pMenu->thisId),
static_cast<cell>(MENU_EXIT)); static_cast<cell>(MENU_EXIT));
player->newmenu = -1;
player->menu = 0;
} }
} }
g_NewMenus[params[1]] = NULL; g_NewMenus[params[1]] = NULL;
@ -824,6 +865,7 @@ AMX_NATIVE_INFO g_NewMenuNatives[] =
{"menu_item_setname", menu_item_setname}, {"menu_item_setname", menu_item_setname},
{"menu_destroy", menu_destroy}, {"menu_destroy", menu_destroy},
{"menu_setprop", menu_setprop}, {"menu_setprop", menu_setprop},
{"menu_cancel", menu_cancel},
{"player_menu_info", player_menu_info}, {"player_menu_info", player_menu_info},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -1,6 +1,8 @@
#include <string.h> #include <string.h>
#include "optimizer.h" #include "optimizer.h"
int g_opt_level = 0;
#define OP_SYSREQ_C 123 #define OP_SYSREQ_C 123
#define OP_NOP 134 #define OP_NOP 134
#define OP_FLOAT_MUL 138 #define OP_FLOAT_MUL 138
@ -83,13 +85,31 @@ void _Setup_Optimizer_Stage2(AMX *amx, cell *oplist, cell *cip)
amx->usertags[UT_OPTIMIZER] = (void *)opt; amx->usertags[UT_OPTIMIZER] = (void *)opt;
FIND_NATIVE("floatmul", N_Float_Mul); if (g_opt_level & 1)
FIND_NATIVE("floatdiv", N_Float_Div); {
FIND_NATIVE("floatadd", N_Float_Add); FIND_NATIVE("floatmul", N_Float_Mul);
FIND_NATIVE("floatsub", N_Float_Sub); FIND_NATIVE("floatdiv", N_Float_Div);
FIND_NATIVE("float", N_Float_To); FIND_NATIVE("floatadd", N_Float_Add);
FIND_NATIVE("floatround", N_Float_Round); FIND_NATIVE("floatsub", N_Float_Sub);
FIND_NATIVE("floatcmp", N_Float_Cmp); }
if (g_opt_level & 4)
{
FIND_NATIVE("float", N_Float_To);
FIND_NATIVE("floatround", N_Float_Round);
}
if (g_opt_level & 2)
{
#if !defined AMD64
if (amxx_CpuSupport())
{
#endif
FIND_NATIVE("floatcmp", N_Float_Cmp);
#if !defined AMD64
} else {
g_opt_level &= ~(2);
}
#endif
}
//we don't do these yet because of radix stuff >:\ //we don't do these yet because of radix stuff >:\
//FIND_NATIVE("floatsin", N_Float_Sin); //FIND_NATIVE("floatsin", N_Float_Sin);
//FIND_NATIVE("floatcos", N_Float_Cos); //FIND_NATIVE("floatcos", N_Float_Cos);

View File

@ -22,5 +22,8 @@ struct optimizer_s
}; };
void SetupOptimizer(AMX *amx); void SetupOptimizer(AMX *amx);
extern "C" int amxx_CpuSupport();
extern int g_opt_level;
#endif //_INCLUDE_AMXMODX_OPTIMIZER_H #endif //_INCLUDE_AMXMODX_OPTIMIZER_H

View File

@ -32,6 +32,7 @@
#include <ctype.h> #include <ctype.h>
#include "amxmodx.h" #include "amxmodx.h"
#include "format.h" #include "format.h"
#include "binlog.h"
const char* stristr(const char* str, const char* substr) const char* stristr(const char* str, const char* substr)
{ {
@ -57,7 +58,18 @@ const char* stristr(const char* str, const char* substr)
char* format_amxstring(AMX *amx, cell *params, int parm, int& len) char* format_amxstring(AMX *amx, cell *params, int parm, int& len)
{ {
#if !defined BINLOG_ENABLED
return g_langMngr.FormatAmxString(amx, params, parm, len); return g_langMngr.FormatAmxString(amx, params, parm, len);
#else
char *ans = g_langMngr.FormatAmxString(amx, params, parm, len);
if (g_binlog_level & 4)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_FormatString, pl->getId(), parm, len, ans);
}
return ans;
#endif
} }
int amxstring_len(cell* a) int amxstring_len(cell* a)
@ -80,6 +92,15 @@ int set_amxstring(AMX *amx, cell amx_addr, const char *source, int max)
register cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr)); register cell* dest = (cell *)(amx->base + (int)(((AMX_HEADER *)amx->base)->dat + amx_addr));
register cell* start = dest; register cell* start = dest;
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_SetString, pl->getId(), amx_addr, max, source);
}
#endif
while (max-- && *source) while (max-- && *source)
*dest++ = (cell)*source++; *dest++ = (cell)*source++;
@ -99,6 +120,15 @@ extern "C" size_t get_amxstring_r(AMX *amx, cell amx_addr, char *destination, in
*dest = '\0'; *dest = '\0';
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, destination);
}
#endif
return dest - start; return dest - start;
} }
@ -113,6 +143,15 @@ char* get_amxstring(AMX *amx, cell amx_addr, int id, int& len)
len = --dest - start; len = --dest - start;
#if defined BINLOG_ENABLED
if (g_binlog_level & 2)
{
CPluginMngr::CPlugin *pl = g_plugins.findPluginFast(amx);
if (pl)
g_BinLog.WriteOp(BinLog_GetString, pl->getId(), amx_addr, start);
}
#endif
return start; return start;
} }
@ -757,7 +796,7 @@ do_copy:
i++; i++;
const char *start = had_quotes ? &(string[beg+1]) : &(string[beg]); const char *start = had_quotes ? &(string[beg+1]) : &(string[beg]);
size_t _end = had_quotes ? (i==len-1 ? 1 : 2) : 0; size_t _end = had_quotes ? (i==len-1 ? 1 : 2) : 0;
size_t end = (pos - _end > LeftMax) ? LeftMax : pos - _end; size_t end = (pos - _end > (size_t)LeftMax) ? (size_t)LeftMax : pos - _end;
size_t to_go = end-beg; size_t to_go = end-beg;
if (end && to_go) if (end && to_go)
{ {
@ -765,7 +804,7 @@ do_copy:
*left++ = (cell)*start++; *left++ = (cell)*start++;
} }
*left = '\0'; *left = '\0';
end = (len-i+1 > RightMax) ? RightMax : len-i+1; end = (len-i+1 > (size_t)RightMax) ? (size_t)RightMax : len-i+1;
if (end) if (end)
{ {
start = &(string[i]); start = &(string[i]);

View File

@ -27,8 +27,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,7,0,0 FILEVERSION 1,7,1,0
PRODUCTVERSION 1,7,0,0 PRODUCTVERSION 1,7,1,0
FILEFLAGSMASK 0x17L FILEFLAGSMASK 0x17L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -45,12 +45,12 @@ BEGIN
BEGIN BEGIN
VALUE "Comments", "AMX Mod X" VALUE "Comments", "AMX Mod X"
VALUE "FileDescription", "AMX Mod X" VALUE "FileDescription", "AMX Mod X"
VALUE "FileVersion", "1.70" VALUE "FileVersion", "1.71"
VALUE "InternalName", "amxmodx" VALUE "InternalName", "amxmodx"
VALUE "LegalCopyright", "Copyright (c) 2004-2006, AMX Mod X Dev Team" VALUE "LegalCopyright", "Copyright (c) 2004-2006, AMX Mod X Dev Team"
VALUE "OriginalFilename", "amxmodx_mm.dll" VALUE "OriginalFilename", "amxmodx_mm.dll"
VALUE "ProductName", "AMX Mod X" VALUE "ProductName", "AMX Mod X"
VALUE "ProductVersion", "1.70" VALUE "ProductVersion", "1.71"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

Binary file not shown.

View File

@ -14,3 +14,26 @@ amxx_vault addons/amxmodx/data/vault.ini
; 2 - one logfile / map ; 2 - one logfile / map
; 3 - HL Logs ; 3 - HL Logs
amxx_logging 1 amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -16,3 +16,26 @@ csstats addons/amxmodx/data/csstats.dat
; 2 - one logfile / map ; 2 - one logfile / map
; 3 - HL Logs ; 3 - HL Logs
amxx_logging 1 amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -17,3 +17,26 @@ amxx_logging 1
dodstats_score addons/amxmodx/data/dodstats.amxx dodstats_score addons/amxmodx/data/dodstats.amxx
dodstats addons/amxmodx/data/dodstats.dat dodstats addons/amxmodx/data/dodstats.dat
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -16,3 +16,26 @@ tfcstats addons/amxmodx/data/tfcstats.dat
; 2 - one logfile / map ; 2 - one logfile / map
; 3 - HL Logs ; 3 - HL Logs
amxx_logging 1 amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

View File

@ -16,3 +16,26 @@ tsstats addons/amxmodx/data/tsstats.dat
; 2 - one logfile / map ; 2 - one logfile / map
; 3 - HL Logs ; 3 - HL Logs
amxx_logging 1 amxx_logging 1
; Binary logging level
; add these up to get what you want
; these only work with bin logging binaries
; 1 - default
; 2 - log internal string sets/gets
; 4 - log internal formats
; 8 - log all native params
; 16 - log internal function calls (only in debug mode)
; 32 - log line number accesses (only in debug mode)
bin_logging 49
; Maximum binary log size, in megs
max_binlog_size 20
; Plugin optimization flags - add these up to get what you want
; lowering these may stop crashes on very old CPUs
; set 65536 to disable optimizer, NOT 0!
;-------------
; 1 - float arithmetic
; 2 - float comparisons
; 4 - float rounding
optimizer 7

34
dlls/arrayx/Array.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "amxxmodule.h"
#include "ComboArray.h"
extern AMX_NATIVE_INFO bintrie_exports[];
extern AMX_NATIVE_INFO bintrie_usage_exports[];
extern ComboArray MasterTrie;
extern AMX_NATIVE_INFO list_exports[];
extern AMX_NATIVE_INFO list_creation_exports[];
extern ComboArray MasterList;
extern AMX_NATIVE_INFO map_exports[];
extern AMX_NATIVE_INFO map_creation_exports[];
extern ComboArray MasterMap;
void OnAmxxAttach( void )
{
MF_AddNatives(bintrie_exports);
MF_AddNatives(bintrie_usage_exports);
MF_AddNatives(list_exports);
MF_AddNatives(list_creation_exports);
MF_AddNatives(map_exports);
MF_AddNatives(map_creation_exports);
}
void OnAmxxDetach( void )
{
JudyClearMasterTrie(&MasterTrie);
JudyClearMasterList(&MasterList);
JudyClearMasterMap(&MasterMap);
}

View File

@ -4,7 +4,7 @@
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=ARRAY - WIN32 RELEASE CFG=Array - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
@ -13,11 +13,12 @@ CFG=ARRAY - WIN32 RELEASE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "Array.mak" CFG="ARRAY - WIN32 RELEASE" !MESSAGE NMAKE /f "Array.mak" CFG="Array - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "Array - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "Array - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "Array - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
@ -27,45 +28,101 @@ CFG=ARRAY - WIN32 RELEASE
CPP=cl.exe CPP=cl.exe
MTL=midl.exe MTL=midl.exe
RSC=rc.exe RSC=rc.exe
!IF "$(CFG)" == "Array - Win32 Release"
# PROP BASE Use_MFC 0 # PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0 # PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release" # PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release" # PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir "" # PROP BASE Target_Dir ""
# PROP Use_MFC 2 # PROP Use_MFC 0
# PROP Use_Debug_Libraries 0 # PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release" # PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release" # PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir "" # PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARRAY_EXPORTS" /YX /FD /c # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARRAY_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /vmg /vms /GX /ZI /O2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARRAY_EXPORTS" /D "_WINDLL" /D "_AFXDLL" /U "DLLEXPORT" /FR /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARRAY_EXPORTS" /FR /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG" /d "_AFXDLL" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# SUBTRACT LINK32 /incremental:yes
!ELSEIF "$(CFG)" == "Array - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARRAY_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "ARRAY_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target # Begin Target
# Name "Array - Win32 Release" # Name "Array - Win32 Release"
# Name "Array - Win32 Debug"
# Begin Group "Source Files" # Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File # Begin Source File
SOURCE=.\amxxmodule.cpp SOURCE=.\Array.cpp
# SUBTRACT CPP /Z<none>
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\array.cpp SOURCE=.\BinTrieNatives.cpp
# SUBTRACT CPP /Z<none> /u # End Source File
# Begin Source File
SOURCE=.\Capsule.cpp
# End Source File
# Begin Source File
SOURCE=.\CArray.cpp
# End Source File
# Begin Source File
SOURCE=.\CBinTrie.cpp
# End Source File
# Begin Source File
SOURCE=.\CKeytable.cpp
# End Source File
# Begin Source File
SOURCE=.\JudyExtra.cpp
# End Source File
# Begin Source File
SOURCE=.\ListNatives.cpp
# End Source File
# Begin Source File
SOURCE=.\MapNatives.cpp
# End Source File # End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"
@ -73,7 +130,11 @@ SOURCE=.\array.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File # Begin Source File
SOURCE=.\amxxmodule.h SOURCE=.\BinTrieNativeFunctions.h
# End Source File
# Begin Source File
SOURCE=.\Capsule.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -81,6 +142,18 @@ SOURCE=.\CArray.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\CBaseList.h
# End Source File
# Begin Source File
SOURCE=.\CBaseMap.h
# End Source File
# Begin Source File
SOURCE=.\CBinTrie.h
# End Source File
# Begin Source File
SOURCE=.\CHashtable.h SOURCE=.\CHashtable.h
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -89,11 +162,23 @@ SOURCE=.\CKeytable.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\element.h SOURCE=.\ComboArray.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\moduleconfig.h SOURCE=.\ComboTable.h
# End Source File
# Begin Source File
SOURCE=.\GenericNatives.h
# End Source File
# Begin Source File
SOURCE=.\JudyIncludes.h
# End Source File
# Begin Source File
SOURCE=.\MapNativeFunctions.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"
@ -101,7 +186,51 @@ SOURCE=.\moduleconfig.h
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File # Begin Source File
SOURCE="..\module\Judy-1.0.1\src\Judy.lib" SOURCE=.\amxxmodule.cpp
# End Source File
# Begin Source File
SOURCE=.\amxxmodule.h
# End Source File
# Begin Source File
SOURCE=.\Judy.h
# End Source File
# Begin Source File
SOURCE=.\JudyEx.h
# End Source File
# Begin Source File
SOURCE=.\JudyExtra.h
# End Source File
# Begin Source File
SOURCE=.\JudyVar.h
# End Source File
# Begin Source File
SOURCE=.\JudyVec.h
# End Source File
# Begin Source File
SOURCE=.\ListNativeFunctions.h
# End Source File
# Begin Source File
SOURCE=.\moduleconfig.h
# End Source File
# Begin Source File
SOURCE=.\NativeIncludes.h
# End Source File
# Begin Source File
SOURCE=.\osdefs.h
# End Source File
# Begin Source File
SOURCE=.\Judy.lib
# End Source File # End Source File
# End Group # End Group
# End Target # End Target

29
dlls/arrayx/Array.dsw Normal file
View File

@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "Array"=".\Array.dsp" - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

Binary file not shown.

BIN
dlls/arrayx/Array.opt Normal file

Binary file not shown.

36
dlls/arrayx/Array.plg Normal file
View File

@ -0,0 +1,36 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: Array - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\Edward\LOCALS~1\Temp\RSP36D.tmp" with contents
[
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /pdb:"Release/Array.pdb" /machine:I386 /out:"Release/Array.dll" /implib:"Release/Array.lib"
".\Release\Array.obj"
".\Release\BinTrieNatives.obj"
".\Release\Capsule.obj"
".\Release\CArray.obj"
".\Release\CBinTrie.obj"
".\Release\CKeytable.obj"
".\Release\JudyExtra.obj"
".\Release\ListNatives.obj"
".\Release\MapNatives.obj"
".\Release\amxxmodule.obj"
".\Judy.lib"
]
Creating command line "link.exe @C:\DOCUME~1\Edward\LOCALS~1\Temp\RSP36D.tmp"
<h3>Output Window</h3>
Linking...
Creating library Release/Array.lib and object Release/Array.exp
LINK : warning LNK4098: defaultlib "LIBC" conflicts with use of other libs; use /NODEFAULTLIB:library
<h3>Results</h3>
Array.dll - 0 error(s), 1 warning(s)
</pre>
</body>
</html>

View File

@ -1,151 +0,0 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="Array"
SccProjectName=""
SccLocalPath=""
Keyword="MFCProj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="2"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/vmg /vms"
Optimization="2"
InlineFunctionExpansion="1"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;_USRDLL;ARRAY_EXPORTS"
StringPooling="TRUE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/Array.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
UndefinePreprocessorDefinitions="DLLEXPORT"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile=".\Release/array_amxx.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/Array.pdb"
ImportLibrary=".\Release/Array.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Release/Array.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath="amxxmodule.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/vmg /vms /vmg /vms"
Optimization="2"
PreprocessorDefinitions=""
BrowseInformation="1"
DebugInformationFormat="0"
UndefinePreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="array.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="/vmg /vms /vmg /vms"
Optimization="2"
PreprocessorDefinitions=""
BrowseInformation="1"
DebugInformationFormat="0"
UndefinePreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath="amxxmodule.h">
</File>
<File
RelativePath="CArray.h">
</File>
<File
RelativePath="CHashtable.h">
</File>
<File
RelativePath="CKeytable.h">
</File>
<File
RelativePath="element.h">
</File>
<File
RelativePath="moduleconfig.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
RelativePath=".\Judy-1.0.1\src\Judy.lib">
</File>
<File
RelativePath=".\osdefs.h">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,78 @@
#ifndef _bintrie_NATIVE_FUNC_INC_H
#define _bintrie_NATIVE_FUNC_INC_H
#define JUDY_GLUE_FUNC( x , y ) x ## y
#define JUDY_GLUE_STR( x, y ) #x#y
#define JUDY_MASTER_EDIT_FUNCTIONS
#define JUDY_MASTER_CLEAR_FUNC JUDY_GLUE_FUNC( bintrie , _clear )
#define JUDY_MASTER_CLEAR_STR JUDY_GLUE_STR ( bintrie , _clear )
#define JUDY_MASTER_DELETE_FUNC JUDY_GLUE_FUNC( bintrie , _delete )
#define JUDY_MASTER_DELETE_STR JUDY_GLUE_STR ( bintrie , _delete )
#define JUDY_MASTER_IO_FUNCTIONS
#define JUDY_MASTER_SAVE_FUNC JUDY_GLUE_FUNC( bintrie , _save )
#define JUDY_MASTER_SAVE_STR JUDY_GLUE_STR ( bintrie , _save )
#define JUDY_SAVE_FUNC(bin,file) JudySaveBinTrie(bin , file )
#define JUDY_MASTER_LOAD_FUNC JUDY_GLUE_FUNC( bintrie , _load )
#define JUDY_MASTER_LOAD_STR JUDY_GLUE_STR ( bintrie , _load )
#define JUDY_LOAD_FUNC(bin, file) JudyLoadBinTrie(bin , file )
#define JUDY_MASTER_AMOUNT_FUNCTIONS
#define JUDY_MASTER_COUNT_FUNC JUDY_GLUE_FUNC( bintrie , _count )
#define JUDY_MASTER_COUNT_STR JUDY_GLUE_STR ( bintrie , _count )
#define JUDY_MASTER_BYCOUNT_FUNC JUDY_GLUE_FUNC( bintrie , _bycount )
#define JUDY_MASTER_BYCOUNT_STR JUDY_GLUE_STR ( bintrie , _bycount )
#define JUDY_SLAVE_AMOUNT_FUNCTIONS
#define JUDY_SLAVE_COUNT_FUNC JUDY_GLUE_FUNC( bintrie , _size )
#define JUDY_SLAVE_COUNT_STR JUDY_GLUE_STR ( bintrie , _size )
#define JUDY_SLAVE_BYCOUNT_FUNC JUDY_GLUE_FUNC( bintrie , _get_nth )
#define JUDY_SLAVE_BYCOUNT_STR JUDY_GLUE_STR ( bintrie , _get_nth )
#define JUDY_SLAVE_EDIT_FUNCTIONS
#define JUDY_SLAVE_MEMORY_FUNC JUDY_GLUE_FUNC( bintrie , _memory )
#define JUDY_SLAVE_MEMORY_STR JUDY_GLUE_STR ( bintrie , _memory )
#define JUDY_SLAVE_ISFILLED_FUNC JUDY_GLUE_FUNC( bintrie , _isfilled )
#define JUDY_SLAVE_ISFILLED_STR JUDY_GLUE_STR ( bintrie , _isfilled )
#define JUDY_SLAVE_ISEMPTY_FUNC JUDY_GLUE_FUNC( bintrie , _isempty )
#define JUDY_SLAVE_ISEMPTY_STR JUDY_GLUE_STR ( bintrie , _isempty )
#define NO_JUDY_SLAVE_REMOVE_FUNC
#define JUDY_SLAVE_SEARCH_FUNCTIONS
#define JUDY_SLAVE_FIRST_FUNC JUDY_GLUE_FUNC( bintrie , _first )
#define JUDY_SLAVE_LAST_FUNC JUDY_GLUE_FUNC( bintrie , _last )
#define JUDY_SLAVE_FIRST_STR JUDY_GLUE_STR ( bintrie , _first )
#define JUDY_SLAVE_LAST_STR JUDY_GLUE_STR ( bintrie , _last )
#define JUDY_SLAVE_NEXT_FUNC JUDY_GLUE_FUNC( bintrie , _next )
#define JUDY_SLAVE_PREV_FUNC JUDY_GLUE_FUNC( bintrie , _prev )
#define JUDY_SLAVE_NEXT_STR JUDY_GLUE_STR ( bintrie , _next )
#define JUDY_SLAVE_PREV_STR JUDY_GLUE_STR ( bintrie , _prev )
#define JUDY_SLAVE_SEARCH_EMPTY_FUNCTIONS
#define JUDY_SLAVE_FIRSTEMPTY_FUNC JUDY_GLUE_FUNC( bintrie , _firstempty )
#define JUDY_SLAVE_LASTEMPTY_FUNC JUDY_GLUE_FUNC( bintrie , _lastempty )
#define JUDY_SLAVE_FIRSTEMPTY_STR JUDY_GLUE_STR ( bintrie , _firstempty )
#define JUDY_SLAVE_LASTEMPTY_STR JUDY_GLUE_STR ( bintrie , _lastempty )
#define JUDY_SLAVE_NEXTEMPTY_FUNC JUDY_GLUE_FUNC( bintrie , _nextempty )
#define JUDY_SLAVE_PREVEMPTY_FUNC JUDY_GLUE_FUNC( bintrie , _prevempty )
#define JUDY_SLAVE_NEXTEMPTY_STR JUDY_GLUE_STR ( bintrie , _nextempty )
#define JUDY_SLAVE_PREVEMPTY_STR JUDY_GLUE_STR ( bintrie , _prevempty )
#endif

View File

@ -0,0 +1,69 @@
#include "CBinTrie.h"
#define KEY_TYPE cell
#define DYNAMIC_UNIT_TYPE BinTrie
#define STORAGE_TYPE cell
#define MASTER_NAME MasterTrie
#define EXPORT_NAME bintrie_exports
#define SEARCH_ERROR_OFFSET 0
#define GET_KEY(params, num) params[num]
#define SET_KEY(stuff, parameter) stuff
#include "BinTrieNativeFunctions.h"
#include "NativeIncludes.h"
static cell AMX_NATIVE_CALL bintrie_create(AMX *amx,cell *params)
{
DTYPE* Unit;
M_ITYPE Index = params[1];
JUDY_CREATE_INDEX(MNAME,Unit,BinTrie,Index);
return Index;
}
static cell AMX_NATIVE_CALL bintrie_set(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
bool Value = (params[3] != NULL);
try { return Unit->Set(Indice, Value ); }
JUDY_ERROR_CATCH("Judy Error: (No error possible) - Slave Set Function ");
}
static cell AMX_NATIVE_CALL bintrie_get(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
try { return Unit->Get(Indice ); }
JUDY_ERROR_CATCH("Judy Error: (No error possible) - Slave Get Function ");
}
static cell AMX_NATIVE_CALL bintrie_remove(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
try { return Unit->Delete(Indice ); }
JUDY_ERROR_CATCH("Judy Error: (No error possible) - Slave Delete Function ");
}
AMX_NATIVE_INFO bintrie_usage_exports[] =
{
{ "bintrie_create", bintrie_create },
{ "bintrie_set", bintrie_set },
{ "bintrie_get", bintrie_get },
{ "bintrie_remove", bintrie_remove },
{ NULL, NULL }
};

87
dlls/arrayx/CArray.cpp Normal file
View File

@ -0,0 +1,87 @@
#include "CArray.h"
void Array::ThrowSearchError(char* type)
{
char value[50];
sprintf(value,"Function attempted to search %s: Judy returned NULL value", type);
throw JudyEx(value,false);
}
void Array::ThrowIndexError( cell index, bool disable_check )
{
if(disable_check == true) return;
char error[50];
sprintf(error,"Index %i is not set.",index);
throw JudyEx(error,true);
}
cell Array::First( cell Start)
{
PPvoid_t success = JudyLFirst(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:First");
return Start;
}
cell Array::FirstEmpty( cell Start)
{
cell success = JudyLFirstEmpty(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:FirstEmpty");
return Start;
}
cell Array::Next( cell Start)
{
PPvoid_t success = JudyLNext(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Next");
return Start;
}
cell Array::NextEmpty( cell Start)
{
cell success = JudyLNextEmpty(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:NextEmpty");
return Start;
}
cell Array::Prev( cell Start)
{
PPvoid_t success = JudyLPrev(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Prev");
return Start;
}
cell Array::PrevEmpty( cell Start)
{
cell success = JudyLPrevEmpty(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:PrevEmpty");
return Start;
}
cell Array::Last( cell Start)
{
PPvoid_t success = JudyLLast(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Last");
return Start;
}
cell Array::LastEmpty( cell Start)
{
cell success = JudyLLastEmpty(Table, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:LastEmpty");
return Start;
}
cell Array::ByCount(cell n, cell Start)
{
PPvoid_t success = JudyLByCount(Table, n, reinterpret_cast<Word_t *>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Nth");
return Start;
}

View File

@ -1,734 +1,74 @@
Pvoid_t MasterArray = (Pvoid_t) NULL; //Create the control array #ifndef _ARRAYCLASS_H
#define _ARRAYCLASS_H
//Create an array that stores whether or not indices are used. #include "JudyIncludes.h"
Pvoid_t MasterArray_Binary = (Pvoid_t) NULL; #include "CBaseList.h"
#include "JudyExtra.h"
//#include <JudyL.h>
void DeleteMasterArray(void); class Array: public CBaseList
Word_t NewArray(Word_t Index, Word_t reserve = 0);
PPvoid_t Find_Array(Word_t Index, Word_t disable_check = 1, AMX *amx = 0);
void DeleteArray(Word_t Index);
void ClearArray(Word_t Index);
template <class Type>
void Array_Set(PPvoid_t Array, char* Index, Type value);
PPvoid_t Array_Get(AMX* amx, PPvoid_t Array, Word_t Index, int ignore_error = 0);
void DeleteCell(Pvoid_t* Array, Word_t Index);
void Delete_MasterArray(void)
{ {
Word_t private:
Index = 0, Pvoid_t Table;
success = 0;
J1F(success, MasterArray_Binary, Index); void ThrowIndexError( cell index, bool disable_check = false );
while( success ) void ThrowSearchError(char* msg);
public:
Array() { Table = NULL; }
~Array() { Clear(); }
void Remove() { delete this; }
Word_t Clear() { JudyClearList(this); return JudyLFreeArray(&Table, PJE0); }
Word_t MemoryUsed() { return JudyLMemUsed(Table); }
int Delete(cell Key) { return JudyLDel(&Table, Key, PJE0 ); }
void Set(cell Index, Pvoid_t value, bool disable_check)
{ {
DeleteArray( Index ); //Delete array. PPvoid_t PValue = JudyLIns(&Table, Index,PJE0);
J1F(success, MasterArray_Binary, Index); //Get next array *PValue = value;
} }
}
Word_t NewArray(Word_t Index, Word_t reserve) Pvoid_t Get(cell Index, bool disable_check = false)
{
Word_t success; //Dummy for macros.
J1T(success, MasterArray_Binary, Index); //Check if bit is already set.
if (success && reserve)
return Index; //If the bit is set but it's 'reserved', return the index.
//Only do this if the bit is not set.
J1FE(success, MasterArray_Binary, Index);
J1S(success, MasterArray_Binary, Index);
PPvoid_t Array = JudyLIns(&MasterArray, Index, PJE0);
*Array = (PWord_t) NULL;
return Index;
}
PPvoid_t Find_Array(Word_t Index, Word_t disable_check, AMX *amx)
{
Word_t success;
J1T(success, MasterArray_Binary, Index);
if (success || disable_check)
{ //Bit is valid
if(!success)
NewArray(Index);
return JudyLGet( MasterArray, Index, PJE0);
}
MF_LogError(amx,AMX_ERR_NATIVE,"Array %d is invalid", Index);
return NULL;
}
void DeleteArray(Word_t Index)
{
int success;
J1T(success, MasterArray_Binary, Index);
if (success)
{ //If the bit is set, clear and delete array.
ClearArray(Index);
J1U(success, MasterArray_Binary, Index);
JudyLDel(&MasterArray, Index, PJE0);
}
}
void ClearArray(Word_t Index)
{
int success;
J1T(success, MasterArray_Binary, Index);
if (success) //dont bother with unset arrays.
{ {
PPvoid_t Array = Find_Array(Index); PPvoid_t PValue = JudyLGet(Table, Index, PJE0);
Word_t index = 0; if(PValue == NULL) { ThrowIndexError(Index, disable_check); return NULL; }
PPvoid_t PValue = JudyLFirst(*Array, &index, PJE0);
while (PValue != NULL) return *PValue;
{
element elem_value = *reinterpret_cast<element*>(*PValue);
elem_value.delete_element();
PValue = JudyLNext(*Array, &index, PJE0);
}
JudyLFreeArray(Array, PJE0);
} }
}
static cell AMX_NATIVE_CALL new_array(AMX *amx,cell *params) template<class Type>
{ void Set(cell Index, Type value)
return NewArray(params[1], params[2]);
}
template <class Type> //This will support input char*, Vector*, int, and cell_real*.
void Array_Set(PPvoid_t Array, int Index, Type value)
{
PPvoid_t PValue; // pointer to array element value
PValue = JudyLIns(Array, Index, PJE0);
*PValue = reinterpret_cast<void*>(value);
}
PPvoid_t Array_Get(AMX* amx, PPvoid_t Array, int Index, int ignore_error = 0)
{
PPvoid_t PValue = JudyLGet( *Array, Index, PJE0 );
if (PValue == NULL && !ignore_error)
MF_LogError(amx, AMX_ERR_NATIVE, "Array index %d is invalid", Index);
return PValue;
}
void DeleteCell(PPvoid_t Array, Word_t Index)
{
JudyLDel(Array, Index, PJE0);
}
static cell AMX_NATIVE_CALL delete_array(AMX *amx,cell *params)
{
DeleteArray( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL clear_array(AMX *amx,cell *params)
{
ClearArray( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL Array_Save(AMX *amx, cell *params)
{
PPvoid_t Array = Find_Array(params[1], params[3], amx);
if (Array == NULL) return 0;
int filename_length;
char *file = MF_GetAmxString(amx, params[2], 0, &filename_length);
file = MF_BuildPathname("%s", file);
unlink(file);
FILE *ArrayDB = fopen(file,"w");
if (!ArrayDB)
return 0;
Word_t Index = 0;
PPvoid_t PValue = JudyLFirst(*Array, &Index, PJE0);
element elem = NULL;
char elem_type = 0;
int error;
REAL vector_data[3] = { 0.0, 0.0, 0.0 };
while (PValue)
{ {
elem = *reinterpret_cast<element*>(*PValue); PPvoid_t PValue = JudyLIns(&Table, Index,PJE0);
elem_type = elem.get_type(); *PValue = reinterpret_cast<void*>(value);
if (elem_type < elem_type_int || elem_type > elem_type_vector)
continue;
fwrite(&Index, sizeof(int), 1, ArrayDB);
fwrite(&elem_type, sizeof(char), 1, ArrayDB);
if (elem_type == elem_type_int)
{
int int_buffer = elem.get_int(error);
fwrite(&int_buffer, sizeof(int), 1, ArrayDB);
}
else if (elem_type == elem_type_real)
{
REAL flo_buffer = elem.get_flo(error);
fwrite(&flo_buffer, sizeof(REAL), 1, ArrayDB);
}
else if (elem_type == elem_type_char)
{
const char* str_buffer = elem.get_str(error);
short buf_len = strlen(str_buffer);
fwrite(&buf_len, sizeof(short), 1, ArrayDB);
fwrite(str_buffer, sizeof(char), buf_len, ArrayDB);
}
else if (elem_type == elem_type_vector)
{
const Vector* vec_buffer = elem.get_vec(error);
fwrite(vec_buffer, sizeof(Vector), 1, ArrayDB);
}
PValue = JudyLNext(*Array, &Index, PJE0);
} }
fclose(ArrayDB);
return 1;
}
static cell AMX_NATIVE_CALL Array_Load(AMX *amx, cell *params) template <class Type>
{ Type Get(cell Index, Type example, bool disable_check = false)
//params[1]: file
int filename_length;
char *file = MF_GetAmxString(amx, params[1], 0, &filename_length);
file = MF_BuildPathname("%s", file);
FILE *ArrayDB = fopen(file, "a+");
if (!ArrayDB)
return 0;
//params[2]: array to create (optional index supplied)
int ArrayIndex = NewArray(params[2], params[3]);
ClearArray(ArrayIndex); //make sure the array is empty.
PPvoid_t Array = Find_Array(ArrayIndex);
while(!feof(ArrayDB))
{ {
int index = 0; char type = 0; PPvoid_t PValue = JudyLGet(Table, Index, PJE0);
element *elem_value = NULL; if(PValue == NULL) { ThrowIndexError(Index, disable_check); return (Type)NULL; }
fread(&index, sizeof(int), 1, ArrayDB);
if (feof(ArrayDB) || ferror(ArrayDB))
break;
fread(&type, sizeof(char), 1, ArrayDB); return (Type)(*PValue);
if (type < elem_type_int || type > elem_type_vector)
{
MF_LogError(amx, AMX_ERR_FORMAT, "Error loading array database \"%s\" into array %d. Bad file.", file, ArrayIndex);
return ArrayIndex;
}
else if (type == elem_type_int)
{
int value = 0; fread(&value, sizeof(int), 1, ArrayDB);
elem_value = new element(value);
}
else if (type == elem_type_real)
{
REAL value = 0; fread(&value, sizeof(REAL), 1, ArrayDB);
elem_value = new element(value);
}
else if (type == elem_type_char)
{
short length; fread(&length, sizeof(short), 1, ArrayDB);
char* value = new char[length+1]; fgets(value, length+1, ArrayDB);
elem_value = new element(value);
delete(value);
}
else if (type == elem_type_vector)
{
Vector *value = new Vector(); fread(value, sizeof(Vector), 1, ArrayDB);
elem_value = new element(value);
}
Array_Set(Array,index,elem_value);
} }
fclose(ArrayDB);
return ArrayIndex;
}
static cell AMX_NATIVE_CALL Array_Save_ASCII(AMX *amx, cell *params) cell First(cell Start = 0);
{ cell Next(cell Start = 0);
//params[1]: file cell Prev(cell Start = -1);
int filename_length; cell Last(cell Start = -1);
char *inputfile = MF_GetAmxString(amx, params[1], 0, &filename_length);
inputfile = MF_BuildPathname("%s", inputfile);
FILE *ArrayDB = fopen(inputfile, "a+");
if (!ArrayDB)
return 0;
char *outputfile = MF_GetAmxString(amx, params[2], 0, &filename_length); cell FirstEmpty(cell Start = 0);
outputfile = MF_BuildPathname("%s", outputfile); cell NextEmpty(cell Start = 0);
FILE *ReadableDB = fopen(outputfile, "w"); cell PrevEmpty(cell Start = -1);
cell LastEmpty(cell Start = -1);
char *buffer = "\0"; cell ByCount(cell n, cell Start = 0);
char *buffer_two = "\0"; cell Count(cell Start = 0, cell Stop = -1) { return JudyLCount(Table, Start, Stop, PJE0); }
while(!feof(ArrayDB)) bool IsFilled(cell Index) { return ( (Get(Index, true ) != NULL) ? true : false); }
{ bool IsEmpty(cell Index) { return ( (Get(Index, true ) == NULL) ? true : false); }
Word_t index = 0; char type = 0;
fread(&index, sizeof(int), 1, ArrayDB);
if (feof(ArrayDB) || ferror(ArrayDB))
break;
fread(&type, sizeof(char), 1, ArrayDB);
sprintf(buffer, "Index % 11d\tType %7s,", index, elem_types[type]);
if (type < elem_type_int || type > elem_type_vector)
{
MF_LogError(amx, AMX_ERR_FORMAT, "Error loading array database \"%s\" into readable format. Bad file.", inputfile);
return 0;
}
else if (type == elem_type_int)
{
int value = 0; fread(&value, sizeof(int), 1, ArrayDB);
sprintf(buffer, "%s\t\t\tValue: %d\n", buffer, value);
}
else if (type == elem_type_real)
{
REAL value = 0; fread(&value, sizeof(REAL), 1, ArrayDB);
sprintf(buffer, "%s\t\t\tValue: %f\n", buffer, value);
}
else if (type == elem_type_char)
{
short length; fread(&length, sizeof(short), 1, ArrayDB);
char* value = new char[length+1]; fgets(value, length+1, ArrayDB);
sprintf(buffer, "%s Length: %d\tValue: \"%s\"\n", buffer, length, value);
delete value;
}
else if (type == elem_type_vector)
{
Vector *value = new Vector(); fread(value, sizeof(Vector), 1, ArrayDB);
sprintf(buffer, "%s\t\t\tValue: {%f,%f,%f}\n", buffer, (*value).x, (*value).y, (*value).z);
delete value;
}
fwrite(buffer, sizeof(char), strlen(buffer), ReadableDB);
}
fclose(ArrayDB);
fclose(ReadableDB);
return 1;
}
static cell AMX_NATIVE_CALL Array_SetVector(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1], params[4], amx);
if (Array == NULL) return 0;
cell *input_vec = MF_GetAmxAddr(amx, params[3]);
Vector *value = new Vector(
amx_ctof(input_vec[0]),
amx_ctof(input_vec[1]),
amx_ctof(input_vec[2])
);
int Index = params[2];
PPvoid_t PValue = Array_Get(amx, Array, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(value);
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_vec(value);
}
Array_Set(Array,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Array_GetVector(AMX *amx, cell *params)
{
PPvoid_t Array = Find_Array(params[1], params[4], amx);
if (Array == NULL) return 0;
int Index = params[2];
PPvoid_t PValue = Array_Get(amx, Array, Index, params[4]);
cell *vAmx = MF_GetAmxAddr(amx, params[3]);
if( PValue == NULL ) {
vAmx[0] = amx_ftoc(0);
vAmx[1] = amx_ftoc(0);
vAmx[2] = amx_ftoc(0);
return 0;
}
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
const Vector retr_vec = *elem_value.get_vec(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
vAmx[0] = amx_ftoc(retr_vec.x);
vAmx[1] = amx_ftoc(retr_vec.y);
vAmx[2] = amx_ftoc(retr_vec.z);
return 1;
}
static cell AMX_NATIVE_CALL Array_SetString(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1], params[4], amx);
if (Array == NULL) return 0;
//params[2]: index
int Index = params[2];
//params[3]: value
int iLen = 0;
char *value = MF_GetAmxString(amx,params[3],1,&iLen);
//element that is stored at index
PPvoid_t PValue = Array_Get(amx, Array, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(value);
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_str(value);
}
Array_Set(Array,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Array_GetString(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1], params[5], amx);
if (Array == NULL) return 0;
//params[2]: index
int Index = params[2];
Pvoid_t * PValue = Array_Get(amx, Array, Index, params[5]);
//params[3] and params[4] are the return string and length respectively.
if( PValue == NULL ) return MF_SetAmxString( amx , params[3] , "dne", params[4] );
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
const char* str_out = elem_value.get_str(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return MF_SetAmxString( amx , params[3] , str_out, params[4] );
}
static cell AMX_NATIVE_CALL Array_SetFloat(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1], params[4], amx);
if (Array == NULL) return 0;
//params[2]: index
int Index = params[2];
//params[3]: value
PPvoid_t PValue = Array_Get(amx, Array, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(amx_ctof(params[3]));
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_flo(amx_ctof(params[3]));
}
Array_Set(Array,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Array_GetFloat(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1], params[3], amx);
if (Array == NULL) return 0;
//params[2]: index
int Index = params[2];
PPvoid_t PValue = Array_Get(amx, Array, Index, params[3]);
if( PValue == NULL ) return amx_ftoc(0.0);
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
cell retr_float = amx_ftoc(elem_value.get_flo(error));
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return retr_float;
}
static cell AMX_NATIVE_CALL Array_SetInt(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1], params[3], amx);
if (Array == NULL) return 0;
//params[2]: index
int Index = params[2];
PPvoid_t PValue = Array_Get(amx, Array, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(params[3]);
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_int(params[3]);
}
Array_Set(Array,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Array_GetInt(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1], params[3], amx);
if (Array == NULL) return 0;
//params[2]: index
int Index = params[2];
Pvoid_t * PValue = Array_Get(amx, Array, Index, params[3]);
if( PValue == NULL ) return 0;
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
cell retr_int = elem_value.get_int(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return retr_int;
}
static cell AMX_NATIVE_CALL array_size(AMX *amx,cell *params)
{
Pvoid_t * Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
return JudyLCount( *Array, params[2], params[3],PJE0);
}
static cell AMX_NATIVE_CALL array_count(AMX *amx,cell *params)
{
return JudyLCount( MasterArray, params[1], params[2],PJE0);
}
static cell AMX_NATIVE_CALL array_memory(AMX *amx,cell *params)
{
Pvoid_t * Array = Find_Array(params[1],params[2],amx);
if (Array == NULL) return 0;
return JudyLMemUsed(*Array);
}
static cell AMX_NATIVE_CALL delete_cell(AMX *amx,cell *params)
{
Pvoid_t * Array = Find_Array(params[1]);
if (Array == NULL) return 0;
DeleteCell( Array, params[2] );
return 1;
}
static cell AMX_NATIVE_CALL array_next(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = Word_t(params[2]);
cell *success = MF_GetAmxAddr(amx, params[3]);
PPvoid_t pointer;
pointer = JudyLNext(*Array, &Index, PJE0);
*success = (pointer == NULL) ? 0 : 1;
return cell(Index);
}
static cell AMX_NATIVE_CALL array_prev(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = Word_t(params[2]);
cell *success = MF_GetAmxAddr(amx, params[3]);
PPvoid_t pointer;
pointer = JudyLPrev(*Array, &Index, PJE0);
*success = (pointer == NULL) ? 0 : 1;
return cell(Index);
}
static cell AMX_NATIVE_CALL array_first(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = Word_t(params[2]);
cell *success = MF_GetAmxAddr(amx, params[3]);
PPvoid_t pointer;
pointer = JudyLFirst(*Array, &Index, PJE0);
*success = (pointer == NULL) ? 0 : 1;
return cell(Index);
}
static cell AMX_NATIVE_CALL array_last(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = Word_t(params[2]);
cell *success = MF_GetAmxAddr(amx, params[3]);
PPvoid_t pointer;
pointer = JudyLLast(*Array, &Index, PJE0);
*success = (pointer == NULL) ? 0 : 1;
return cell(Index);
}
static cell AMX_NATIVE_CALL array_nextempty(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = (Word_t)params[2];
cell *success = MF_GetAmxAddr(amx, params[3]);
*success = JudyLNextEmpty(*Array, &Index, PJE0);
return (cell)Index;
}
static cell AMX_NATIVE_CALL array_prevempty(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = (Word_t)params[2];
cell *success = MF_GetAmxAddr(amx, params[3]);
*success = JudyLPrevEmpty(*Array, &Index, PJE0);
return (cell)Index;
}
static cell AMX_NATIVE_CALL array_firstempty(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = (Word_t)params[2];
cell *success = MF_GetAmxAddr(amx, params[3]);
*success = JudyLFirstEmpty(*Array, &Index, PJE0);
return (cell)Index;
}
static cell AMX_NATIVE_CALL array_lastempty(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = (Word_t)params[2];
cell *success = MF_GetAmxAddr(amx, params[3]);
*success = JudyLLastEmpty(*Array, &Index, PJE0);
return (cell)Index;
}
static cell AMX_NATIVE_CALL array_isempty(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[3],amx);
if (Array == NULL) return 0;
PPvoid_t pointer;
pointer = JudyLGet(*Array, params[2], PJE0);
return (pointer == NULL) ? 1 : 0;
}
static cell AMX_NATIVE_CALL array_isfilled(AMX *amx,cell *params)
{
//params[1]: array
PPvoid_t Array = Find_Array(params[1],params[3],amx);
if (Array == NULL) return 0;
//params[2]: index
PPvoid_t pointer;
pointer = JudyLGet(*Array, params[2], PJE0);
return (pointer != NULL) ? 1 : 0;
}
static cell AMX_NATIVE_CALL Array_ByCount(AMX *amx,cell *params)
{
PPvoid_t Array = Find_Array(params[1],params[4],amx);
if (Array == NULL) return 0;
Word_t Index = Word_t(params[3]);
cell *success = MF_GetAmxAddr(amx, params[4]);
PPvoid_t pointer;
pointer = JudyLByCount(*Array, params[2], &Index, PJE0);
*success = (pointer == NULL) ? 0 : 1;
return cell(Index);
}
AMX_NATIVE_INFO array_exports[] = {
{ "array_set_string", Array_SetString },
{ "array_get_string", Array_GetString },
{ "array_set_int", Array_SetInt },
{ "array_get_int", Array_GetInt },
{ "array_set_float", Array_SetFloat },
{ "array_get_float", Array_GetFloat },
{ "array_set_vector", Array_SetVector },
{ "array_get_vector", Array_GetVector },
{ "array_isempty", array_isempty },
{ "array_isfilled", array_isfilled },
{ "array_remove", delete_cell },
{ "array_create", new_array },
{ "array_delete", delete_array },
{ "array_clear", clear_array },
{ "array_size", array_size },
{ "array_count", array_count },
{ "array_memory", array_memory },
{ "array_nextempty", array_nextempty },
{ "array_prevempty", array_prevempty },
{ "array_firstempty", array_firstempty },
{ "array_lastempty", array_lastempty },
{ "array_next", array_next },
{ "array_prev", array_prev },
{ "array_first", array_first },
{ "array_last", array_last },
{ "array_save", Array_Save },
{ "array_load", Array_Load },
{ "array_get_nth", Array_ByCount },
{ "array_save_ascii", Array_Save_ASCII },
{ NULL, NULL }
}; };
#endif

36
dlls/arrayx/CBaseList.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef _BASE_ARRAYCLASS_H
#define _BASE_ARRAYCLASS_H
#include "JudyIncludes.h"
class CBaseList
{
public:
virtual Word_t Clear() =0;
virtual Word_t MemoryUsed() =0;
virtual int Delete(cell Key) =0;
virtual void Remove() =0;
virtual void Set(cell Index, Pvoid_t value, bool disable_check = false) =0;
virtual Pvoid_t Get(cell Index, bool disable_check = false) =0;
virtual cell First(cell Start = 0) =0;
virtual cell Next(cell Start = 0) =0;
virtual cell Prev(cell Start = -1) =0;
virtual cell Last(cell Start = -1) =0;
virtual cell FirstEmpty(cell Start = 0) =0;
virtual cell NextEmpty(cell Start = 0) =0;
virtual cell PrevEmpty(cell Start = -1) =0;
virtual cell LastEmpty(cell Start = -1) =0;
virtual cell ByCount(cell n, cell Start = 0) =0;
virtual cell Count(cell Start = 0, cell Stop = -1) =0;
virtual bool IsFilled(cell Index) =0;
virtual bool IsEmpty(cell Index) =0;
};
#endif

29
dlls/arrayx/CBaseMap.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef _BASE_MAPCLASS_H
#define _BASE_MAPCLASS_H
#include "JudyIncludes.h"
class CBaseMap
{
public:
virtual Word_t Clear() =0;
virtual Word_t MemoryUsed() =0;
virtual int Delete(char* Key) =0;
virtual void Remove() =0;
virtual void Set(char* Index, Pvoid_t value, bool disable_check = false) =0;
virtual Pvoid_t Get(char* Index, bool disable_check = false) =0;
virtual char* First(char* Start = "") =0;
virtual char* Next(char* Start) =0;
virtual char* Prev(char* Start) =0;
virtual char* Last(char* Start) =0;
virtual bool IsFilled(char* Index) =0;
virtual bool IsEmpty(char* Index) =0;
};
#endif

76
dlls/arrayx/CBinTrie.cpp Normal file
View File

@ -0,0 +1,76 @@
#include "CBinTrie.h"
void BinTrie::ThrowSearchError(char* type)
{
char value[50];
sprintf(value,"Function attempted to search %s: Judy returned NULL value", type);
throw JudyEx (value,false);
}
cell BinTrie::First( cell Start)
{
cell success = Judy1First(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:First");
return Start;
}
cell BinTrie::FirstEmpty( cell Start)
{
cell success = Judy1FirstEmpty(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:FirstEmpty");
return Start;
}
cell BinTrie::Next( cell Start)
{
cell success = Judy1Next(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Next");
return Start;
}
cell BinTrie::NextEmpty( cell Start)
{
cell success = Judy1NextEmpty(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:NextEmpty");
return Start;
}
cell BinTrie::Prev( cell Start)
{
cell success = Judy1Prev(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Prev");
return Start;
}
cell BinTrie::PrevEmpty( cell Start)
{
cell success = Judy1PrevEmpty(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:PrevEmpty");
return Start;
}
cell BinTrie::Last( cell Start)
{
cell success = Judy1Last(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Last");
return Start;
}
cell BinTrie::LastEmpty( cell Start)
{
cell success = Judy1LastEmpty(Table, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:LastEmpty");
return Start;
}
cell BinTrie::ByCount(cell n, cell Start)
{
cell success = Judy1ByCount(Table, n, reinterpret_cast<unsigned int*>(&Start), PJE0);
if (success == NULL) ThrowSearchError("Type:Nth");
return Start;
}

54
dlls/arrayx/CBinTrie.h Normal file
View File

@ -0,0 +1,54 @@
#ifndef _BINTRIECLASS_H
#define _BINTRIECLASS_H
#include "JudyIncludes.h"
#include "JudyExtra.h"
//#include <Judy1.h>
class BinTrie
{
private:
Pvoid_t Table;
void ThrowSearchError(char* msg);
public:
BinTrie() { Table = NULL; }
~BinTrie() { Clear(); }
void Remove() { delete this; }
Word_t Clear() { JudyClearBinTrie(this); return Judy1FreeArray(&Table, PJE0); }
Word_t MemoryUsed() { return Judy1MemUsed(Table); }
cell Delete(cell Key) { return Judy1Unset(&Table, Key, PJE0 ); }
cell Set(cell Index, bool val)
{
if(val == false) return Delete(Index);
else return Judy1Set(&Table, Index,PJE0);
}
cell Get(cell Index)
{
cell PValue = Judy1Test(Table, Index, PJE0);
return PValue;
}
cell First(cell Start = 0);
cell Next(cell Start = 0);
cell Prev(cell Start = -1);
cell Last(cell Start = -1);
cell FirstEmpty(cell Start = 0);
cell NextEmpty(cell Start = 0);
cell PrevEmpty(cell Start = -1);
cell LastEmpty(cell Start = -1);
cell ByCount(cell n, cell Start);
cell Count(cell Start = 0, cell Stop = -1) { return Judy1Count(Table, Start, Stop, PJE0); }
bool IsFilled(cell Index) { return ( (Get(Index )) ? true : false); }
bool IsEmpty(cell Index) { return ( (Get(Index )) ? true : false); }
};
#endif

View File

@ -1,375 +1,82 @@
#if !defined _JUDYHS_ENABLED_ #ifndef _HASHCLASS_INCLUDED
#define _JUDYHS_ENABLED_ #define _HASHCLASS_INCLUDED
Pvoid_t MasterHashtable = (Pvoid_t) NULL; //Create the new array #include "JudyIncludes.h"
#include "CBaseMap.h"
//#include <JudyHS.h>
//Create an array that stores whether or not indices are used. class Hashtable: public CBaseMap
Pvoid_t MasterHashtable_Binary = (Pvoid_t) NULL;
void Delete_MasterHashtable(void);
Word_t New_Hashtable(Word_t Index, Word_t reserve = 0);
Pvoid_t* Find_Hashtable(Word_t Index, Word_t disable_check = 1, AMX *amx = 0);
void Delete_Hashtable(Word_t Index);
void Clear_Hashtable(Word_t Index);
template <class Type>
void Hashtable_Set(PPvoid_t Hashtable, char *Index, Word_t Length, Type value);
PPvoid_t Hashtable_Get(AMX* amx, Pvoid_t Hashtable, char *Index, int ignore_error = 0);
void Delete_MasterHashtable(void)
{ {
Word_t private:
Index = 0, Pvoid_t Table;
success;
J1F(success, MasterHashtable_Binary, Index); public:
while( success ) Hashtable() { Table = NULL; }
~Hashtable() { Clear(); }
void Remove() { delete this; }
Word_t Clear() { return JudyHSFreeArray(&Table, PJE0); }
Word_t MemoryUsed() { return JudyLMemUsed(Table); }
int Delete(char* Key) { return JudyHSDel(&Table, Key, strlen(Key), PJE0 ); }
void Set(char* Index, Pvoid_t value, bool disable_check)
{ {
Delete_Hashtable(Index); int Len = strlen(Index) + 1;
J1F(success, MasterHashtable_Binary, Index); PPvoid_t PValue = JudyHSIns(&Table, Index, Len, PJE0);
*PValue = value;
} }
}
Word_t New_Hashtable(Word_t Index, Word_t reserve) Pvoid_t Get(char* Index, bool disable_check = false)
{
Word_t success; //Dummy for macros.
J1T(success, MasterHashtable_Binary, Index);
if (success && reserve)
return Index; //If the bit is set but it's 'reserved', return the index.
//Only do this if the bit is not set or not reserved.
J1FE(success, MasterHashtable_Binary, Index);
J1S(success, MasterHashtable_Binary, Index);
PPvoid_t Hashtable = JudyLIns(&MasterHashtable, Index, PJE0);
*Hashtable = (PWord_t) NULL;
return Index;
}
PPvoid_t Find_Hashtable(Word_t Index, Word_t disable_check, AMX* amx)
{
Word_t success;
J1T(success, MasterHashtable_Binary, Index);
if (success || disable_check)
{ //Bit is valid
if(!success)
New_Hashtable(Index);
return JudyLGet(MasterHashtable, Index, PJE0);
}
MF_LogError(amx,AMX_ERR_NATIVE,"Hashtable %d is invalid.", Index);
return NULL;
}
void Delete_Hashtable(Word_t Index)
{
int success;
J1T(success, MasterHashtable_Binary, Index);
if (success)
{ //If the bit was set, clear, unset and delist hashtable.
Clear_Hashtable(Index);
J1U(success, MasterHashtable_Binary, Index);
JudyLDel(&MasterHashtable, Index, PJE0);
}
}
void Clear_Hashtable(Word_t Index)
{
int success;
J1T(success, MasterHashtable_Binary, Index);
if (success) //dont bother with unset hashtables.
{ {
PPvoid_t Hashtable = Find_Hashtable(Index); PPvoid_t PValue = JudyHSGet(Table, Index, strlen(Index)+1);
JHSFA(success, *Hashtable); if(PValue == NULL) { ThrowIndexError(Index, disable_check); return NULL; }
return *PValue;
} }
}
template <class Type> //This will support input char*, Vector*, int, and cell_real*. template <class Type>
void Hashtable_Set(PPvoid_t Hashtable, char* Index, Type value) void Set(char* Index, Type value)
{
int Len = strlen(Index)+1;
PPvoid_t PValue = JudyHSIns(Hashtable, Index, Len, PJE0);
*PValue = reinterpret_cast<void*>(value);
}
PPvoid_t Hashtable_Get(AMX* amx,PPvoid_t Hashtable, char *Index, int ignore_error = 0)
{
PPvoid_t PValue = JudyHSGet(*Hashtable, Index, strlen(Index)+1);
if (PValue == NULL && !ignore_error)
MF_LogError(amx, AMX_ERR_NATIVE, "Hashtable get on index \"%s\" is invalid", Index);
return PValue;
}
static cell AMX_NATIVE_CALL Hashtable_Create(AMX *amx, cell *params)
{
return New_Hashtable(params[1],params[2]);
}
static cell AMX_NATIVE_CALL Hashtable_Delete(AMX *amx, cell *params)
{
Delete_Hashtable( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL Hashtable_Clear(AMX *amx, cell *params)
{
Clear_Hashtable( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL Hashtable_SetVector(AMX *amx,cell *params)
{
PPvoid_t Hashtable = Find_Hashtable(params[1], params[4], amx);
if (Hashtable == NULL) return 0;
cell *input_vec = MF_GetAmxAddr(amx, params[3]);
Vector *value = new Vector(
amx_ctof(input_vec[0]),
amx_ctof(input_vec[1]),
amx_ctof(input_vec[2])
);
int strlen;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlen);
PPvoid_t PValue = Hashtable_Get(amx, Hashtable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(value);
else
{ {
elem_value = reinterpret_cast<element*>(*PValue); int Len = strlen(Index) + 1;
(*elem_value).set_vec(value); PPvoid_t PValue = JudyHSIns(&Table, Index, Len, PJE0);
*PValue = reinterpret_cast<void*>(value);
} }
Hashtable_Set(Hashtable,Index,elem_value);
return 1;
}
template <class Type>
static cell AMX_NATIVE_CALL Hashtable_GetVector(AMX *amx, cell *params) Type Get(char* Index, Type example, bool disable_check = false)
{
PPvoid_t Hashtable = Find_Hashtable(params[1], params[4], amx);
if (Hashtable == NULL) return 0;
int strlen;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlen);
PPvoid_t PValue = Hashtable_Get(amx, Hashtable, Index, params[4]);
cell *vAmx = MF_GetAmxAddr(amx, params[3]);
if( PValue == NULL ) {
vAmx[0] = amx_ftoc(0);
vAmx[1] = amx_ftoc(0);
vAmx[2] = amx_ftoc(0);
return 0;
}
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
const Vector retr_vec = *elem_value.get_vec(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
vAmx[0] = amx_ftoc(retr_vec.x);
vAmx[1] = amx_ftoc(retr_vec.y);
vAmx[2] = amx_ftoc(retr_vec.z);
return 1;
}
static cell AMX_NATIVE_CALL Hashtable_SetString(AMX *amx,cell *params)
{
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], params[4], amx);
if (Hashtable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3]: value
int iLen = 0;
char *value = MF_GetAmxString(amx,params[3],1,&iLen);
PPvoid_t PValue = Hashtable_Get(amx, Hashtable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(value);
else
{ {
elem_value = reinterpret_cast<element*>(*PValue); PPvoid_t PValue = JudyHSGet(Table, Index, strlen(Index)+1);
(*elem_value).set_str(value); if(PValue == NULL) { ThrowIndexError(Index, disable_check); return (Type)NULL; }
return (Type)(*PValue);
} }
Hashtable_Set(Hashtable,Index,elem_value);
return 1; char* First( char* Start = "") { ThrowSearchError(); return (char*)NULL; }
} char* Next( char* Start = "") { ThrowSearchError(); return (char*)NULL; }
char* Prev( char* Start) { ThrowSearchError(); return (char*)NULL; }
char* Last( char* Start) { ThrowSearchError(); return (char*)NULL; }
static cell AMX_NATIVE_CALL Hashtable_GetString(AMX *amx,cell *params) bool IsFilled(char* Index) { return ( (Get(Index,(PPvoid_t)(NULL), true ) != NULL) ? true : false);}
{ bool IsEmpty(char* Index) { return ( (Get(Index,(PPvoid_t)(NULL), true ) == NULL) ? true : false);}
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], params[5], amx);
if (Hashtable == NULL) return 0;
//params[2]: key protected:
int strlength; void ThrowIndexError( char* index, bool disable_check = false )
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
Pvoid_t * PValue = Hashtable_Get(amx, Hashtable, Index, params[5]);
//params[3] and params[4] are the return string and length respectively.
if( PValue == NULL )
return MF_SetAmxString(amx, params[3] , "dne", params[4] );
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
if (error)
elem_value.issue_type_error(amx, params[1], Index);
const char* str_out = elem_value.get_str(error);
return MF_SetAmxString( amx , params[3] , str_out, params[4] );
}
static cell AMX_NATIVE_CALL Hashtable_SetFloat(AMX *amx,cell *params)
{
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], params[4], amx);
if (Hashtable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3]: value
PPvoid_t PValue = Hashtable_Get(amx, Hashtable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(amx_ctof(params[3]));
else
{ {
elem_value = reinterpret_cast<element*>(*PValue); if(disable_check == true) return;
(*elem_value).set_flo(amx_ctof(params[3]));
char value[100];
sprintf(value,"Function attempted to read non existant index %s", index );
throw JudyEx(value, true);
} }
Hashtable_Set(Hashtable,Index,elem_value); void ThrowSearchError( void )
return 1;
}
static cell AMX_NATIVE_CALL Hashtable_GetFloat(AMX *amx,cell *params)
{
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], params[3], amx);
if (Hashtable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
PPvoid_t PValue = Hashtable_Get(amx, Hashtable, Index, params[3]);
if( PValue == NULL ) return amx_ftoc(0.0);
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
cell retr_float = amx_ftoc(elem_value.get_flo(error));
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return retr_float;
}
static cell AMX_NATIVE_CALL Hashtable_SetInt(AMX *amx,cell *params)
{
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], params[4], amx);
if (Hashtable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
PPvoid_t PValue = Hashtable_Get(amx, Hashtable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(params[3]);
else
{ {
elem_value = reinterpret_cast<element*>(*PValue); char value[50];
(*elem_value).set_int(params[3]); sprintf(value,"Function attempted to search HashTable!: Invalid action!");
throw JudyEx(value,true);
} }
Hashtable_Set(Hashtable,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Hashtable_GetInt(AMX *amx,cell *params)
{
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], params[3], amx);
if (Hashtable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
Pvoid_t * PValue = Hashtable_Get(amx, Hashtable, Index, params[3]);
if( PValue == NULL ) return 0;
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
cell retr_int = elem_value.get_int(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return retr_int;
}
static cell AMX_NATIVE_CALL Hashtable_Memory(AMX *amx,cell *params)
{
Pvoid_t * Array = Find_Hashtable(params[1],params[2],amx);
if (Array == NULL) return 0;
return JudyLMemUsed(*Array);
}
static cell AMX_NATIVE_CALL Hashtable_Remove(AMX *amx,cell *params)
{
//params[1]: hashtable
PPvoid_t Hashtable = Find_Hashtable(params[1], 0, amx);
if (Hashtable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
JudyHSDel(Hashtable, Index, strlength+1, PJE0 );
return 1;
}
AMX_NATIVE_INFO hashtable_exports[] = {
{ "hashtable_set_str", Hashtable_SetString },
{ "hashtable_get_str", Hashtable_GetString },
{ "hashtable_set_vec", Hashtable_SetVector },
{ "hashtable_get_vec", Hashtable_GetVector },
{ "hashtable_set_int", Hashtable_SetInt },
{ "hashtable_get_int", Hashtable_GetInt },
{ "hashtable_set_float", Hashtable_SetFloat },
{ "hashtable_get_float", Hashtable_GetFloat },
{ "hashtable_memory", Hashtable_Memory },
{ "hashtable_remove", Hashtable_Remove },
{ "hashtable_create", Hashtable_Create },
{ "hashtable_delete", Hashtable_Delete },
{ "hashtable_clear", Hashtable_Clear },
{ NULL, NULL }
}; };
#endif #endif

66
dlls/arrayx/CKeytable.cpp Normal file
View File

@ -0,0 +1,66 @@
#include "CKeytable.h"
void Keytable::ThrowIndexError( char* index, bool disable_check = false )
{
if(disable_check == true) return;
char error[50];
sprintf(error,"Index %s is not set.",index);
throw JudyEx(error,true);
}
void Keytable::ThrowSearchError(char* type)
{
char value[50];
sprintf(value,"Function attempted to search %s: Judy returned NULL value", type);
throw JudyEx(value,false);
}
char* Keytable::First( char* Start)
{
PPvoid_t index = JudySLFirst(Table, Start, PJE0);
if (index == NULL)
{
sprintf(Start,"dne");
ThrowSearchError("Type:First");
}
return Start;
}
char* Keytable::Next( char* Start)
{
PPvoid_t index = JudySLNext(Table, Start, PJE0);
if (index == NULL)
{
sprintf(Start,"dne");
ThrowSearchError("Type:Next");
}
return Start;
}
char* Keytable::Prev( char* Start)
{
PPvoid_t index = JudySLPrev(Table, Start, PJE0);
if (index == NULL)
{
sprintf(Start,"dne");
ThrowSearchError("Type:Prev");
}
return Start;
}
char* Keytable::Last( char* Start)
{
PPvoid_t index = JudySLLast(Table, Start, PJE0);
if (index == NULL)
{
sprintf(Start,"dne");
ThrowSearchError("Type:Last");
}
return Start;
}

View File

@ -1,703 +1,66 @@
#if !defined _JUDYSL_ENABLED_ #ifndef _KEYCLASS_INCLUDED
#define _JUDYSL_ENABLED_ #define _KEYCLASS_INCLUDED
#define MAXLINELEN 1024 #include "JudyIncludes.h"
#include "CBaseMap.h"
#include "JudyExtra.h"
//#include <JudySL.h>
Pvoid_t MasterKeytable = (Pvoid_t) NULL; //Create the control array class Keytable: public CBaseMap
//Create an array that stores whether or not indices are used.
Pvoid_t MasterKeytable_Binary = (Pvoid_t) NULL;
void Delete_MasterKeytable(void);
Word_t New_Keytable(Word_t Index, Word_t reserve = 0);
PPvoid_t Find_Keytable(Word_t Index, Word_t disable_check = 1, AMX *amx = 0);
void Delete_Keytable(Word_t Index);
void Clear_Keytable(Word_t Index);
template <class Type>
void Keytable_Set(PPvoid_t Keytable, char *Index, Type value);
PPvoid_t Keytable_Get(AMX* amx, Pvoid_t Keytable, char *Index, int ignore_error = 0);
void Delete_MasterKeytable(void)
{ {
Word_t private:
Index = 0, Pvoid_t Table;
success;
J1F(success, MasterKeytable_Binary, Index); void ThrowSearchError(char* type);
while( success ) void ThrowIndexError( char* index, bool disable_check);
public:
Keytable() { Table = NULL; }
~Keytable() { Clear(); }
void Remove() { delete this; }
Word_t Clear() { JudyClearMap(this); return JudySLFreeArray(&Table, PJE0); }
Word_t MemoryUsed() { return JudyLMemUsed(Table); }
int Delete(char* Key) { return JudySLDel(&Table, Key, PJE0 ); }
void Set(char* Index, Pvoid_t value, bool disable_check)
{ {
Delete_Keytable(Index); PPvoid_t PValue = JudySLIns(&Table, Index,PJE0);
J1F(success, MasterKeytable_Binary, Index); *PValue = value;
} }
}
Word_t New_Keytable(Word_t Index, Word_t reserve) Pvoid_t Get(char* Index, bool disable_check = false)
{
Word_t success; //Dummy for macros.
J1T(success, MasterKeytable_Binary, Index);
if (success && reserve)
return Index; //If the bit is set but it's 'reserved', return the index.
//Only do this if the bit is not set or not reserved.
J1FE(success, MasterKeytable_Binary, Index);
J1S(success, MasterKeytable_Binary, Index);
PPvoid_t Keytable = JudyLIns(&MasterKeytable, Index, PJE0);
*Keytable = (PWord_t) NULL;
return Index;
}
PPvoid_t Find_Keytable(Word_t Index, Word_t disable_check, AMX* amx)
{
Word_t success;
J1T(success, MasterKeytable_Binary, Index);
if (success || disable_check)
{ //Bit is valid
if(!success)
New_Keytable(Index);
return JudyLGet(MasterKeytable, Index, PJE0);
}
MF_LogError(amx, AMX_ERR_NATIVE, "Keytable \"%s\" is invalid", Index);
return NULL;
}
void Delete_Keytable(Word_t Index)
{
int success;
J1T(success, MasterKeytable_Binary, Index);
if (success)
{ //If the bit was set, clear and delete keytable.
Clear_Keytable(Index);
J1U(success, MasterKeytable_Binary, Index);
JudyLDel(&MasterKeytable, Index, PJE0);
}
}
void Clear_Keytable(Word_t Index)
{
int success;
J1T(success, MasterKeytable_Binary, Index);
if (success) //dont bother with unset Keytables.
{ {
PPvoid_t Keytable = Find_Keytable(Index); PPvoid_t PValue = JudySLGet(Table, Index, PJE0);
char *Key = ""; if(PValue == NULL) { ThrowIndexError(Index, disable_check); return NULL; }
PPvoid_t PValue = JudySLFirst(*Keytable, Key, PJE0);
while (PValue != NULL) return *PValue;
{
element elem_value = *reinterpret_cast<element*>(*PValue);
elem_value.delete_element();
PValue = JudySLNext(*Keytable, Key, PJE0);
}
JudySLFreeArray(Keytable, PJE0);
} }
}
template <class Type>
static cell AMX_NATIVE_CALL Keytable_Save(AMX *amx, cell *params) void Set(char* Index, Type value)
{
PPvoid_t Keytable = Find_Keytable(params[1], params[3], amx);
if (Keytable == NULL) return 0;
int filename_length;
char *file = MF_GetAmxString(amx, params[2], 0, &filename_length);
file = MF_BuildPathname("%s", file);
unlink(file);
FILE *KeytableDB = fopen(file,"w");
if (!KeytableDB)
return 0;
char* Key = new char[1024]; Key[0] = '\0';
PPvoid_t PValue = JudySLFirst(*Keytable, reinterpret_cast<uint8_t*>(Key), PJE0);
element elem = NULL;
char elem_type = 0;
int error;
REAL vector_data[3] = { 0.0, 0.0, 0.0 };
while (PValue)
{ {
elem = *reinterpret_cast<element*>(*PValue); PPvoid_t PValue = JudySLIns(&Table, Index,PJE0);
elem_type = elem.get_type(); *PValue = reinterpret_cast<void*>(value);
if (elem_type < elem_type_int || elem_type > elem_type_vector)
continue;
short key_len = strlen(Key);
fwrite(&key_len, sizeof(short), 1, KeytableDB);
fwrite(Key, sizeof(char), key_len, KeytableDB);
fwrite(&elem_type, sizeof(char), 1, KeytableDB);
if (elem_type == elem_type_int)
{
int int_buffer = elem.get_int(error);
fwrite(&int_buffer, sizeof(int), 1, KeytableDB);
}
else if (elem_type == elem_type_real)
{
REAL flo_buffer = elem.get_flo(error);
fwrite(&flo_buffer, sizeof(REAL), 1, KeytableDB);
}
else if (elem_type == elem_type_char)
{
const char* str_buffer = elem.get_str(error);
short buf_len = strlen(str_buffer);
fwrite(&buf_len, sizeof(short), 1, KeytableDB);
fwrite(str_buffer, sizeof(char), buf_len, KeytableDB);
}
else if (elem_type == elem_type_vector)
{
const Vector* vec_buffer = elem.get_vec(error);
fwrite(vec_buffer, sizeof(Vector), 1, KeytableDB);
}
PValue = JudySLNext(*Keytable, Key, PJE0);
} }
fclose(KeytableDB);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_Load(AMX *amx, cell *params) template <class Type>
{ Type Get(char* Index, Type example, bool disable_check = false)
//params[1]: file
int filename_length;
char *file = MF_GetAmxString(amx, params[1], 0, &filename_length);
file = MF_BuildPathname("%s", file);
FILE *KeytableDB = fopen(file, "a+");
if (!KeytableDB)
return 0;
//params[2]: keytable to create (optional index supplied)
int KeytableIndex = New_Keytable(params[2], params[3]);
Clear_Keytable(KeytableIndex); //make sure the keytable is empty.
PPvoid_t Keytable = Find_Keytable(KeytableIndex);
while(!feof(KeytableDB))
{ {
char* index = ""; char type = 0; short index_len; PPvoid_t PValue = JudySLGet(Table, Index, PJE0);
element *elem_value = NULL; if(PValue == NULL) { ThrowIndexError(Index, disable_check); return (Type)NULL; }
fread(&index_len, sizeof(short), 1, KeytableDB);
index = new char[index_len+1]; return (Type)*PValue;
fgets(index, index_len+1, KeytableDB);
if (feof(KeytableDB) || ferror(KeytableDB))
break;
fread(&type, sizeof(char), 1, KeytableDB);
if (type < elem_type_int || type > elem_type_vector)
{
MF_LogError(amx, AMX_ERR_FORMAT, "Error loading keytable database \"%s\" into keytable %d. Bad file.", file, KeytableIndex);
return KeytableIndex;
}
else if (type == elem_type_int)
{
int value = 0; fread(&value, sizeof(int), 1, KeytableDB);
elem_value = new element(value);
}
else if (type == elem_type_real)
{
REAL value = 0; fread(&value, sizeof(REAL), 1, KeytableDB);
elem_value = new element(value);
}
else if (type == elem_type_char)
{
short length; fread(&length, sizeof(short), 1, KeytableDB);
char* value = new char[length+1]; fgets(value, length+1, KeytableDB);
elem_value = new element(value);
delete(value);
}
else if (type == elem_type_vector)
{
Vector *value = new Vector(); fread(value, sizeof(Vector), 1, KeytableDB);
elem_value = new element(value);
}
Keytable_Set(Keytable,index,elem_value);
delete (index);
} }
fclose(KeytableDB);
return KeytableIndex;
}
static cell AMX_NATIVE_CALL Keytable_Save_ASCII(AMX *amx, cell *params) char* First(char* Start = "");
{ char* Next(char* Start = "");
//params[1]: file char* Prev(char* Start = "");
int filename_length; char* Last(char* Start = "");
char *inputfile = MF_GetAmxString(amx, params[1], 0, &filename_length);
inputfile = MF_BuildPathname("%s", inputfile);
FILE *KeytableDB = fopen(inputfile, "a+");
if (!KeytableDB)
return 0;
char *outputfile = MF_GetAmxString(amx, params[2], 0, &filename_length); bool IsFilled(char* Index) { return ( (Get(Index,(PPvoid_t)(NULL), true ) != NULL) ? true : false); }
outputfile = MF_BuildPathname("%s", outputfile); bool IsEmpty(char* Index) { return ( (Get(Index,(PPvoid_t)(NULL), true ) == NULL) ? true : false); }
FILE *ReadableDB = fopen(outputfile, "w");
char *buffer = "\0";
while(!feof(KeytableDB))
{
char* key = NULL; char type = 0; short key_len;
fread(&key_len, sizeof(short), 1, KeytableDB);
key = new char[key_len+1];
fgets(key, key_len+1, KeytableDB);
if (feof(KeytableDB) || ferror(KeytableDB))
break;
fread(&type, sizeof(char), 1, KeytableDB);
sprintf(buffer, "Key %-32s Length %3d, Type %7s", key, key_len, elem_types[type]);
if (type < elem_type_int || type > elem_type_vector)
{
MF_LogError(amx, AMX_ERR_FORMAT, "Error loading array database \"%s\" into readable format. Bad file.", inputfile);
return 0;
}
else if (type == elem_type_int)
{
int value = 0; fread(&value, sizeof(int), 1, KeytableDB);
fprintf(ReadableDB, "%s\t\t\t\tValue: %d\n", buffer, value);
}
else if (type == elem_type_real)
{
REAL value = 0; fread(&value, sizeof(REAL), 1, KeytableDB);
fprintf(ReadableDB, "%s\t\t\t\tValue: %f\n", buffer, value);
}
else if (type == elem_type_char)
{
short length; fread(&length, sizeof(short), 1, KeytableDB);
char* value = new char[length+1]; fgets(value, length+1, KeytableDB);
fprintf(ReadableDB, "%s Length %3d\tValue: \"%s\"\n", buffer, length, value);
delete value;
}
else if (type == elem_type_vector)
{
Vector *value = new Vector(); fread(value, sizeof(Vector), 1, KeytableDB);
fprintf(ReadableDB, "%s\t\t\t\tValue: {%f,%f,%f}\n", buffer, (*value).x, (*value).y, (*value).z);
delete value;
}
}
fclose(KeytableDB);
fclose(ReadableDB);
return 1;
}
template <class Type> //This will support input char*, Vector*, int, and cell_real*.
void Keytable_Set(PPvoid_t Keytable, char* Index, Type value)
{
PPvoid_t PValue; // pointer to keytable element value
PValue = JudySLIns(Keytable, Index, PJE0);
*PValue = reinterpret_cast<void*>(value);
}
PPvoid_t Keytable_Get(AMX* amx, PPvoid_t Keytable, char *Index, int ignore_error = 0)
{
PPvoid_t PValue = JudySLGet( *Keytable, Index, PJE0 );
if (PValue == NULL && !ignore_error)
MF_LogError(amx, AMX_ERR_NATIVE, "Keytable get on key \"%s\" is invalid", Index);
return PValue;
}
static cell AMX_NATIVE_CALL Keytable_Create(AMX *amx, cell *params)
{
return New_Keytable(params[1],params[2]);
}
static cell AMX_NATIVE_CALL Keytable_Delete(AMX *amx, cell *params)
{
Delete_Keytable( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL Keytable_Clear(AMX *amx, cell *params)
{
Clear_Keytable( params[1] );
return 1;
}
static cell AMX_NATIVE_CALL Keytable_SetVector(AMX *amx,cell *params)
{
PPvoid_t Keytable = Find_Keytable(params[1], params[4], amx);
if (Keytable == NULL) return 0;
cell *input_vec = MF_GetAmxAddr(amx, params[3]);
Vector *value = new Vector(
amx_ctof(input_vec[0]),
amx_ctof(input_vec[1]),
amx_ctof(input_vec[2])
);
int strlen;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlen);
PPvoid_t PValue = Keytable_Get(amx, Keytable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(value);
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_vec(value);
}
Keytable_Set(Keytable,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_GetVector(AMX *amx, cell *params)
{
PPvoid_t Keytable = Find_Keytable(params[1], params[4], amx);
if (Keytable == NULL) return 0;
int strlen;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlen);
PPvoid_t PValue = Keytable_Get(amx, Keytable, Index, params[4]);
cell *vAmx = MF_GetAmxAddr(amx, params[3]);
if( PValue == NULL ) {
vAmx[0] = amx_ftoc(0);
vAmx[1] = amx_ftoc(0);
vAmx[2] = amx_ftoc(0);
return 0;
}
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
const Vector retr_vec = *elem_value.get_vec(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
vAmx[0] = amx_ftoc(retr_vec.x);
vAmx[1] = amx_ftoc(retr_vec.y);
vAmx[2] = amx_ftoc(retr_vec.z);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_SetString(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[4], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3]: value
int iLen = 0;
char *value = MF_GetAmxString(amx,params[3],1,&iLen);
PPvoid_t PValue = Keytable_Get(amx, Keytable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(value);
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_str(value);
}
Keytable_Set(Keytable,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_GetString(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[5], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
Pvoid_t * PValue = Keytable_Get(amx, Keytable, Index, params[5]);
//params[3] and params[4] are the return string and length respectively.
if( PValue == NULL )
return MF_SetAmxString(amx, params[3] , "dne", params[4] );
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
if (error)
elem_value.issue_type_error(amx, params[1], Index);
const char* str_out = elem_value.get_str(error);
return MF_SetAmxString( amx , params[3] , str_out, params[4] );
}
static cell AMX_NATIVE_CALL Keytable_SetFloat(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[4], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3]: value
PPvoid_t PValue = Keytable_Get(amx, Keytable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(amx_ctof(params[3]));
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_flo(amx_ctof(params[3]));
}
Keytable_Set(Keytable,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_GetFloat(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[3], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
PPvoid_t PValue = Keytable_Get(amx, Keytable, Index, params[3]);
if( PValue == NULL ) return amx_ftoc(0.0);
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
cell retr_float = amx_ftoc(elem_value.get_flo(error));
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return retr_float;
}
static cell AMX_NATIVE_CALL Keytable_SetInt(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[4], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
PPvoid_t PValue = Keytable_Get(amx, Keytable, Index, 1);
element *elem_value = NULL;
if ( PValue == NULL )
elem_value = new element(params[3]);
else
{
elem_value = reinterpret_cast<element*>(*PValue);
(*elem_value).set_int(params[3]);
}
Keytable_Set(Keytable,Index,elem_value);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_GetInt(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[3], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
Pvoid_t * PValue = Keytable_Get(amx, Keytable, Index, params[3]);
if( PValue == NULL ) return 0;
element elem_value = *reinterpret_cast<element*>(*PValue);
int error = 0;
cell retr_int = elem_value.get_int(error);
if (error)
elem_value.issue_type_error(amx, params[1], Index);
return retr_int;
}
static cell AMX_NATIVE_CALL Keytable_Memory(AMX *amx,cell *params)
{
Pvoid_t * Keytable = Find_Keytable(params[1],params[2],amx);
if (Keytable == NULL) return 0;
return JudyLMemUsed(*Keytable);
}
static cell AMX_NATIVE_CALL Keytable_Remove(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], 0, amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//Have to delete the element
PPvoid_t PValue = JudySLGet(*Keytable, Index, PJE0);
if (PValue == NULL) return 1;
element elem_value = *reinterpret_cast<element*>(*PValue);
elem_value.delete_element();
JudySLDel(Keytable, Index, PJE0 );
return 1;
}
static cell AMX_NATIVE_CALL Keytable_Next(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[5], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3], params[4]: return key and length
PPvoid_t pointer;
pointer = JudySLNext(*Keytable, Index, PJE0);
if (pointer == NULL) {
MF_SetAmxString(amx, params[3], "dne", 0);
return 0;
}
MF_SetAmxString(amx, params[3], Index, params[4]);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_Prev(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[5], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3], params[4]: return key and length
PPvoid_t pointer;
pointer = JudySLPrev(*Keytable, Index, PJE0);
if (pointer == NULL) {
MF_SetAmxString(amx, params[3], "dne", 0);
return 0;
}
MF_SetAmxString(amx, params[3], Index, params[4]);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_First(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[5], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3], params[4]: return key and length
PPvoid_t pointer;
pointer = JudySLFirst(*Keytable, Index, PJE0);
if (pointer == NULL) {
MF_SetAmxString(amx, params[3], "dne", 0);
return 0;
}
MF_SetAmxString(amx, params[3], Index, params[4]);
return 1;
}
static cell AMX_NATIVE_CALL Keytable_Last(AMX *amx,cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[5], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
//params[3], params[4]: return key and length
PPvoid_t pointer;
pointer = JudySLLast(*Keytable, Index, PJE0);
if (pointer == NULL) {
MF_SetAmxString(amx, params[3], "dne", 0);
return 0;
}
MF_SetAmxString(amx, params[3], Index, params[4]);
return 1;
}
static cell AMX_NATIVE_CALL Key_IsEmpty(AMX *amx, cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[3], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
PPvoid_t pointer = JudySLGet(*Keytable, Index, PJE0);
return (pointer == NULL) ? 1 : 0;
}
static cell AMX_NATIVE_CALL Key_IsFilled(AMX *amx, cell *params)
{
//params[1]: keytable
PPvoid_t Keytable = Find_Keytable(params[1], params[3], amx);
if (Keytable == NULL) return 0;
//params[2]: key
int strlength;
char *Index = MF_GetAmxString(amx, params[2], 0, &strlength);
PPvoid_t pointer = JudySLGet(*Keytable, Index, PJE0);
return (pointer != NULL) ? 1 : 0;
}
AMX_NATIVE_INFO keytable_exports[] = {
{ "keytable_set_string", Keytable_SetString },
{ "keytable_get_string", Keytable_GetString },
{ "keytable_set_vector", Keytable_SetVector },
{ "keytable_get_vector", Keytable_GetVector },
{ "keytable_set_int", Keytable_SetInt },
{ "keytable_get_int", Keytable_GetInt },
{ "keytable_set_float", Keytable_SetFloat },
{ "keytable_get_float", Keytable_GetFloat },
{ "keytable_isempty", Key_IsEmpty },
{ "keytable_isfilled", Key_IsFilled },
{ "keytable_memory", Keytable_Memory },
{ "keytable_remove", Keytable_Remove },
{ "keytable_create", Keytable_Create },
{ "keytable_delete", Keytable_Delete },
{ "keytable_clear", Keytable_Clear },
{ "keytable_next", Keytable_Next },
{ "keytable_prev", Keytable_Prev },
{ "keytable_first", Keytable_First },
{ "keytable_last", Keytable_Last },
{ "keytable_save", Keytable_Save },
{ "keytable_load", Keytable_Load },
{ "keytable_save_ascii", Keytable_Save_ASCII },
{ NULL, NULL }
}; };
#endif #endif

261
dlls/arrayx/Capsule.cpp Normal file
View File

@ -0,0 +1,261 @@
#include "Capsule.h"
const char* capsule_types[] =
{
"-NO VALUE-",
"BOOLEAN",
"INTEGER",
"FLOAT",
"VECTOR",
"STRING"
};
void Capsule::ThrowTypeError(cell get_type)
{
char ValStr[15];
GetAsStr(ValStr);
char value[100];
sprintf(value,"Function attempted to read NON-%s value, actual type is: %s, actual value is: %s", capsule_types[get_type], capsule_types[type], ValStr );
throw JudyEx(value, true);
}
bool Capsule::CheckEmpty(bool clear)
{
bool empty = ( data == NULL );
if(empty != true && clear == true) Clear();
return empty;
}
void Capsule::Clear()
{
//This function intelligently creates a pointer x,
//which will be of correct type and then deletes it.
switch (type)
{
case capsule_type_flo:
{
REAL *real_val = reinterpret_cast<REAL*>(data);
delete real_val;
break;
}
case capsule_type_vec:
{
JudyVec *vector_val = reinterpret_cast<JudyVec*>(data);
delete vector_val;
break;
}
case capsule_type_str:
{
char *char_val = reinterpret_cast<char*>(data);
delete char_val;
break;
}
}
data = NULL; //Null the address as well. (Used for ints too.)
}
bool Capsule::GetBool( void )
{
if (type != capsule_type_bool) ThrowTypeError(capsule_type_bool);
return reinterpret_cast<bool>(data);
}
void Capsule::SetBool(bool Value)
{
CheckEmpty(true);
type = capsule_type_bool;
data = reinterpret_cast<void*>(Value);
};
cell Capsule::GetInt( void )
{
if (type != capsule_type_int) ThrowTypeError(capsule_type_int);
return reinterpret_cast<cell>(data);
}
void Capsule::SetInt(cell Value)
{
CheckEmpty(true);
type = capsule_type_int;
data = reinterpret_cast<void*>(Value);
};
REAL Capsule::GetFlo( void )
{
if (type != capsule_type_flo) ThrowTypeError(capsule_type_flo);
return *reinterpret_cast<REAL*>(data);
}
void Capsule::SetFlo(REAL Value)
{
CheckEmpty(true);
type = capsule_type_flo;
data = new REAL(Value);
};
const JudyVec* Capsule::GetVec( void )
{
if (type != capsule_type_vec) ThrowTypeError(capsule_type_vec);
return reinterpret_cast<const JudyVec*>(data);
}
void Capsule::SetVec(JudyVec* Value)
{
CheckEmpty(true);
type = capsule_type_vec;
data = reinterpret_cast<void*>(Value);
}
const char* Capsule::GetStr( void )
{
if (type != capsule_type_str) ThrowTypeError(capsule_type_str);
return reinterpret_cast<const char*>(data);
}
void Capsule::SetStr(char* Value)
{
CheckEmpty(true);
type = capsule_type_str;
char *string_val = new char[strlen(Value)+1];
strcpy(string_val,Value);
data = reinterpret_cast<void*>(string_val);
}
void Capsule::GetAsStr(char* value)
{
switch (type)
{
case capsule_type_bool:
sprintf(value, "%i",(cell)GetBool());
break;
case capsule_type_int:
sprintf(value, "%d", GetInt() );
break;
case capsule_type_flo:
sprintf(value, "%f", GetFlo() );
break;
case capsule_type_vec:
sprintf(value, "{%f,%f,%f}", GetVec()->first, GetVec()->second, GetVec()->third);
break;
case capsule_type_str:
sprintf(value, "\"%s\"", GetStr() );
break;
default:
sprintf(value, "-NO VALUE-");
}
}
void Capsule::Save(FILE* capsuleDB)
{
fwrite(&type,sizeof(char),1,capsuleDB);
switch(type)
{
case capsule_type_none: { break; }
case capsule_type_bool: { bool var = GetBool(); fwrite(&var, sizeof(bool), 1, capsuleDB); break; }
case capsule_type_int: { cell var = GetInt(); fwrite(&var, sizeof(cell), 1, capsuleDB); break; }
case capsule_type_flo: { fwrite(reinterpret_cast<REAL*>(GetData()), sizeof(REAL), 1, capsuleDB); break; }
case capsule_type_str:
{
const char* str = GetStr();
size_t len = strlen(str);
fwrite(&len,sizeof(size_t), 1, capsuleDB);
fwrite(&str, sizeof(char), len, capsuleDB);
break;
}
case capsule_type_vec:
{
const JudyVec* buffer = GetVec();
fwrite(buffer, sizeof(JudyVec), 1, capsuleDB);
break;
}
default:
{
char value[20];
sprintf(value,"Invalid type found!");
throw JudyEx(value, true);
break;
}
};
}
void Capsule::Load(FILE* capsuleDB)
{
fread(&type, sizeof(char), 1, capsuleDB);
switch(type)
{
case capsule_type_none: { CheckEmpty(true); break; }
case capsule_type_bool:
{
bool value = false;
fread(&value, sizeof(bool), 1, capsuleDB);
SetBool(value);
break;
}
case capsule_type_int:
{
cell value = NULL;
fread(&value, sizeof(cell), 1, capsuleDB);
SetInt(value);
break;
}
case capsule_type_flo:
{
REAL value = NULL;
fread(&value, sizeof(REAL), 1, capsuleDB);
SetFlo(value);
break;
}
case capsule_type_str:
{
size_t length;
fread(&length, sizeof(size_t), 1, capsuleDB);
char* value = new char[length+1];
fgets(value, length+1, capsuleDB);
SetStr(value);
delete(value);
break;
}
case capsule_type_vec:
{
JudyVec* value = new JudyVec(NULL,NULL,NULL);
fread(value, sizeof(JudyVec), 1, capsuleDB);
SetVec(value);
break;
}
default:
{
char value[20];
sprintf(value,"Invalid type found: %i",(int)type);
throw JudyEx(value, true);
}
};
}

65
dlls/arrayx/Capsule.h Normal file
View File

@ -0,0 +1,65 @@
#ifndef _JUDYCAP_INCLUDED
#define _JUDYCAP_INCLUDED
#include "JudyIncludes.h"
enum
{
capsule_type_none,
capsule_type_bool,
capsule_type_int,
capsule_type_flo,
capsule_type_vec,
capsule_type_str
};
extern const char* capsule_types[];
class Capsule
{
private:
Pvoid_t data;
char type;
protected:
void Clear( void );
void ThrowTypeError(cell get_type);
public:
Capsule() { data = NULL; type = capsule_type_none;}
~Capsule() { Clear(); }
void Remove() { delete this; }
Capsule(bool set) { SetBool(set); }
Capsule(cell set) { SetInt(set); }
Capsule(REAL set) { SetFlo(set); }
Capsule(JudyVec* set) { SetVec(set); }
Capsule(char* set) { SetStr(set); }
bool GetBool( void );
void SetBool(bool set);
cell GetInt( void );
void SetInt(cell set);
REAL GetFlo( void );
void SetFlo(REAL set);
const JudyVec* GetVec( void );
void SetVec(JudyVec* set);
const char* GetStr( void );
void SetStr(char* set);
void GetAsStr(char* value);
void Load(FILE* db);
void Save(FILE* db);
bool CheckEmpty(bool clear);
Pvoid_t GetData( void ) { return data; }
char GetType( void ) { return type; }
};
#endif

80
dlls/arrayx/ComboArray.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef _COMBOARRAY_INCLUDED
#define _COMBOARRAY_INCLUDED
#include "CBinTrie.h"
#include "CArray.h"
#include "CBaseList.h"
class ComboArray: public CBaseList
{
private:
BinTrie MasterBin;
Array MasterArray;
public:
ComboArray() { }
~ComboArray() { Clear(); }
void Remove() { delete this; }
Word_t Clear() { return (MasterBin.Clear() + MasterArray.Clear() ); }
Word_t MemoryUsed() { return (MasterBin.MemoryUsed() + MasterArray.MemoryUsed() ); }
int Delete(cell Key) { return (MasterBin.Delete(Key) + MasterArray.Delete(Key) ); }
void Set(cell Index, Pvoid_t value, bool disable_check)
{
MasterBin.Set(Index, true);
MasterArray.Set(Index, value, disable_check);
}
Pvoid_t Get(cell Index, bool disable_check = false)
{
if(MasterBin.Get(Index) == NULL) { ThrowIndexError(Index, disable_check); return NULL; }
return MasterArray.Get(Index);
}
template <class Type>
void Set(cell Index, Type value)
{
MasterBin.Set(Index, true);
MasterArray.Set(Index, value);
}
template <class Type>
Type Get(cell Index, Type example, bool disable_check = false)
{
if(MasterBin.Get(Index) == NULL) { ThrowIndexError(Index, disable_check); return (Type)NULL; }
return MasterArray.Get(Index,example);
}
cell First(cell Start = 0) { return MasterBin.First(Start); }
cell Next(cell Start = 0) { return MasterBin.Next(Start); }
cell Prev(cell Start = -1) { return MasterBin.Prev(Start); }
cell Last(cell Start = -1) { return MasterBin.Last(Start); }
cell FirstEmpty(cell Start = 0) { return MasterBin.FirstEmpty(Start); }
cell NextEmpty(cell Start = 0) { return MasterBin.NextEmpty(Start); }
cell PrevEmpty(cell Start = -1) { return MasterBin.PrevEmpty(Start); }
cell LastEmpty(cell Start = -1) { return MasterBin.LastEmpty(Start); }
cell ByCount(cell n, cell Start = 0) { return MasterBin.ByCount(n, Start); }
cell Count(cell Start = 0, cell Stop = -1) { return MasterBin.Count(Start, Stop); }
bool IsFilled(cell Index) { return ( (MasterBin.Get(Index) != NULL) ? true : false); }
bool IsEmpty(cell Index) { return ( (MasterBin.Get(Index) == NULL) ? true : false); }
protected:
void ThrowIndexError(cell Index, bool disable_check = false)
{
if(disable_check == true) return;
char error[50];
sprintf(error,"Index %i is not set.",Index);
throw JudyEx(error,true);
}
};
#endif

68
dlls/arrayx/ComboTable.h Normal file
View File

@ -0,0 +1,68 @@
#ifndef _COMBOTABLE_INCLUDED
#define _COMBOTABLE_INCLUDED
#include "CKeytable.h"
#include "CHashtable.h"
#include "CBaseMap.h"
class ComboTable: public CBaseMap
{
private:
Keytable MasterKey;
Hashtable MasterHash;
public:
ComboTable() { }
~ComboTable() { Clear(); }
void Remove() { delete this; }
Word_t Clear() { return (MasterHash.Clear() + MasterKey.Clear() ); }
Word_t MemoryUsed() { return (MasterKey.MemoryUsed() + MasterHash.MemoryUsed() ); }
int Delete(char* Key) { return (MasterKey.Delete(Key) + MasterHash.Delete(Key) ); }
bool IsFilled(char* Index) { return ( (MasterHash.Get(Index,(PPvoid_t)(NULL), true ) != NULL) ? true : false);}
bool IsEmpty(char* Index) { return ( (MasterHash.Get(Index,(PPvoid_t)(NULL), true ) == NULL) ? true : false);}
void Set(char* Index, Pvoid_t value, bool disable_check)
{
MasterKey.Set(Index, value);
MasterHash.Set(Index, value);
}
Pvoid_t Get(char* Index, bool disable_check = false)
{
return MasterHash.Get(Index, disable_check);
}
template <class Type>
void Set(char* Index, Type value)
{
MasterKey.Set(Index, value);
MasterHash.Set(Index, value);
}
template <class Type>
Type Get(char* Index, Type example, bool disable_check = false)
{
return MasterHash.Get(Index, example, disable_check);
}
char* First( char* Start = "") { return MasterKey.First(Start);}
char* Next( char* Start = "") { return MasterKey.Next(Start);}
char* Prev( char* Start = "") { return MasterKey.Prev(Start); }
char* Last( char* Start = "") { return MasterKey.Last(Start);}
protected:
void ThrowIndexError( char* index, bool disable_check = false )
{
if(disable_check == true) return;
char value[100];
sprintf(value,"Function attempted to read non existant index %s", index );
throw JudyEx(value, true);
}
};
#endif

View File

@ -0,0 +1,862 @@
#ifndef _GENERIC_INC_H
#define _GENERIC_INC_H
// Master table
ComboArray MNAME;
///* MASTER FUNCTIONS *///
///* Start Master Edit Funcs *///
#ifdef JUDY_MASTER_EDIT_FUNCTIONS
#ifdef JUDY_MASTER_DELETE_FUNC
// generic_delete(id)
static cell AMX_NATIVE_CALL JUDY_MASTER_DELETE_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1] );
Unit->Remove();
try { return MNAME.Delete( params[1] ); }
JUDY_ERROR_CATCH("Judy Error: (No error possible) - Delete function ");
}
#else
#error Must Have Delete func: JUDY_MASTER_DELETE_FUNC not defined!
#endif
#ifdef JUDY_MASTER_CLEAR_FUNC
// generic_clear(id)
static cell AMX_NATIVE_CALL JUDY_MASTER_CLEAR_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1] );
try { return Unit->Clear(); }
JUDY_ERROR_CATCH("Judy Error: (Search error likely) - Clear function ");
}
#else
#error Must Have Clear func: JUDY_MASTER_CLEAR_FUNC not defined!
#endif
///* End Master Edit Funcs *///
#endif
///* Start Master IO Funcs *///
#ifdef JUDY_MASTER_IO_FUNCTIONS
#ifdef JUDY_MASTER_SAVE_FUNC
// generic_save(id,file[])
static cell AMX_NATIVE_CALL JUDY_MASTER_SAVE_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
return JUDY_SAVE_FUNC(Unit, JUDY_BUILD_PATH(amx,params[2]) );
}
#else
#error Must Have Save func: JUDY_MASTER_SAVE_FUNC not defined properly!
#endif
#ifdef JUDY_MASTER_LOAD_FUNC
// generic_load(file[],id)
static cell AMX_NATIVE_CALL JUDY_MASTER_LOAD_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[2]);
return JUDY_LOAD_FUNC(Unit, JUDY_BUILD_PATH(amx,params[1]) );
}
#else
#error Must Have Load func: JUDY_MASTER_LOAD_FUNC not defined!
#endif
///* End Master IO Funcs *///
#endif
///* Start Master Amount Funcs *///
#ifdef JUDY_MASTER_AMOUNT_FUNCTIONS
#ifdef JUDY_MASTER_COUNT_FUNC
// generic_count(start = 0, stop = -1)
static cell AMX_NATIVE_CALL JUDY_MASTER_COUNT_FUNC(AMX *amx,cell *params)
{
try { return MNAME.Count(params[1],params[2] ); }
JUDY_ERROR_CATCH("Judy Error: (Search error likely) - Count Function ");
}
#else
#error Must Have Count func: JUDY_MASTER_COUNT_FUNC not defined!
#endif
#ifdef JUDY_MASTER_BYCOUNT_FUNC
// generic_bycount(nth, start = -1)
static cell AMX_NATIVE_CALL JUDY_MASTER_BYCOUNT_FUNC(AMX *amx,cell *params)
{
try { return MNAME.ByCount(params[1],params[2] ); }
JUDY_ERROR_CATCH("Judy Error: (Search error likely) - ByCount Function ");
}
#else
#error Must Have ByCount func: JUDY_MASTER_BYCOUNT_FUNC not defined!
#endif
///* End Master Amount Funcs *///
#endif
///* SLAVE FUNCTIONS *///
///* Start Slave Amount Funcs *///
#ifdef JUDY_SLAVE_AMOUNT_FUNCTIONS
#ifdef JUDY_SLAVE_COUNT_FUNC
// generic_size(id, start = 0, stop = -1)
static cell AMX_NATIVE_CALL JUDY_SLAVE_COUNT_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
try { return Unit->Count(JUDY_GET_KEY(params,2),JUDY_GET_KEY(params, 3) ); }
JUDY_ERROR_CATCH("Judy Error: (Search error likely) - Slave Count Function ");
}
#else
#error Must Have Count func: JUDY_SLAVE_COUNT_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_BYCOUNT_FUNC
// generic_get_nth(id, nth, start = -1)
static cell AMX_NATIVE_CALL JUDY_SLAVE_BYCOUNT_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
try { return Unit->ByCount(JUDY_GET_KEY(params,2),JUDY_GET_KEY(params, 3) ); }
JUDY_ERROR_CATCH("Judy Error: (Search error likely) - Slave ByCount Function ");
}
#else
#error Must Have ByCount func: JUDY_SLAVE_BYCOUNT_FUNC not defined!
#endif
///* End Slave Amount Funcs *///
#endif
///* Start Slave Edit Funcs *///
#ifdef JUDY_SLAVE_EDIT_FUNCTIONS
#ifdef JUDY_SLAVE_MEMORY_FUNC
// generic_memory(id)
static cell AMX_NATIVE_CALL JUDY_SLAVE_MEMORY_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
try { return Unit->MemoryUsed(); }
JUDY_ERROR_CATCH("Judy Error: (Search error likely) - Slave ByCount Function ");
}
#else
#error Must Have Memory func: JUDY_SLAVE_MEMORY_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_ISFILLED_FUNC
// generic_isfilled(id, index)
static cell AMX_NATIVE_CALL JUDY_SLAVE_ISFILLED_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
try { return Unit->IsFilled(JUDY_GET_KEY(params,2) ); }
JUDY_ERROR_CATCH("Judy Error: (No error possible) - Slave IsFilled Function ");
}
#else
#error Must Have IsFilled func: JUDY_SLAVE_ISFILLED_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_ISEMPTY_FUNC
// generic_isempty(id, index)
static cell AMX_NATIVE_CALL JUDY_SLAVE_ISEMPTY_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
try { return Unit->IsEmpty(JUDY_GET_KEY(params,2) ); }
JUDY_ERROR_CATCH("Judy Error: (No error possible) - Slave IsEmpty Function ");
}
#else
#error Must Have IsEmpty func: JUDY_SLAVE_ISEMPTY_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_REMOVE_FUNC
// generic_remove(id, index)
static cell AMX_NATIVE_CALL JUDY_SLAVE_REMOVE_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, true ) );
Storage->Remove();
try { return Unit->Delete(Indice); }
JUDY_ERROR_CATCH("Judy Error: (No Error Possible) - Delete function ");
}
#else
#ifdef NO_JUDY_SLAVE_REMOVE_FUNC
#else
#error Must Have Delete func: JUDY_SLAVE_REMOVE_FUNC not defined!
#endif
#endif
///* End Required Slave Edit Funcs *///
///* Start Slave Bool Funcs *///
#ifdef JUDY_SLAVE_EDIT_BOOL
#ifdef JUDY_SLAVE_SET_BOOL_FUNC
// generic_set_bool(id, index, Bool:val)
static cell AMX_NATIVE_CALL JUDY_SLAVE_SET_BOOL_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
bool Value = (params[3] != NULL);
Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, true ) );
if(Storage == NULL) Storage = new STYPE(Value);
else Storage->SetBool(Value);
JUDY_SET_INDEX_P(Unit,Storage,Indice);
}
#else
#error Must Have Set func: JUDY_SLAVE_SET_BOOL_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_GET_BOOL_FUNC
// Bool:generic_get_bool(id, index, disable_check = 0)
static cell AMX_NATIVE_CALL JUDY_SLAVE_GET_BOOL_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
bool disable_check = (params[3] != NULL);
try { Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, disable_check ) ); }
JUDY_ERROR_CATCH("Judy Error: (Retrieve unset value) - Slave Get Function ");
if(Storage == NULL) return 0;
return Storage->GetBool();
}
#else
#error Must Have Get func: JUDY_SLAVE_GET_BOOL_FUNC not defined!
#endif
///* End Slave Bool Funcs *///
#endif
///* Start Slave Int Funcs *///
#ifdef JUDY_SLAVE_EDIT_INT
#ifdef JUDY_SLAVE_SET_INT_FUNC
// generic_set_bool(id, index, val)
static cell AMX_NATIVE_CALL JUDY_SLAVE_SET_INT_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell Value = params[3];
Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, true ) );
if(Storage == NULL) Storage = new STYPE(Value);
else Storage->SetInt(Value);
JUDY_SET_INDEX_P(Unit,Storage,Indice);
}
#else
#error Must Have Set func: JUDY_SLAVE_SET_INT_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_GET_INT_FUNC
// generic_get_int(id, index, disable_check = 0)
static cell AMX_NATIVE_CALL JUDY_SLAVE_GET_INT_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
bool disable_check = (params[3] != NULL);
try { Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, disable_check ) ); }
JUDY_ERROR_CATCH("Judy Error: (Retrieve unset value) - Slave Get Function ");
if(Storage == NULL) return 0;
return Storage->GetInt();
}
#else
#error Must Have Get func: JUDY_SLAVE_GET_INT_FUNC not defined!
#endif
///* End Slave Int Funcs *///
#endif
///* Start Slave Float Funcs *///
#ifdef JUDY_SLAVE_EDIT_FLO
#ifdef JUDY_SLAVE_SET_FLO_FUNC
// generic_set_float(id, index, Float:val)
static cell AMX_NATIVE_CALL JUDY_SLAVE_SET_FLO_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
REAL Value = amx_ctof(params[3]);
Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, true ) );
if(Storage == NULL) Storage = new STYPE(Value);
else Storage->SetFlo(Value);
JUDY_SET_INDEX_P(Unit,Storage,Indice);
}
#else
#error Must Have Set func: JUDY_SLAVE_SET_FLO_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_GET_FLO_FUNC
// Float:generic_get_float(id, index, disable_check = 0)
static cell AMX_NATIVE_CALL JUDY_SLAVE_GET_FLO_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
bool disable_check = (params[3] != NULL);
try { Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, disable_check ) ); }
JUDY_ERROR_CATCH("Judy Error: (Retrieve unset value) - Slave Get Function ");
if(Storage == NULL) return 0;
return amx_ftoc(Storage->GetFlo() );
}
#else
#error Must Have Get func: JUDY_SLAVE_GET_FLO_FUNC not defined!
#endif
///* End Slave Float Funcs *///
#endif
///* Start Slave String Funcs *///
#ifdef JUDY_SLAVE_EDIT_STR
#ifdef JUDY_SLAVE_SET_STR_FUNC
// generic_set_string(id, index, val[])
static cell AMX_NATIVE_CALL JUDY_SLAVE_SET_STR_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
char* Value = MF_GetAmxString(amx,params[3],3,NULL);
Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, true ) );
if(Storage == NULL) Storage = new STYPE(Value);
else Storage->SetStr(Value);
JUDY_SET_INDEX_P(Unit,Storage,Indice);
}
#else
#error Must Have Set func: JUDY_SLAVE_SET_STR_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_GET_STR_FUNC
// generic_get_string(id, index, val[], len, disable_check = 0)
static cell AMX_NATIVE_CALL JUDY_SLAVE_GET_STR_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
bool disable_check = (params[5] != NULL);
try { Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, disable_check ) ); }
JUDY_ERROR_CATCH("Judy Error: (Retrieve unset value) - Slave Get Function ");
if(Storage == NULL) return 0;
return MF_SetAmxString(amx,params[3], Storage->GetStr(), params[4] );
}
#else
#error Must Have Get func: JUDY_SLAVE_GET_STR_FUNC not defined!
#endif
///* End Slave String Funcs *///
#endif
///* Start Slave Vector Funcs *///
#ifdef JUDY_SLAVE_EDIT_VEC
#ifdef JUDY_SLAVE_SET_VEC_FUNC
// generic_set_vec(id, index, Float:val[3])
static cell AMX_NATIVE_CALL JUDY_SLAVE_SET_VEC_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell *input_vec = MF_GetAmxAddr(amx, params[3]);
JudyVec *Value = new JudyVec(
amx_ctof(input_vec[0]),
amx_ctof(input_vec[1]),
amx_ctof(input_vec[2])
);
Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, true ) );
if(Storage == NULL) Storage = new STYPE(Value);
else Storage->SetVec(Value);
JUDY_SET_INDEX_P(Unit,Storage,Indice);
}
#else
#error Must Have Set func: JUDY_SLAVE_SET_VEC_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_GET_FLO_FUNC
// generic_get_vec(id,index,Float:vec[3], disable_check = 0)
static cell AMX_NATIVE_CALL JUDY_SLAVE_GET_VEC_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
STYPE* Storage;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell *vAmx = MF_GetAmxAddr(amx, params[3]);
bool disable_check = (params[4] != NULL);
try { Storage = reinterpret_cast<STYPE*>( Unit->Get(Indice, disable_check ) ); }
JUDY_ERROR_CATCH("Judy Error: (Retrieve unset value) - Slave Get Function ");
if(Storage == NULL)
{
vAmx[0] = amx_ftoc(0);
vAmx[1] = amx_ftoc(0);
vAmx[2] = amx_ftoc(0);
return 0;
}
JudyVec* Vec = const_cast<JudyVec*>( Storage->GetVec() );
REAL One, Two, Three;
Vec->Get(One, Two, Three);
vAmx[0] = amx_ftoc(One);
vAmx[1] = amx_ftoc(Two);
vAmx[2] = amx_ftoc(Three);
return 1;
}
#else
#error Must Have Get func: JUDY_SLAVE_GET_VEC_FUNC not defined!
#endif
///* End Slave VEC Funcs *///
#endif
///* End Slave Edit Funcs *///
#endif
///* Start Slave Search Funcs
#ifdef JUDY_SLAVE_SEARCH_FUNCTIONS
#ifdef JUDY_SLAVE_FIRST_FUNC
// generic_first(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_FIRST_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->First(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_FIRST_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_NEXT_FUNC
// generic_next(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_NEXT_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->Next(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_NEXT_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_PREV_FUNC
// generic_prev(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_PREV_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->Prev(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_PREV_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_LAST_FUNC
// generic_first(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_LAST_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->Last(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_LAST_FUNC not defined!
#endif
///* End Slave Search Funcs *///
#endif
///* Start Slave Empty Search Funcs
#ifdef JUDY_SLAVE_SEARCH_EMPTY_FUNCTIONS
#ifdef JUDY_SLAVE_FIRSTEMPTY_FUNC
// generic_firstempty(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_FIRSTEMPTY_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->FirstEmpty(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_FIRSTEMPTY_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_NEXTEMPTY_FUNC
// generic_next(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_NEXTEMPTY_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->NextEmpty(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_NEXTEMPTY_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_PREVEMPTY_FUNC
// generic_prev(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_PREVEMPTY_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->PrevEmpty(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function", *success);
}
#else
#error Must Have Search func: JUDY_SLAVE_PREVEMPTY_FUNC not defined!
#endif
#ifdef JUDY_SLAVE_LASTEMPTY_FUNC
// generic_first(id, index,...)
static cell AMX_NATIVE_CALL JUDY_SLAVE_LASTEMPTY_FUNC(AMX *amx,cell *params)
{
DTYPE* Unit = NULL;
JUDY_GET_INDEX(MNAME,Unit, params[1]);
ITYPE Indice = JUDY_GET_KEY(params,2);
cell* success = MF_GetAmxAddr(amx, params[3 + SE_OFFSET]);
*success = 1;
try { return JUDY_SET_KEY(Unit->LastEmpty(Indice),3); }
JUDY_SEARCH_ERROR_CATCH("Judy Error (Search failed) - Slave Search Function",*success);
}
#else
#error Must Have Search func: JUDY_SLAVE_LASTEMPTY_FUNC not defined!
#endif
///* End Slave Search Empty Funcs *///
#endif
AMX_NATIVE_INFO EXPORT_NAME[] =
{
#ifdef JUDY_MASTER_EDIT_FUNCTIONS
{ JUDY_MASTER_CLEAR_STR , JUDY_MASTER_CLEAR_FUNC },
{ JUDY_MASTER_DELETE_STR , JUDY_MASTER_DELETE_FUNC },
#endif
#ifdef JUDY_MASTER_IO_FUNCTIONS
{ JUDY_MASTER_SAVE_STR , JUDY_MASTER_SAVE_FUNC },
{ JUDY_MASTER_LOAD_STR , JUDY_MASTER_LOAD_FUNC },
#endif
#ifdef JUDY_MASTER_AMOUNT_FUNCTIONS
{ JUDY_MASTER_COUNT_STR , JUDY_MASTER_COUNT_FUNC },
{ JUDY_MASTER_BYCOUNT_STR , JUDY_MASTER_BYCOUNT_FUNC },
#endif
#ifdef JUDY_SLAVE_AMOUNT_FUNCTIONS
{ JUDY_SLAVE_COUNT_STR , JUDY_SLAVE_COUNT_FUNC },
{ JUDY_SLAVE_BYCOUNT_STR , JUDY_SLAVE_BYCOUNT_FUNC },
#endif
#ifdef JUDY_SLAVE_EDIT_FUNCTIONS
{ JUDY_SLAVE_MEMORY_STR , JUDY_SLAVE_MEMORY_FUNC },
{ JUDY_SLAVE_ISFILLED_STR , JUDY_SLAVE_ISFILLED_FUNC },
{ JUDY_SLAVE_ISEMPTY_STR , JUDY_SLAVE_ISEMPTY_FUNC },
#ifndef NO_JUDY_SLAVE_REMOVE_FUNC
{ JUDY_SLAVE_REMOVE_STR , JUDY_SLAVE_REMOVE_FUNC },
#endif
#ifdef JUDY_SLAVE_EDIT_BOOL
{ JUDY_SLAVE_GET_BOOL_STR , JUDY_SLAVE_GET_BOOL_FUNC },
{ JUDY_SLAVE_SET_BOOL_STR , JUDY_SLAVE_SET_BOOL_FUNC },
#endif
#ifdef JUDY_SLAVE_EDIT_INT
{ JUDY_SLAVE_GET_INT_STR , JUDY_SLAVE_GET_INT_FUNC },
{ JUDY_SLAVE_SET_INT_STR , JUDY_SLAVE_SET_INT_FUNC },
#endif
#ifdef JUDY_SLAVE_EDIT_FLO
{ JUDY_SLAVE_GET_FLO_STR , JUDY_SLAVE_GET_FLO_FUNC },
{ JUDY_SLAVE_SET_FLO_STR , JUDY_SLAVE_SET_FLO_FUNC },
#endif
#ifdef JUDY_SLAVE_EDIT_STR
{ JUDY_SLAVE_GET_STR_STR , JUDY_SLAVE_GET_STR_FUNC },
{ JUDY_SLAVE_SET_STR_STR , JUDY_SLAVE_SET_STR_FUNC },
#endif
#ifdef JUDY_SLAVE_EDIT_VEC
{ JUDY_SLAVE_GET_VEC_STR , JUDY_SLAVE_GET_VEC_FUNC },
{ JUDY_SLAVE_SET_VEC_STR , JUDY_SLAVE_SET_VEC_FUNC },
#endif
// End all edit functions
#endif
#ifdef JUDY_SLAVE_SEARCH_FUNCTIONS
{ JUDY_SLAVE_FIRST_STR , JUDY_SLAVE_FIRST_FUNC },
{ JUDY_SLAVE_LAST_STR , JUDY_SLAVE_LAST_FUNC },
{ JUDY_SLAVE_NEXT_STR , JUDY_SLAVE_NEXT_FUNC },
{ JUDY_SLAVE_PREV_STR , JUDY_SLAVE_PREV_FUNC },
#endif
#ifdef JUDY_SLAVE_SEARCH_EMPTY_FUNCTIONS
{ JUDY_SLAVE_FIRSTEMPTY_STR , JUDY_SLAVE_FIRSTEMPTY_FUNC },
{ JUDY_SLAVE_LASTEMPTY_STR , JUDY_SLAVE_LASTEMPTY_FUNC },
{ JUDY_SLAVE_NEXTEMPTY_STR , JUDY_SLAVE_NEXTEMPTY_FUNC },
{ JUDY_SLAVE_PREVEMPTY_STR , JUDY_SLAVE_PREVEMPTY_FUNC },
#endif
{ NULL, NULL }
};
#endif

View File

@ -1,139 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Fake "program" to test the exports in Judy.h by exercising each one. This
// program should compile OK (with libJudy.a) but does not run OK.
#include "Judy.h"
int
main()
{
Pvoid_t PArray = (Pvoid_t) NULL;
PPvoid_t PPArray = &PArray;
Word_t Index = 0;
PWord_t PIndex = &Index;
uint8_t *CIndex = NULL;
PPvoid_t PPvoid;
Word_t myword;
Word_t Length;
int myint;
// JUDY FUNCTIONS:
myint = Judy1Test ( PArray, Index, PJE0);
myint = Judy1Set (PPArray, Index, PJE0);
myint = Judy1SetArray (PPArray, Index, &Index, PJE0);
myint = Judy1Unset (PPArray, Index, PJE0);
myword = Judy1Count ( PArray, Index, Index, PJE0);
myint = Judy1ByCount ( PArray, Index, PIndex, PJE0);
myword = Judy1FreeArray (PPArray, PJE0);
myword = Judy1MemUsed ( PArray );
myword = Judy1MemActive ( PArray );
myint = Judy1First ( PArray, PIndex, PJE0);
myint = Judy1Next ( PArray, PIndex, PJE0);
myint = Judy1Last ( PArray, PIndex, PJE0);
myint = Judy1Prev ( PArray, PIndex, PJE0);
myint = Judy1FirstEmpty ( PArray, PIndex, PJE0);
myint = Judy1NextEmpty ( PArray, PIndex, PJE0);
myint = Judy1LastEmpty ( PArray, PIndex, PJE0);
myint = Judy1PrevEmpty ( PArray, PIndex, PJE0);
PPvoid = JudyLGet ( PArray, Index, PJE0);
PPvoid = JudyLIns (PPArray, Index, PJE0);
myint = JudyLInsArray (PPArray, Index, &Index, &Index, PJE0);
myint = JudyLDel (PPArray, Index, PJE0);
myword = JudyLCount ( PArray, Index, Index, PJE0);
PPvoid = JudyLByCount ( PArray, Index, PIndex, PJE0);
myword = JudyLFreeArray (PPArray, PJE0);
myword = JudyLMemUsed ( PArray );
myword = JudyLMemActive ( PArray );
PPvoid = JudyLFirst ( PArray, PIndex, PJE0);
PPvoid = JudyLNext ( PArray, PIndex, PJE0);
PPvoid = JudyLLast ( PArray, PIndex, PJE0);
PPvoid = JudyLPrev ( PArray, PIndex, PJE0);
myint = JudyLFirstEmpty ( PArray, PIndex, PJE0);
myint = JudyLNextEmpty ( PArray, PIndex, PJE0);
myint = JudyLLastEmpty ( PArray, PIndex, PJE0);
myint = JudyLPrevEmpty ( PArray, PIndex, PJE0);
PPvoid = JudySLGet ( PArray, CIndex, PJE0);
PPvoid = JudySLIns (PPArray, CIndex, PJE0);
myint = JudySLDel (PPArray, CIndex, PJE0);
myword = JudySLFreeArray (PPArray, PJE0);
PPvoid = JudySLFirst ( PArray, CIndex, PJE0);
PPvoid = JudySLNext ( PArray, CIndex, PJE0);
PPvoid = JudySLLast ( PArray, CIndex, PJE0);
PPvoid = JudySLPrev ( PArray, CIndex, PJE0);
PPvoid = JudyHSGet ( PArray, CIndex, Length);
PPvoid = JudyHSIns (PPArray, CIndex, Length, PJE0);
myint = JudyHSDel (PPArray, CIndex, Length, PJE0);
// MACRO EQUIVALENTS:
J1T (myint, PArray, Index);
J1S (myint, PArray, Index);
J1SA (myint, PArray, Index, &Index);
J1U (myint, PArray, Index);
J1F (myint, PArray, Index);
J1N (myint, PArray, Index);
J1L (myint, PArray, Index);
J1P (myint, PArray, Index);
J1FE (myint, PArray, Index);
J1NE (myint, PArray, Index);
J1LE (myint, PArray, Index);
J1PE (myint, PArray, Index);
J1C (myword, PArray, Index, Index);
J1BC (myint, PArray, Index, Index);
J1FA (myword, PArray);
JLG (PPvoid, PArray, Index);
JLI (PPvoid, PArray, Index);
JLIA (myint, PArray, Index, &Index, &Index);
JLD (myint, PArray, Index);
JLF (PPvoid, PArray, Index);
JLN (PPvoid, PArray, Index);
JLL (PPvoid, PArray, Index);
JLP (PPvoid, PArray, Index);
JLFE (myint, PArray, Index);
JLNE (myint, PArray, Index);
JLLE (myint, PArray, Index);
JLPE (myint, PArray, Index);
JLC (myword, PArray, Index, Index);
JLBC (PPvoid, PArray, myword, Index);
JLFA (myword, PArray);
JSLG (PPvoid, PArray, CIndex);
JSLI (PPvoid, PArray, CIndex);
JSLD (myint, PArray, CIndex);
JSLF (PPvoid, PArray, CIndex);
JSLN (PPvoid, PArray, CIndex);
JSLL (PPvoid, PArray, CIndex);
JSLP (PPvoid, PArray, CIndex);
JSLFA (myword, PArray);
JHSI (PPvoid, PArray, CIndex, Length);
JHSG (PPvoid, PArray, CIndex, Length);
JHSD (myint, PArray, CIndex, Length);
return(0);
} // main()

View File

@ -1,551 +0,0 @@
#ifndef _JUDY1_INCLUDED
#define _JUDY1_INCLUDED
// _________________
//
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// ****************************************************************************
// JUDY1 -- SMALL/LARGE AND/OR CLUSTERED/SPARSE BIT ARRAYS
//
// -by-
//
// Douglas L. Baskins
// doug@sourcejudy.com
//
// Judy arrays are designed to be used instead of arrays. The performance
// suggests the reason why Judy arrays are thought of as arrays, instead of
// trees. They are remarkably memory efficient at all populations.
// Implemented as a hybrid digital tree (but really a state machine, see
// below), Judy arrays feature fast insert/retrievals, fast near neighbor
// searching, and contain a population tree for extremely fast ordinal related
// retrievals.
//
// CONVENTIONS:
//
// - The comments here refer to 32-bit [64-bit] systems.
//
// - BranchL, LeafL refer to linear branches and leaves (small populations),
// except LeafL does not actually appear as such; rather, Leaf1..3 [Leaf1..7]
// is used to represent leaf Index sizes, and LeafW refers to a Leaf with
// full (long) word Indexes, which is also a type of linear leaf. Note that
// root-level LeafW (Leaf4 [Leaf8]) leaves are also called LEAFW.
//
// - BranchB, LeafB1 refer to bitmap branches and leaves (intermediate
// populations).
//
// - BranchU refers to uncompressed branches. An uncompressed branch has 256
// JPs, some of which could be null. Note: All leaves are compressed (and
// sorted), or else an expanse is full (FullPopu), so there is no LeafU
// equivalent to BranchU.
//
// - "Popu" is short for "Population".
// - "Pop1" refers to actual population (base 1).
// - "Pop0" refers to Pop1 - 1 (base 0), the way populations are stored in data
// structures.
//
// - Branches and Leaves are both named by the number of bytes in their Pop0
// field. In the case of Leaves, the same number applies to the Index sizes.
//
// - The representation of many numbers as hex is a relatively safe and
// portable way to get desired bitpatterns as unsigned longs.
//
// - Some preprocessors cant handle single apostrophe characters within
// #ifndef code, so here, use delete all instead.
#include "JudyPrivate.h" // includes Judy.h in turn.
#include "JudyPrivateBranch.h"
// ****************************************************************************
// JUDY1 ROOT POINTER (JRP) AND JUDY1 POINTER (JP) TYPE FIELDS
// ****************************************************************************
//
// The following enum lists all possible JP Type fields.
typedef enum // uint8_t -- but C does not support this type of enum.
{
// JP NULL TYPES:
//
// There is a series of cJ1_JPNULL* Types because each one pre-records a
// different Index Size for when the first Index is inserted in the previously
// null JP. They must start >= 8 (three bits).
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPNULL1 = 1,
// Index Size 1[1] byte when 1 Index inserted.
cJ1_JPNULL2, // Index Size 2[2] bytes when 1 Index inserted.
cJ1_JPNULL3, // Index Size 3[3] bytes when 1 Index inserted.
#ifndef JU_64BIT
#define cJ1_JPNULLMAX cJ1_JPNULL3
#else
cJ1_JPNULL4, // Index Size 4[4] bytes when 1 Index inserted.
cJ1_JPNULL5, // Index Size 5[5] bytes when 1 Index inserted.
cJ1_JPNULL6, // Index Size 6[6] bytes when 1 Index inserted.
cJ1_JPNULL7, // Index Size 7[7] bytes when 1 Index inserted.
#define cJ1_JPNULLMAX cJ1_JPNULL7
#endif
// JP BRANCH TYPES:
//
// Note: There are no state-1 branches; only leaves reside at state 1.
// Linear branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_L2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_L3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_L4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_L5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_L6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_L7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_L, // note: DcdPopO field not used.
// Bitmap branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_B2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_B3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_B4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_B5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_B6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_B7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_B, // note: DcdPopO field not used.
// Uncompressed branches:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
cJ1_JPBRANCH_U2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPBRANCH_U3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPBRANCH_U4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPBRANCH_U5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPBRANCH_U6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPBRANCH_U7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
cJ1_JPBRANCH_U, // note: DcdPopO field not used.
// JP LEAF TYPES:
// Linear leaves:
//
// Note: These Types must be in sequential order for doing relative
// calculations between them.
//
// Note: There is no cJ1_JPLEAF1 for 64-bit for a subtle reason. An immediate
// JP can hold 15 1-byte Indexes, and a bitmap leaf would be used for 17
// Indexes, so rather than support a linear leaf for only the case of exactly
// 16 Indexes, a bitmap leaf is used in that case. See also below regarding
// cJ1_LEAF1_MAXPOP1 on 64-bit systems.
//
// Note: There is no full-word (4-byte [8-byte]) Index leaf under a JP because
// non-root-state leaves only occur under branches that decode at least one
// byte. Full-word, root-state leaves are under a JRP, not a JP. However, in
// the code a "fake" JP can be created temporarily above a root-state leaf.
#ifndef JU_64BIT // 32-bit only; see above.
cJ1_JPLEAF1, // 1 byte Pop0, 2 bytes Dcd.
#endif
cJ1_JPLEAF2, // 2[2] bytes Pop0, 1[5] bytes Dcd.
cJ1_JPLEAF3, // 3[3] bytes Pop0, 0[4] bytes Dcd.
#ifdef JU_64BIT
cJ1_JPLEAF4, // [4] bytes Pop0, [3] bytes Dcd.
cJ1_JPLEAF5, // [5] bytes Pop0, [2] bytes Dcd.
cJ1_JPLEAF6, // [6] bytes Pop0, [1] byte Dcd.
cJ1_JPLEAF7, // [7] bytes Pop0, [0] bytes Dcd.
#endif
// Bitmap leaf; Index Size == 1:
//
// Note: These are currently only supported at state 1. At other states the
// bitmap would grow from 256 to 256^2, 256^3, ... bits, which would not be
// efficient..
cJ1_JPLEAF_B1, // 1[1] byte Pop0, 2[6] bytes Dcd.
// Full population; Index Size == 1 virtual leaf:
//
// Note: These are currently only supported at state 1. At other states they
// could be used, but they would be rare and the savings are dubious.
cJ1_JPFULLPOPU1, // 1[1] byte Pop0, 2[6] bytes Dcd.
#ifdef notdef // for future enhancements
cJ1_JPFULLPOPU1m1, // Full Population - 1
cJ1_JPFULLPOPU1m2, // Full Population - 2
cJ1_JPFULLPOPU1m3, // Full Population - 3
cJ1_JPFULLPOPU1m4, // Full Population - 4
cJ1_JPFULLPOPU1m5, // Full Population - 5
cJ1_JPFULLPOPU1m6, // Full Population - 6
cJ1_JPFULLPOPU1m7, // Full Population - 7
#ifdef JU_64BIT
cJ1_JPFULLPOPU1m8, // Full Population - 8
cJ1_JPFULLPOPU1m9, // Full Population - 9
cJ1_JPFULLPOPU1m10, // Full Population - 10
cJ1_JPFULLPOPU1m11, // Full Population - 11
cJ1_JPFULLPOPU1m12, // Full Population - 12
cJ1_JPFULLPOPU1m13, // Full Population - 13
cJ1_JPFULLPOPU1m14, // Full Population - 14
cJ1_JPFULLPOPU1m15, // Full Population - 15
#endif
#endif // notdef -- for future enhancements
// JP IMMEDIATES; leaves (Indexes) stored inside a JP:
//
// The second numeric suffix is the Pop1 for each type. As the Index Size
// increases, the maximum possible population decreases.
//
// Note: These Types must be in sequential order in each group (Index Size),
// and the groups in correct order too, for doing relative calculations between
// them. For example, since these Types enumerate the Pop1 values (unlike
// other JP Types where there is a Pop0 value in the JP), the maximum Pop1 for
// each Index Size is computable.
cJ1_JPIMMED_1_01, // Index Size = 1, Pop1 = 1.
cJ1_JPIMMED_2_01, // Index Size = 2, Pop1 = 1.
cJ1_JPIMMED_3_01, // Index Size = 3, Pop1 = 1.
#ifdef JU_64BIT
cJ1_JPIMMED_4_01, // Index Size = 4, Pop1 = 1.
cJ1_JPIMMED_5_01, // Index Size = 5, Pop1 = 1.
cJ1_JPIMMED_6_01, // Index Size = 6, Pop1 = 1.
cJ1_JPIMMED_7_01, // Index Size = 7, Pop1 = 1.
#endif
cJ1_JPIMMED_1_02, // Index Size = 1, Pop1 = 2.
cJ1_JPIMMED_1_03, // Index Size = 1, Pop1 = 3.
cJ1_JPIMMED_1_04, // Index Size = 1, Pop1 = 4.
cJ1_JPIMMED_1_05, // Index Size = 1, Pop1 = 5.
cJ1_JPIMMED_1_06, // Index Size = 1, Pop1 = 6.
cJ1_JPIMMED_1_07, // Index Size = 1, Pop1 = 7.
#ifdef JU_64BIT
cJ1_JPIMMED_1_08, // Index Size = 1, Pop1 = 8.
cJ1_JPIMMED_1_09, // Index Size = 1, Pop1 = 9.
cJ1_JPIMMED_1_10, // Index Size = 1, Pop1 = 10.
cJ1_JPIMMED_1_11, // Index Size = 1, Pop1 = 11.
cJ1_JPIMMED_1_12, // Index Size = 1, Pop1 = 12.
cJ1_JPIMMED_1_13, // Index Size = 1, Pop1 = 13.
cJ1_JPIMMED_1_14, // Index Size = 1, Pop1 = 14.
cJ1_JPIMMED_1_15, // Index Size = 1, Pop1 = 15.
#endif
cJ1_JPIMMED_2_02, // Index Size = 2, Pop1 = 2.
cJ1_JPIMMED_2_03, // Index Size = 2, Pop1 = 3.
#ifdef JU_64BIT
cJ1_JPIMMED_2_04, // Index Size = 2, Pop1 = 4.
cJ1_JPIMMED_2_05, // Index Size = 2, Pop1 = 5.
cJ1_JPIMMED_2_06, // Index Size = 2, Pop1 = 6.
cJ1_JPIMMED_2_07, // Index Size = 2, Pop1 = 7.
#endif
cJ1_JPIMMED_3_02, // Index Size = 3, Pop1 = 2.
#ifdef JU_64BIT
cJ1_JPIMMED_3_03, // Index Size = 3, Pop1 = 3.
cJ1_JPIMMED_3_04, // Index Size = 3, Pop1 = 4.
cJ1_JPIMMED_3_05, // Index Size = 3, Pop1 = 5.
cJ1_JPIMMED_4_02, // Index Size = 4, Pop1 = 2.
cJ1_JPIMMED_4_03, // Index Size = 4, Pop1 = 3.
cJ1_JPIMMED_5_02, // Index Size = 5, Pop1 = 2.
cJ1_JPIMMED_5_03, // Index Size = 3, Pop1 = 3.
cJ1_JPIMMED_6_02, // Index Size = 6, Pop1 = 2.
cJ1_JPIMMED_7_02, // Index Size = 7, Pop1 = 2.
#endif
// This special Type is merely a sentinel for doing relative calculations.
// This value should not be used in switch statements (to avoid allocating code
// for it), which is also why it appears at the end of the enum list.
cJ1_JPIMMED_CAP
} jp1_Type_t;
// RELATED VALUES:
//
// Index Size (state) for leaf JP, and JP type based on Index Size (state):
#ifndef JU_64BIT // 32-bit
#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF1 + 1)
#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF1 - 1)
#else
#define J1_LEAFINDEXSIZE(jpType) ((jpType) - cJ1_JPLEAF2 + 2)
#define J1_LEAFTYPE(IndexSize) ((IndexSize) + cJ1_JPLEAF2 - 2)
#endif
// ****************************************************************************
// JUDY1 POINTER (JP) -- RELATED MACROS AND CONSTANTS
// ****************************************************************************
// MAXIMUM POPULATIONS OF LINEAR LEAVES:
//
// Allow up to 2 cache lines per leaf, with N bytes per index.
//
// J_1_MAXB is the maximum number of bytes (sort of) to allocate per leaf.
// ALLOCSIZES is defined here, not there, for single-point control of these key
// definitions. See JudyTables.c for "TERMINATOR".
#define J_1_MAXB (sizeof(Word_t) * 32)
#define ALLOCSIZES { 3, 5, 7, 11, 15, 23, 32, 47, 64, TERMINATOR } // in words.
#define cJ1_LEAF1_MAXWORDS 5 // Leaf1 max alloc size in words.
// Under JRP (root-state leaves):
//
// Includes a count (Population) word.
//
// Under JP (non-root-state leaves), which have no count (Population) words:
//
// When a 1-byte index leaf grows above cJ1_LEAF1_MAXPOP1 Indexes (bytes),
// the memory chunk required grows to a size where a bitmap is just as
// efficient, so use a bitmap instead for all greater Populations, on both
// 32-bit and 64-bit systems. However, on a 32-bit system this occurs upon
// going from 6 to 8 words (24 to 32 bytes) in the memory chunk, but on a
// 64-bit system this occurs upon going from 2 to 4 words (16 to 32 bytes). It
// would be silly to go from a 15-Index Immediate JP to a 16-Index linear leaf
// to a 17-Index bitmap leaf, so just use a bitmap leaf for 16+ Indexes, which
// means set cJ1_LEAF1_MAXPOP1 to cJ1_IMMED1_MAXPOP1 (15) to cause the
// transition at that point.
//
// Note: cJ1_LEAF1_MAXPOP1 is not used on 64-bit systems.
#ifndef JU_64BIT // 32-bit
#define cJ1_LEAF1_MAXPOP1 (cJ1_LEAF1_MAXWORDS * cJU_BYTESPERWORD)
#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2)
#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3)
#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD)
#else // 64-bit
// #define cJ1_LEAF1_MAXPOP1 // no LEAF1 in 64-bit.
#define cJ1_LEAF2_MAXPOP1 (J_1_MAXB / 2)
#define cJ1_LEAF3_MAXPOP1 (J_1_MAXB / 3)
#define cJ1_LEAF4_MAXPOP1 (J_1_MAXB / 4)
#define cJ1_LEAF5_MAXPOP1 (J_1_MAXB / 5)
#define cJ1_LEAF6_MAXPOP1 (J_1_MAXB / 6)
#define cJ1_LEAF7_MAXPOP1 (J_1_MAXB / 7)
#define cJ1_LEAFW_MAXPOP1 ((J_1_MAXB - cJU_BYTESPERWORD) / cJU_BYTESPERWORD)
#endif
// MAXIMUM POPULATIONS OF IMMEDIATE JPs:
//
// These specify the maximum Population of immediate JPs with various Index
// Sizes (== sizes of remaining undecoded Index bits).
#define cJ1_IMMED1_MAXPOP1 ((sizeof(jp_t) - 1) / 1) // 7 [15].
#define cJ1_IMMED2_MAXPOP1 ((sizeof(jp_t) - 1) / 2) // 3 [7].
#define cJ1_IMMED3_MAXPOP1 ((sizeof(jp_t) - 1) / 3) // 2 [5].
#ifdef JU_64BIT
#define cJ1_IMMED4_MAXPOP1 ((sizeof(jp_t) - 1) / 4) // [3].
#define cJ1_IMMED5_MAXPOP1 ((sizeof(jp_t) - 1) / 5) // [3].
#define cJ1_IMMED6_MAXPOP1 ((sizeof(jp_t) - 1) / 6) // [2].
#define cJ1_IMMED7_MAXPOP1 ((sizeof(jp_t) - 1) / 7) // [2].
#endif
// ****************************************************************************
// JUDY1 BITMAP LEAF (J1LB) SUPPORT
// ****************************************************************************
#define J1_JLB_BITMAP(Pjlb,Subexp) ((Pjlb)->j1lb_Bitmap[Subexp])
typedef struct J__UDY1_BITMAP_LEAF
{
BITMAPL_t j1lb_Bitmap[cJU_NUMSUBEXPL];
} j1lb_t, * Pj1lb_t;
// ****************************************************************************
// MEMORY ALLOCATION SUPPORT
// ****************************************************************************
// ARRAY-GLOBAL INFORMATION:
//
// At the cost of an occasional additional cache fill, this object, which is
// pointed at by a JRP and in turn points to a JP_BRANCH*, carries array-global
// information about a Judy1 array that has sufficient population to amortize
// the cost. The jpm_Pop0 field prevents having to add up the total population
// for the array in insert, delete, and count code. The jpm_JP field prevents
// having to build a fake JP for entry to a state machine; however, the
// jp_DcdPopO field in jpm_JP, being one byte too small, is not used.
//
// Note: Struct fields are ordered to keep "hot" data in the first 8 words
// (see left-margin comments) for machines with 8-word cache lines, and to keep
// sub-word fields together for efficient packing.
typedef struct J_UDY1_POPULATION_AND_MEMORY
{
/* 1 */ Word_t jpm_Pop0; // total population-1 in array.
/* 2 */ jp_t jpm_JP; // JP to first branch; see above.
/* 4 */ Word_t jpm_LastUPop0; // last jpm_Pop0 when convert to BranchU
// Note: Field names match PJError_t for convenience in macros:
/* 7 */ char je_Errno; // one of the enums in Judy.h.
/* 7/8 */ int je_ErrID; // often an internal source line number.
/* 8/9 */ Word_t jpm_TotalMemWords; // words allocated in array.
} j1pm_t, *Pj1pm_t;
// TABLES FOR DETERMINING IF LEAVES HAVE ROOM TO GROW:
//
// These tables indicate if a given memory chunk can support growth of a given
// object into wasted (rounded-up) memory in the chunk. This violates the
// hiddenness of the JudyMalloc code.
//
// Also define macros to hide the details in the code using these tables.
#ifndef JU_64BIT
extern const uint8_t j__1_Leaf1PopToWords[cJ1_LEAF1_MAXPOP1 + 1];
#endif
extern const uint8_t j__1_Leaf2PopToWords[cJ1_LEAF2_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf3PopToWords[cJ1_LEAF3_MAXPOP1 + 1];
#ifdef JU_64BIT
extern const uint8_t j__1_Leaf4PopToWords[cJ1_LEAF4_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf5PopToWords[cJ1_LEAF5_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf6PopToWords[cJ1_LEAF6_MAXPOP1 + 1];
extern const uint8_t j__1_Leaf7PopToWords[cJ1_LEAF7_MAXPOP1 + 1];
#endif
extern const uint8_t j__1_LeafWPopToWords[cJ1_LEAFW_MAXPOP1 + 1];
// Check if increase of population will fit in same leaf:
#ifndef JU_64BIT
#define J1_LEAF1GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF1_MAXPOP1, j__1_Leaf1PopToWords)
#endif
#define J1_LEAF2GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF2_MAXPOP1, j__1_Leaf2PopToWords)
#define J1_LEAF3GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF3_MAXPOP1, j__1_Leaf3PopToWords)
#ifdef JU_64BIT
#define J1_LEAF4GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF4_MAXPOP1, j__1_Leaf4PopToWords)
#define J1_LEAF5GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF5_MAXPOP1, j__1_Leaf5PopToWords)
#define J1_LEAF6GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF6_MAXPOP1, j__1_Leaf6PopToWords)
#define J1_LEAF7GROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAF7_MAXPOP1, j__1_Leaf7PopToWords)
#endif
#define J1_LEAFWGROWINPLACE(Pop1) \
J__U_GROWCK(Pop1, cJ1_LEAFW_MAXPOP1, j__1_LeafWPopToWords)
#ifndef JU_64BIT
#define J1_LEAF1POPTOWORDS(Pop1) (j__1_Leaf1PopToWords[Pop1])
#endif
#define J1_LEAF2POPTOWORDS(Pop1) (j__1_Leaf2PopToWords[Pop1])
#define J1_LEAF3POPTOWORDS(Pop1) (j__1_Leaf3PopToWords[Pop1])
#ifdef JU_64BIT
#define J1_LEAF4POPTOWORDS(Pop1) (j__1_Leaf4PopToWords[Pop1])
#define J1_LEAF5POPTOWORDS(Pop1) (j__1_Leaf5PopToWords[Pop1])
#define J1_LEAF6POPTOWORDS(Pop1) (j__1_Leaf6PopToWords[Pop1])
#define J1_LEAF7POPTOWORDS(Pop1) (j__1_Leaf7PopToWords[Pop1])
#endif
#define J1_LEAFWPOPTOWORDS(Pop1) (j__1_LeafWPopToWords[Pop1])
// FUNCTIONS TO ALLOCATE OBJECTS:
Pj1pm_t j__udy1AllocJ1PM(void); // constant size.
Pjbl_t j__udy1AllocJBL( Pj1pm_t); // constant size.
Pjbb_t j__udy1AllocJBB( Pj1pm_t); // constant size.
Pjp_t j__udy1AllocJBBJP(Word_t, Pj1pm_t);
Pjbu_t j__udy1AllocJBU( Pj1pm_t); // constant size.
#ifndef JU_64BIT
Pjll_t j__udy1AllocJLL1( Word_t, Pj1pm_t);
#endif
Pjll_t j__udy1AllocJLL2( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL3( Word_t, Pj1pm_t);
#ifdef JU_64BIT
Pjll_t j__udy1AllocJLL4( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL5( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL6( Word_t, Pj1pm_t);
Pjll_t j__udy1AllocJLL7( Word_t, Pj1pm_t);
#endif
Pjlw_t j__udy1AllocJLW( Word_t ); // no Pj1pm needed.
Pj1lb_t j__udy1AllocJLB1( Pj1pm_t); // constant size.
// FUNCTIONS TO FREE OBJECTS:
void j__udy1FreeJ1PM( Pj1pm_t, Pj1pm_t); // constant size.
void j__udy1FreeJBL( Pjbl_t, Pj1pm_t); // constant size.
void j__udy1FreeJBB( Pjbb_t, Pj1pm_t); // constant size.
void j__udy1FreeJBBJP(Pjp_t, Word_t, Pj1pm_t);
void j__udy1FreeJBU( Pjbu_t, Pj1pm_t); // constant size.
#ifndef JU_64BIT
void j__udy1FreeJLL1( Pjll_t, Word_t, Pj1pm_t);
#endif
void j__udy1FreeJLL2( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL3( Pjll_t, Word_t, Pj1pm_t);
#ifdef JU_64BIT
void j__udy1FreeJLL4( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL5( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL6( Pjll_t, Word_t, Pj1pm_t);
void j__udy1FreeJLL7( Pjll_t, Word_t, Pj1pm_t);
#endif
void j__udy1FreeJLW( Pjlw_t, Word_t, Pj1pm_t);
void j__udy1FreeJLB1( Pj1lb_t, Pj1pm_t); // constant size.
void j__udy1FreeSM( Pjp_t, Pj1pm_t); // everything below Pjp.
#endif // ! _JUDY1_INCLUDED

View File

@ -1,954 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy*ByCount() function for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
// version with cache line optimizations deleted, for testing.
//
// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count().
// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a
// given Index (that is, its position in the list of valid indexes from the
// beginning) as a degenerate case, because in general the count between two
// Indexes, inclusive, is not always just the difference in their ordinals.
// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index
// mapper.
//
// Note: Like Judy*Count(), this code must "count sideways" in branches, which
// can result in a lot of cache line fills. However, unlike Judy*Count(), this
// code does not receive a specific Index, hence digit, where to start in each
// branch, so it cant accurately calculate cache line fills required in each
// direction. The best it can do is an approximation based on the total
// population of the expanse (pop1 from Pjp) and the ordinal of the target
// Index (see SETOFFSET()) within the expanse.
//
// Compile with -DSMARTMETRICS to obtain global variables containing smart
// cache line metrics. Note: Dont turn this on simultaneously for this file
// and JudyCount.c because they export the same globals.
// ****************************************************************************
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// These are imported from JudyCount.c:
//
// TBD: Should this be in common code? Exported from a header file?
#ifdef JUDY1
extern Word_t j__udy1JPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udy1JPPop1
#else
extern Word_t j__udyLJPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udyLJPPop1
#endif
// Avoid duplicate symbols since this file is multi-compiled:
#ifdef SMARTMETRICS
#ifdef JUDY1
Word_t jbb_upward = 0; // counts of directions taken:
Word_t jbb_downward = 0;
Word_t jbu_upward = 0;
Word_t jbu_downward = 0;
Word_t jlb_upward = 0;
Word_t jlb_downward = 0;
#else
extern Word_t jbb_upward;
extern Word_t jbb_downward;
extern Word_t jbu_upward;
extern Word_t jbu_downward;
extern Word_t jlb_upward;
extern Word_t jlb_downward;
#endif
#endif
// ****************************************************************************
// J U D Y 1 B Y C O U N T
// J U D Y L B Y C O U N T
//
// See the manual entry.
#ifdef JUDY1
FUNCTION int Judy1ByCount
#else
FUNCTION PPvoid_t JudyLByCount
#endif
(
Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
Word_t Count, // ordinal of Index to find, 1..MAX.
Word_t * PIndex, // to return found Index.
PJError_t PJError // optional, for returning error info.
)
{
Word_t Count0; // Count, base-0, to match pop0.
Word_t state; // current state in SM.
Word_t pop1; // of current branch or leaf, or of expanse.
Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
Word_t digit; // current word in branch.
Word_t jpcount; // JPs in a BranchB subexpanse.
long jpnum; // JP number in a branch (base 0).
long subexp; // for stepping through layer 1 (subexpanses).
int offset; // index ordinal within a leaf, base 0.
Pjp_t Pjp; // current JP in branch.
Pjll_t Pjll; // current Judy linear leaf.
// CHECK FOR EMPTY ARRAY OR NULL PINDEX:
if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
// desired, to represent the last index in a full array:
//
// Note: Think of Count0 as a reliable "number of Indexes below the target."
Count0 = Count - 1;
assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
pop1lower = 0;
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
*PIndex = Pjlw[Count]; // Index, base 1.
JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0);
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
Pjp = &(Pjpm->jpm_JP);
pop1 = (Pjpm->jpm_Pop0) + 1;
// goto SMByCount;
}
// COMMON CODE:
//
// Prepare to handle a root-level or lower-level branch: Save the current
// state, obtain the total population for the branch in a state-dependent way,
// and then branch to common code for multiple cases.
//
// For root-level branches, the state is always cJU_ROOTSTATE, and the array
// population must already be set in pop1; it is not available in jp_DcdPopO.
//
// Note: The total population is only needed in cases where the common code
// "counts down" instead of up to minimize cache line fills. However, its
// available cheaply, and its better to do it with a constant shift (constant
// state value) instead of a variable shift later "when needed".
#define PREPB_ROOT(Next) \
state = cJU_ROOTSTATE; \
goto Next
// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
// (only if state < cJU_ROOTSTATE - 1):
#define PREPB_DCD(Pjp,cState,Next) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPB((Pjp), cState, Next)
#define PREPB(Pjp,cState,Next) \
state = (cState); \
pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
goto Next
// Calculate whether the ordinal of an Index within a given expanse falls in
// the lower or upper half of the expanses population, taking care with
// unsigned math and boundary conditions:
//
// Note: Assume the ordinal falls within the expanses population, that is,
// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
//
// Note: If the ordinal is the middle element, it doesnt matter whether
// LOWERHALF() is TRUE or FALSE.
#define LOWERHALF(Count0,Pop1lower,Pop1exp) \
(((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
// Calculate the (signed) offset within a leaf to the desired ordinal (Count -
// Pop1lower; offset is one less), and optionally ensure its in range:
#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) <= JU_JPLEAF_POP0(Pjp))
// Variations for immediate indexes, with and without pop1-specific assertions:
#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) < (cPop1))
#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
(Offset) = (Count0) - (Pop1lower)
// STATE MACHINE -- TRAVERSE TREE:
//
// In branches, look for the expanse (digit), if any, where the total pop1
// below or at that expanse would meet or exceed Count, meaning the Index must
// be in this expanse.
SMByCount: // return here for next branch/leaf.
switch (JU_JPTYPE(Pjp))
{
// ----------------------------------------------------------------------------
// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
// expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
//
// Note: A JBL should always fit in one cache line => no need to count up
// versus down to save cache line fills.
//
// TBD: The previous is no longer true. Consider enhancing this code to count
// up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
// sets pop1 for the whole array, but that value is not used here. 001215:
// Maybe its true again?
case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
#ifndef JU_64BIT
case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
#else
case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
#endif
case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
{
Pjbl_t Pjbl;
// Common code (state-independent) for all cases of linear branches:
BranchL:
Pjbl = P_JBL(Pjp->jp_Addr);
for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
{
if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
// >=, but instead use the following expression:
if (pop1lower + pop1 > Count0) // Index is in this expanse.
{
JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
Pjp = (Pjbl->jbl_jp) + jpnum;
goto SMByCount; // look under this expanse.
}
pop1lower += pop1; // add this JPs pop1.
}
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_L
// ----------------------------------------------------------------------------
// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
// until finding the expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
#ifndef JU_64BIT
case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
#else
case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
#endif
case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
{
Pjbb_t Pjbb;
// Common code (state-independent) for all cases of bitmap branches:
BranchB:
Pjbb = P_JBB(Pjp->jp_Addr);
// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
//
// Note: BMPJP0 exists separately to support assertions.
#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
// Common code for descending through a JP:
//
// Determine the digit for the expanse and save it in *PIndex; then "recurse".
#define JBB_FOUNDEXPANSE \
{ \
JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
JU_SETDIGIT(*PIndex, digit, state); \
Pjp = BMPJP(subexp, jpnum); \
goto SMByCount; \
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, adding each "below" JPs pop1:
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = 0; jpnum < jpcount; ++jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBB_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses
// pop1:
else
{
#ifdef SMARTMETRICS
++jbb_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBB_FOUNDEXPANSE; // Index is in this expanse.
}
}
}
#endif // NOSMARTJBB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_B
// ----------------------------------------------------------------------------
// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
// downwards until finding the expanse (digit) containing Count, and "recurse".
case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
#ifndef JU_64BIT
case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
#else
case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
#endif
case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
{
Pjbu_t Pjbu;
// Common code (state-independent) for all cases of uncompressed branches:
BranchU:
Pjbu = P_JBU(Pjp->jp_Addr);
// Common code for descending through a JP:
//
// Save the digit for the expanse in *PIndex, then "recurse".
#define JBU_FOUNDEXPANSE \
{ \
JU_SETDIGIT(*PIndex, jpnum, state); \
Pjp = (Pjbu->jbu_jp) + jpnum; \
goto SMByCount; \
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, simply adding the pop1 of each JP:
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbu_upward;
#endif
for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBU_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jbu_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBU_FOUNDEXPANSE; // Index is in this expanse.
}
}
#endif // NOSMARTJBU
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_U
// ----------------------------------------------------------------------------
// LINEAR LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
// *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which
// is the only cases that need it anyway).
#define PREPL_DCD(cState) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPL
#ifdef JUDY1
#define PREPL_SETPOP1 // not needed in any cases.
#else
#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
#endif
#define PREPL \
Pjll = P_JLL(Pjp->jp_Addr); \
PREPL_SETPOP1; \
SETOFFSET(offset, Count0, pop1lower, Pjp)
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
PREPL_DCD(1);
JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
#endif
case cJU_JPLEAF2:
PREPL_DCD(2);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) Pjll)[offset];
JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
#ifndef JU_64BIT
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL;
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
#else
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL_DCD(3);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
case cJU_JPLEAF4:
PREPL_DCD(4);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) Pjll)[offset];
JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
case cJU_JPLEAF5:
{
Word_t lsb;
PREPL_DCD(5);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
}
case cJU_JPLEAF6:
{
Word_t lsb;
PREPL_DCD(6);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
}
case cJU_JPLEAF7:
{
Word_t lsb;
PREPL;
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
}
#endif
// ----------------------------------------------------------------------------
// BITMAP LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
// counting bits. First copy Dcd bytes (always present since state 1 <
// cJU_ROOTSTATE) to *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (bitmap leaf) as a side-effect, but dont depend on that.
case cJU_JPLEAF_B1:
{
Pjlb_t Pjlb;
JU_SETDCD(*PIndex, Pjp, 1);
Pjlb = P_JLB(Pjp->jp_Addr);
pop1 = JU_JPLEAF_POP0(Pjp) + 1;
// COUNT UPWARD, adding the pop1 of each subexpanse:
//
// The entire bitmap should fit in one cache line, but still try to save some
// CPU time by counting the fewest possible number of subexpanses from the
// bitmap.
//
// See header comments about limitations of this for Judy*ByCount().
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jlb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
goto LeafB1; // Index is in this subexpanse.
pop1lower += pop1; // add this subexpanses pop1.
}
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jlb_downward;
#endif
pop1lower += pop1; // add whole leaf to start.
for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
{
pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
goto LeafB1; // Index is in this subexpanse.
}
}
#endif // NOSMARTJLB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
// RETURN INDEX FOUND:
//
// Come here with subexp set to the correct subexpanse, and pop1lower set to
// the sum for all lower expanses and subexpanses in the Judy tree. Calculate
// and save in *PIndex the digit corresponding to the ordinal in this
// subexpanse.
LeafB1:
SETOFFSET(offset, Count0, pop1lower, Pjp);
JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
JU_SETDIGIT1(*PIndex, digit);
JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
} // case cJU_JPLEAF_B1
#ifdef JUDY1
// ----------------------------------------------------------------------------
// FULL POPULATION:
//
// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
// as the LSB in *PIndex.
case cJ1_JPFULLPOPU1:
JU_SETDCD(*PIndex, Pjp, 1);
SETOFFSET(offset, Count0, pop1lower, Pjp);
assert(offset >= 0);
assert(offset <= cJU_JPFULLPOPU1_POP0);
JU_SETDIGIT1(*PIndex, offset);
JU_RET_FOUND_FULLPOPU1;
#endif
// ----------------------------------------------------------------------------
// IMMEDIATE:
//
// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
// of the immediate Index.
#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
#endif
Imm_01:
DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
JU_RET_FOUND_IMM_01(Pjp);
// Shorthand for where to find start of Index bytes array:
#ifdef JUDY1
#define PJI (Pjp->jp_1Index)
#else
#define PJI (Pjp->jp_LIndex)
#endif
// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
// the Index Size of the Immediate:
#ifndef DEBUG // simple placeholder:
#define IMM(cPop1,Next) \
goto Next
#else // extra pop1-specific checking:
#define IMM(cPop1,Next) \
SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
goto Next
#endif
case cJU_JPIMMED_1_02: IMM( 2, Imm1);
case cJU_JPIMMED_1_03: IMM( 3, Imm1);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: IMM( 4, Imm1);
case cJU_JPIMMED_1_05: IMM( 5, Imm1);
case cJU_JPIMMED_1_06: IMM( 6, Imm1);
case cJU_JPIMMED_1_07: IMM( 7, Imm1);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
case cJ1_JPIMMED_1_10: IMM(10, Imm1);
case cJ1_JPIMMED_1_11: IMM(11, Imm1);
case cJ1_JPIMMED_1_12: IMM(12, Imm1);
case cJ1_JPIMMED_1_13: IMM(13, Imm1);
case cJ1_JPIMMED_1_14: IMM(14, Imm1);
case cJ1_JPIMMED_1_15: IMM(15, Imm1);
#endif
Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
JU_RET_FOUND_IMM(Pjp, offset);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: IMM(2, Imm2);
case cJU_JPIMMED_2_03: IMM(3, Imm2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: IMM(4, Imm2);
case cJ1_JPIMMED_2_05: IMM(5, Imm2);
case cJ1_JPIMMED_2_06: IMM(6, Imm2);
case cJ1_JPIMMED_2_07: IMM(7, Imm2);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: IMM(2, Imm3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: IMM(3, Imm3);
case cJ1_JPIMMED_3_04: IMM(4, Imm3);
case cJ1_JPIMMED_3_05: IMM(5, Imm3);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm3:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_4_02: IMM(2, Imm4);
case cJ1_JPIMMED_4_03: IMM(3, Imm4);
Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
case cJ1_JPIMMED_5_02: IMM(2, Imm5);
case cJ1_JPIMMED_5_03: IMM(3, Imm5);
Imm5:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_6_02: IMM(2, Imm6);
Imm6:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_7_02: IMM(2, Imm7);
Imm7:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif // (JUDY1 && JU_64BIT)
// ----------------------------------------------------------------------------
// UNEXPECTED JP TYPES:
default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // SMByCount switch.
/*NOTREACHED*/
} // Judy1ByCount() / JudyLByCount()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,314 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// Branch creation functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// ****************************************************************************
// J U D Y C R E A T E B R A N C H L
//
// Build a BranchL from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchL. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchL it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchL(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbl_t PjblRaw; // pointer to linear branch.
Pjbl_t Pjbl;
assert(ExpCnt <= cJU_BRANCHLMAXJPS);
PjblRaw = j__udyAllocJBL(Pjpm);
if (PjblRaw == (Pjbl_t) NULL) return(-1);
Pjbl = P_JBL(PjblRaw);
// Build a Linear Branch
Pjbl->jbl_NumJPs = ExpCnt;
// Copy from the Linear branch from splayed leaves
JU_COPYMEM(Pjbl->jbl_Expanse, Exp, ExpCnt);
JU_COPYMEM(Pjbl->jbl_jp, PJPs, ExpCnt);
// Pass back new pointer to the Linear branch in JP
Pjp->jp_Addr = (Word_t) PjblRaw;
return(1);
} // j__udyCreateBranchL()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H B
//
// Build a BranchB from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchB. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchB it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchB(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbb_t PjbbRaw; // pointer to bitmap branch.
Pjbb_t Pjbb;
Word_t ii, jj; // Temps
uint8_t CurrSubExp; // Current sub expanse for BM
// This assertion says the number of populated subexpanses is not too large.
// This function is only called when a BranchL overflows to a BranchB or when a
// cascade occurs, meaning a leaf overflows. Either way ExpCnt cant be very
// large, in fact a lot smaller than cJU_BRANCHBMAXJPS. (Otherwise a BranchU
// would be used.) Popping this assertion means something (unspecified) has
// gone very wrong, or else Judys design criteria have changed, although in
// fact there should be no HARM in creating a BranchB with higher actual
// fanout.
assert(ExpCnt <= cJU_BRANCHBMAXJPS);
// Get memory for a Bitmap branch
PjbbRaw = j__udyAllocJBB(Pjpm);
if (PjbbRaw == (Pjbb_t) NULL) return(-1);
Pjbb = P_JBB(PjbbRaw);
// Get 1st "sub" expanse (0..7) of bitmap branch
CurrSubExp = Exp[0] / cJU_BITSPERSUBEXPB;
// Index thru all 1 byte sized expanses:
for (jj = ii = 0; ii <= ExpCnt; ii++)
{
Word_t SubExp; // Cannot be a uint8_t
// Make sure we cover the last one
if (ii == ExpCnt)
{
SubExp = cJU_ALLONES; // Force last one
}
else
{
// Calculate the "sub" expanse of the byte expanse
SubExp = Exp[ii] / cJU_BITSPERSUBEXPB; // Bits 5..7.
// Set the bit that represents the expanse in Exp[]
JU_JBB_BITMAP(Pjbb, SubExp) |= JU_BITPOSMASKB(Exp[ii]);
}
// Check if a new "sub" expanse range needed
if (SubExp != CurrSubExp)
{
// Get number of JPs in this sub expanse
Word_t NumJP = ii - jj;
Pjp_t PjpRaw;
Pjp_t Pjp;
PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm);
Pjp = P_JP(PjpRaw);
if (PjpRaw == (Pjp_t) NULL) // out of memory.
{
// Free any previous allocations:
while(CurrSubExp--)
{
NumJP = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,
CurrSubExp));
if (NumJP)
{
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb,
CurrSubExp), NumJP, Pjpm);
}
}
j__udyFreeJBB(PjbbRaw, Pjpm);
return(-1);
}
// Place the array of JPs in bitmap branch:
JU_JBB_PJP(Pjbb, CurrSubExp) = PjpRaw;
// Copy the JPs to new leaf:
JU_COPYMEM(Pjp, PJPs + jj, NumJP);
// On to the next bitmap branch "sub" expanse:
jj = ii;
CurrSubExp = SubExp;
}
} // for each 1-byte expanse
// Pass back some of the JP to the new Bitmap branch:
Pjp->jp_Addr = (Word_t) PjbbRaw;
return(1);
} // j__udyCreateBranchB()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H U
//
// Build a BranchU from a BranchB. Return with Pjp pointing to the BranchU.
// Free the BranchB and its JP subarrays.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchU(
Pjp_t Pjp,
Pvoid_t Pjpm)
{
jp_t JPNull;
Pjbu_t PjbuRaw;
Pjbu_t Pjbu;
Pjbb_t PjbbRaw;
Pjbb_t Pjbb;
Word_t ii, jj;
BITMAPB_t BitMap;
Pjp_t PDstJP;
#ifdef JU_STAGED_EXP
jbu_t BranchU; // Staged uncompressed branch
#else
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
#endif
JU_JPSETADT(&JPNull, 0, 0, JU_JPTYPE(Pjp) - cJU_JPBRANCH_B2 + cJU_JPNULL1);
// Get the pointer to the BranchB:
PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
Pjbb = P_JBB(PjbbRaw);
// Set the pointer to the Uncompressed branch
#ifdef JU_STAGED_EXP
PDstJP = BranchU.jbu_jp;
#else
PDstJP = Pjbu->jbu_jp;
#endif
for (ii = 0; ii < cJU_NUMSUBEXPB; ii++)
{
Pjp_t PjpA;
Pjp_t PjpB;
PjpB = PjpA = P_JP(JU_JBB_PJP(Pjbb, ii));
// Get the bitmap for this subexpanse
BitMap = JU_JBB_BITMAP(Pjbb, ii);
// NULL empty subexpanses
if (BitMap == 0)
{
// But, fill with NULLs
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
PDstJP[jj] = JPNull;
}
PDstJP += cJU_BITSPERSUBEXPB;
continue;
}
// Check if Uncompressed subexpanse
if (BitMap == cJU_FULLBITMAPB)
{
// Copy subexpanse to the Uncompressed branch intact
JU_COPYMEM(PDstJP, PjpA, cJU_BITSPERSUBEXPB);
// Bump to next subexpanse
PDstJP += cJU_BITSPERSUBEXPB;
// Set length of subexpanse
jj = cJU_BITSPERSUBEXPB;
}
else
{
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
// Copy JP or NULLJP depending on bit
if (BitMap & 1) { *PDstJP = *PjpA++; }
else { *PDstJP = JPNull; }
PDstJP++; // advance to next JP
BitMap >>= 1;
}
jj = PjpA - PjpB;
}
// Free the subexpanse:
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, ii), jj, Pjpm);
} // for each JP in BranchU
#ifdef JU_STAGED_EXP
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
// Copy staged branch to newly allocated branch:
//
// TBD: I think this code is broken.
*Pjbu = BranchU;
#endif // JU_STAGED_EXP
// Finally free the BranchB and put the BranchU in its place:
j__udyFreeJBB(PjbbRaw, Pjpm);
Pjp->jp_Addr = (Word_t) PjbuRaw;
Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_B;
return(1);
} // j__udyCreateBranchU()

File diff suppressed because it is too large Load Diff

View File

@ -1,213 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy*First[Empty]() and Judy*Last[Empty]() routines for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// These are inclusive versions of Judy*Next[Empty]() and Judy*Prev[Empty]().
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
// ****************************************************************************
// J U D Y 1 F I R S T
// J U D Y L F I R S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1First
#else
FUNCTION PPvoid_t JudyLFirst
#endif
(
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError // optional, for returning error info.
)
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Next(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLNext(PArray, PIndex, PJError));
}
#endif
} // Judy1First() / JudyLFirst()
// ****************************************************************************
// J U D Y 1 L A S T
// J U D Y L L A S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1Last(
#else
FUNCTION PPvoid_t JudyLLast(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Prev(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLPrev(PArray, PIndex, PJError));
}
#endif
} // Judy1Last() / JudyLLast()
// ****************************************************************************
// J U D Y 1 F I R S T E M P T Y
// J U D Y L F I R S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1FirstEmpty(
#else
FUNCTION int JudyLFirstEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1NextEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLNextEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1FirstEmpty() / JudyLFirstEmpty()
// ****************************************************************************
// J U D Y 1 L A S T E M P T Y
// J U D Y L L A S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1LastEmpty(
#else
FUNCTION int JudyLLastEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1PrevEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLPrevEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1LastEmpty() / JudyLLastEmpty()

View File

@ -1,363 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
// Return the number of bytes freed from the array.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
// ****************************************************************************
// J U D Y 1 F R E E A R R A Y
// J U D Y L F R E E A R R A Y
//
// See the Judy*(3C) manual entry for details.
//
// This code is written recursively, at least at first, because thats much
// simpler. Hope its fast enough.
#ifdef JUDY1
FUNCTION Word_t Judy1FreeArray
#else
FUNCTION Word_t JudyLFreeArray
#endif
(
PPvoid_t PPArray, // array to free.
PJError_t PJError // optional, for returning error info.
)
{
jpm_t jpm; // local to accumulate free statistics.
// CHECK FOR NULL POINTER (error by caller):
if (PPArray == (PPvoid_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
return(JERR);
}
DBGCODE(JudyCheckPop(*PPArray);)
// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
// logging in TRACEMI2.
jpm.jpm_Pop0 = 0; // see above.
jpm.jpm_TotalMemWords = 0; // initialize memory freed.
// Empty array:
if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF:
if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD)); // see above.
}
else
// Rootstate leaves: just free the leaf:
// Common code for returning the amount of memory freed.
//
// Note: In a an ordinary LEAFW, pop0 = *PPArray[0].
//
// Accumulate (negative) words freed, while freeing objects.
// Return the positive bytes freed.
{
Pjpm_t Pjpm = P_JPM(*PPArray);
Word_t TotalMem = Pjpm->jpm_TotalMemWords;
j__udyFreeSM(&(Pjpm->jpm_JP), &jpm); // recurse through tree.
j__udyFreeJPM(Pjpm, &jpm);
// Verify the array was not corrupt. This means that amount of memory freed
// (which is negative) is equal to the initial amount:
if (TotalMem + jpm.jpm_TotalMemWords)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
return(JERR);
}
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (TotalMem * cJU_BYTESPERWORD);
}
} // Judy1FreeArray() / JudyLFreeArray()
// ****************************************************************************
// __ J U D Y F R E E S M
//
// Given a pointer to a JP, recursively visit and free (depth first) all nodes
// in a Judy array BELOW the JP, but not the JP itself. Accumulate in *Pjpm
// the total words freed (as a negative value). "SM" = State Machine.
//
// Note: Corruption is not detected at this level because during a FreeArray,
// if the code hasnt already core dumped, its better to remain silent, even
// if some memory has not been freed, than to bother the caller about the
// corruption. TBD: Is this true? If not, must list all legitimate JPNULL
// and JPIMMED above first, and revert to returning bool_t (see 4.34).
FUNCTION void j__udyFreeSM(
Pjp_t Pjp, // top of Judy (top-state).
Pjpm_t Pjpm) // to return words freed.
{
Word_t Pop1;
switch (JU_JPTYPE(Pjp))
{
#ifdef JUDY1
// FULL EXPANSE -- nothing to free for this jp_Type.
case cJ1_JPFULLPOPU1:
break;
#endif
// JUDY BRANCH -- free the sub-tree depth first:
// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL:
//
// Note: There are no null JPs in a JBL.
case cJU_JPBRANCH_L:
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif // JU_64BIT
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
Word_t offset;
for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
break;
}
// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
//
// Note: There are no null JPs in a JBB.
case cJU_JPBRANCH_B:
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif // JU_64BIT
{
Word_t subexp;
Word_t offset;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
if (jpcount)
{
for (offset = 0; offset < jpcount; ++offset)
{
j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
Pjpm);
}
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
}
}
j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
break;
}
// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
// itself:
//
// Note: Null JPs are handled during recursion at a lower state.
case cJU_JPBRANCH_U:
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif // JU_64BIT
{
Word_t offset;
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
break;
}
// -- Cases below here terminate and do not recurse. --
// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
//
// Note: cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif
case cJU_JPLEAF2:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF3:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPLEAF4:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF5:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF6:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF7:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif // JU_64BIT
// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
case cJU_JPLEAF_B1:
{
#ifdef JUDYL
Word_t subexp;
Word_t jpcount;
Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
// Free the value areas in the bitmap leaf:
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
if (jpcount)
j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
}
#endif // JUDYL
j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
break;
} // case cJU_JPLEAF_B1
#ifdef JUDYL
// IMMED*:
//
// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
case cJU_JPIMMED_1_02:
case cJU_JPIMMED_1_03:
#ifdef JU_64BIT
case cJU_JPIMMED_1_04:
case cJU_JPIMMED_1_05:
case cJU_JPIMMED_1_06:
case cJU_JPIMMED_1_07:
#endif
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPIMMED_2_02:
case cJU_JPIMMED_2_03:
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPIMMED_3_02:
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
break;
#endif // JU_64BIT
#endif // JUDYL
// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
//
// Note: Lump together no-op and invalid JP types; see function header
// comments.
default: break;
} // switch (JU_JPTYPE(Pjp))
} // j__udyFreeSM()

View File

@ -1,135 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// BranchL insertion functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
// ****************************************************************************
// __ J U D Y I N S E R T B R A N C H
//
// Insert 2-element BranchL in between Pjp and Pjp->jp_Addr.
//
// Return -1 if out of memory, otherwise return 1.
FUNCTION int j__udyInsertBranch(
Pjp_t Pjp, // JP containing narrow pointer.
Word_t Index, // outlier to Pjp.
Word_t BranchLevel, // of what JP points to, mapped from JP type.
Pjpm_t Pjpm) // for global accounting.
{
jp_t JP2 [2];
jp_t JP;
Pjp_t PjpNull;
Word_t XorExp;
Word_t Inew, Iold;
Word_t DCDMask; // initially for original BranchLevel.
int Ret;
uint8_t Exp2[2];
uint8_t DecodeByteN, DecodeByteO;
// Get the current mask for the DCD digits:
DCDMask = cJU_DCDMASK(BranchLevel);
// Obtain Dcd bits that differ between Index and JP, shifted so the
// digit for BranchLevel is the LSB:
XorExp = ((Index ^ JU_JPDCDPOP0(Pjp)) & (cJU_ALLONES >> cJU_BITSPERBYTE))
>> (BranchLevel * cJU_BITSPERBYTE);
assert(XorExp); // Index must be an outlier.
// Count levels between object under narrow pointer and the level at which
// the outlier diverges from it, which is always at least initial
// BranchLevel + 1, to end up with the level (JP type) at which to insert
// the new intervening BranchL:
do { ++BranchLevel; } while ((XorExp >>= cJU_BITSPERBYTE));
assert((BranchLevel > 1) && (BranchLevel < cJU_ROOTSTATE));
// Get the MSB (highest digit) that differs between the old expanse and
// the new Index to insert:
DecodeByteO = JU_DIGITATSTATE(JU_JPDCDPOP0(Pjp), BranchLevel);
DecodeByteN = JU_DIGITATSTATE(Index, BranchLevel);
assert(DecodeByteO != DecodeByteN);
// Determine sorted order for old expanse and new Index digits:
if (DecodeByteN > DecodeByteO) { Iold = 0; Inew = 1; }
else { Iold = 1; Inew = 0; }
// Copy old JP into staging area for new Branch
JP2 [Iold] = *Pjp;
Exp2[Iold] = DecodeByteO;
Exp2[Inew] = DecodeByteN;
// Create a 2 Expanse Linear branch
//
// Note: Pjp->jp_Addr is set by j__udyCreateBranchL()
Ret = j__udyCreateBranchL(Pjp, JP2, Exp2, 2, Pjpm);
if (Ret == -1) return(-1);
// Get Pjp to the NULL of where to do insert
PjpNull = ((P_JBL(Pjp->jp_Addr))->jbl_jp) + Inew;
// Convert to a cJU_JPIMMED_*_01 at the correct level:
// Build JP and set type below to: cJU_JPIMMED_X_01
JU_JPSETADT(PjpNull, 0, Index, cJU_JPIMMED_1_01 - 2 + BranchLevel);
// Return pointer to Value area in cJU_JPIMMED_X_01
JUDYLCODE(Pjpm->jpm_PValue = (Pjv_t) PjpNull;)
// The old JP now points to a BranchL that is at higher level. Therefore
// it contains excess DCD bits (in the least significant position) that
// must be removed (zeroed); that is, they become part of the Pop0
// subfield. Note that the remaining (lower) bytes in the Pop0 field do
// not change.
//
// Take from the old DCDMask, which went "down" to a lower BranchLevel,
// and zero any high bits that are still in the mask at the new, higher
// BranchLevel; then use this mask to zero the bits in jp_DcdPopO:
// Set old JP to a BranchL at correct level
Pjp->jp_Type = cJU_JPBRANCH_L2 - 2 + BranchLevel;
DCDMask ^= cJU_DCDMASK(BranchLevel);
DCDMask = ~DCDMask & JU_JPDCDPOP0(Pjp);
JP = *Pjp;
JU_JPSETADT(Pjp, JP.jp_Addr, DCDMask, JP.jp_Type);
return(1);
} // j__udyInsertBranch()

View File

@ -1,782 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy malloc/free interface functions for Judy1 and JudyL.
//
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
// calls at the interface level. (See also TRACEMF in lower-level code.)
// Use -DTRACEMI2 for a terser format suitable for trace analysis.
//
// There can be malloc namespace bits in the LSBs of "raw" addresses from most,
// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
// only (for assertions). This test ensures that (a) all callers properly mask
// the namespace bits out before dereferencing a pointer (or else a core dump
// occurs), and (b) all callers send "raw" (unmasked) addresses to
// j__udy*Free*() calls.
//
// Note: Currently -DDEBUG turns on MALLOCBITS automatically.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// Set "hidden" global j__uMaxWords to the maximum number of words to allocate
// to any one array (large enough to have a JPM, otherwise j__uMaxWords is
// ignored), to trigger a fake malloc error when the number is exceeded. Note,
// this code is always executed, not #ifdefd, because its virtually free.
//
// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
// MAXINT, not zero, by default.
Word_t j__uMaxWords = ~0UL;
// This macro hides the faking of a malloc failure:
//
// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
// complexity of first adding WordsNow, meaning the trigger point is not
// exactly where you might assume, but it shouldnt matter.
#define MALLOC(MallocFunc,WordsPrev,WordsNow) \
(((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
// Clear words starting at address:
//
// Note: Only use this for objects that care; in other cases, it doesnt
// matter if the objects memory is pre-zeroed.
#define ZEROWORDS(Addr,Words) \
{ \
Word_t Words__ = (Words); \
PWord_t Addr__ = (PWord_t) (Addr); \
while (Words__--) *Addr__++ = 0UL; \
}
#ifdef TRACEMI
// TRACING SUPPORT:
//
// Note: For TRACEMI, use a format for address printing compatible with other
// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
// part on 64-bit systems.
//
// TBD: The trace macros need fixing for alternate address types.
//
// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
// engine used.
#include <stdio.h>
static Word_t j__udyMemSequence = 0L; // event sequence number.
#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#else
#ifdef TRACEMI2
#include <stdio.h>
#define b_pw cJU_BYTESPERWORD
#define TRACE_ALLOC5(a,b,c,d,e) \
(void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_FREE5( a,b,c,d,e) \
(void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_ALLOC6(a,b,c,d,e,f) \
(void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
#define TRACE_FREE6( a,b,c,d,e,f) \
(void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
static Word_t j__udyMemSequence = 0L; // event sequence number.
#else
#define TRACE_ALLOC5(a,b,c,d,e) // null.
#define TRACE_FREE5( a,b,c,d,e) // null.
#define TRACE_ALLOC6(a,b,c,d,e,f) // null.
#define TRACE_FREE6( a,b,c,d,e,f) // null.
#endif // ! TRACEMI2
#endif // ! TRACEMI
// MALLOC NAMESPACE SUPPORT:
#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
#define MALLOCBITS 1
#endif
#ifdef MALLOCBITS
#define MALLOCBITS_VALUE 0x3 // bit pattern to use.
#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
#define MALLOCBITS_SET( Type,Addr) \
((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
#define MALLOCBITS_TEST(Type,Addr) \
assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
#else
#define MALLOCBITS_SET( Type,Addr) // null.
#define MALLOCBITS_TEST(Type,Addr) // null.
#endif
// SAVE ERROR INFORMATION IN A Pjpm:
//
// "Small" (invalid) Addr values are used to distinguish overrun and no-mem
// errors. (TBD, non-zero invalid values are no longer returned from
// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
#define J__UDYSETALLOCERROR(Addr) \
{ \
JU_ERRID(Pjpm) = __LINE__; \
if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
return(0); \
}
// ****************************************************************************
// ALLOCATION FUNCTIONS:
//
// To help the compiler catch coding errors, each function returns a specific
// object type.
//
// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
// sizeof(Word_t) to indicate the type of memory allocation failure. Other
// allocation functions convert this failure to a JU_ERRNO.
// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
// that is, without malloc namespace or root pointer type bits:
FUNCTION Pjpm_t j__udyAllocJPM(void)
{
Word_t Words = sizeof(jpm_t) / cJU_BYTESPERWORD;
Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
if ((Word_t) Pjpm > sizeof(Word_t))
{
ZEROWORDS(Pjpm, Words);
Pjpm->jpm_TotalMemWords = Words;
}
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
// MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
return(Pjpm);
} // j__udyAllocJPM()
FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
if ((Word_t) PjblRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBL(PjblRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjblRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbl_t, PjblRaw);
return(PjblRaw);
} // j__udyAllocJBL()
FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
if ((Word_t) PjbbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBB(PjbbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbb_t, PjbbRaw);
return(PjbbRaw);
} // j__udyAllocJBB()
FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
Pjp_t PjpRaw;
PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjpRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjpRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjp_t, PjpRaw);
return(PjpRaw);
} // j__udyAllocJBBJP()
FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
if ((Word_t) PjbuRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbuRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbu_t, PjbuRaw);
return(PjbuRaw);
} // j__udyAllocJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL2()
FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL3()
#ifdef JU_64BIT
FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL4()
FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL5()
FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL6()
FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL7()
#endif // JU_64BIT
// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
// other j__udyAlloc*() functions, they are returned non-raw, that is, without
// malloc namespace or root pointer type bits (the latter are added later by
// the caller):
FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1);
// MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
return(Pjlw);
} // j__udyAllocJLW()
FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
Pjlb_t PjlbRaw;
PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
if ((Word_t) PjlbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JLB(PjlbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjlbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjlb_t, PjlbRaw);
return(PjlbRaw);
} // j__udyAllocJLB1()
#ifdef JUDYL
FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
Pjv_t PjvRaw;
PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjvRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjvRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjv_t, PjvRaw);
return(PjvRaw);
} // j__udyLAllocJV()
#endif // JUDYL
// ****************************************************************************
// FREE FUNCTIONS:
//
// To help the compiler catch coding errors, each function takes a specific
// object type to free.
// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
// bits present, that is, they must be stripped by the caller using P_JPM():
FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
{
Word_t Words = sizeof(jpm_t) / cJU_BYTESPERWORD;
// MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
JudyFree((Pvoid_t) PjpmFree, Words);
if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
// really will be 0, not cJU_LEAFW_MAXPOP1.
TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
} // j__udyFreeJPM()
FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbl_t, Pjbl);
JudyFreeVirtual((Pvoid_t) Pjbl, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBL()
FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbb_t, Pjbb);
JudyFreeVirtual((Pvoid_t) Pjbb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBB()
FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
MALLOCBITS_TEST(Pjp_t, Pjp);
JudyFree((Pvoid_t) Pjp, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBBJP()
FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbu_t, Pjbu);
JudyFreeVirtual((Pvoid_t) Pjbu, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL2()
FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL3()
#ifdef JU_64BIT
FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL4()
FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL5()
FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL6()
FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL7()
#endif // JU_64BIT
// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
// bits present, that is, they are stripped by P_JLW():
FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
// MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
JudyFree((Pvoid_t) Pjlw, Words);
if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1 - 1);
} // j__udyFreeJLW()
FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjlb_t, Pjlb);
JudyFree((Pvoid_t) Pjlb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLB1()
#ifdef JUDYL
FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjv_t, Pjv);
JudyFree((Pvoid_t) Pjv, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyLFreeJV()
#endif // JUDYL

View File

@ -1,259 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
FUNCTION static Word_t j__udyGetMemActive(Pjp_t);
// ****************************************************************************
// J U D Y 1 M E M A C T I V E
// J U D Y L M E M A C T I V E
#ifdef JUDY1
FUNCTION Word_t Judy1MemActive
#else
FUNCTION Word_t JudyLMemActive
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
if (PArray == (Pcvoid_t)NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Word_t Words = Pjlw[0] + 1; // population.
#ifdef JUDY1
return((Words + 1) * sizeof(Word_t));
#else
return(((Words * 2) + 1) * sizeof(Word_t));
#endif
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
return(j__udyGetMemActive(&Pjpm->jpm_JP) + sizeof(jpm_t));
}
} // JudyMemActive()
// ****************************************************************************
// __ J U D Y G E T M E M A C T I V E
FUNCTION static Word_t j__udyGetMemActive(
Pjp_t Pjp) // top of subtree.
{
Word_t offset; // in a branch.
Word_t Bytes = 0; // actual bytes used at this level.
Word_t IdxSz; // bytes per index in leaves
switch (JU_JPTYPE(Pjp))
{
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif
case cJU_JPBRANCH_L:
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
Bytes += j__udyGetMemActive((Pjbl->jbl_jp) + offset);
return(Bytes + sizeof(jbl_t));
}
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif
case cJU_JPBRANCH_B:
{
Word_t subexp;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
Bytes += jpcount * sizeof(jp_t);
for (offset = 0; offset < jpcount; ++offset)
{
Bytes += j__udyGetMemActive(P_JP(JU_JBB_PJP(Pjbb, subexp))
+ offset);
}
}
return(Bytes + sizeof(jbb_t));
}
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif
case cJU_JPBRANCH_U:
{
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
{
if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
&& ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
{
continue; // skip null JP to save time.
}
Bytes += j__udyGetMemActive(Pjbu->jbu_jp + offset);
}
return(Bytes + sizeof(jbu_t));
}
// -- Cases below here terminate and do not recurse. --
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1: IdxSz = 1; goto LeafWords;
#endif
case cJU_JPLEAF2: IdxSz = 2; goto LeafWords;
case cJU_JPLEAF3: IdxSz = 3; goto LeafWords;
#ifdef JU_64BIT
case cJU_JPLEAF4: IdxSz = 4; goto LeafWords;
case cJU_JPLEAF5: IdxSz = 5; goto LeafWords;
case cJU_JPLEAF6: IdxSz = 6; goto LeafWords;
case cJU_JPLEAF7: IdxSz = 7; goto LeafWords;
#endif
LeafWords:
#ifdef JUDY1
return(IdxSz * (JU_JPLEAF_POP0(Pjp) + 1));
#else
return((IdxSz + sizeof(Word_t))
* (JU_JPLEAF_POP0(Pjp) + 1));
#endif
case cJU_JPLEAF_B1:
{
#ifdef JUDY1
return(sizeof(jlb_t));
#else
Bytes = (JU_JPLEAF_POP0(Pjp) + 1) * sizeof(Word_t);
return(Bytes + sizeof(jlb_t));
#endif
}
JUDY1CODE(case cJ1_JPFULLPOPU1: return(0);)
#ifdef JUDY1
#define J__Mpy 0
#else
#define J__Mpy sizeof(Word_t)
#endif
case cJU_JPIMMED_1_01: return(0);
case cJU_JPIMMED_2_01: return(0);
case cJU_JPIMMED_3_01: return(0);
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: return(0);
case cJU_JPIMMED_5_01: return(0);
case cJU_JPIMMED_6_01: return(0);
case cJU_JPIMMED_7_01: return(0);
#endif
case cJU_JPIMMED_1_02: return(J__Mpy * 2);
case cJU_JPIMMED_1_03: return(J__Mpy * 3);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: return(J__Mpy * 4);
case cJU_JPIMMED_1_05: return(J__Mpy * 5);
case cJU_JPIMMED_1_06: return(J__Mpy * 6);
case cJU_JPIMMED_1_07: return(J__Mpy * 7);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: return(0);
case cJ1_JPIMMED_1_09: return(0);
case cJ1_JPIMMED_1_10: return(0);
case cJ1_JPIMMED_1_11: return(0);
case cJ1_JPIMMED_1_12: return(0);
case cJ1_JPIMMED_1_13: return(0);
case cJ1_JPIMMED_1_14: return(0);
case cJ1_JPIMMED_1_15: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: return(J__Mpy * 2);
case cJU_JPIMMED_2_03: return(J__Mpy * 3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: return(0);
case cJ1_JPIMMED_2_05: return(0);
case cJ1_JPIMMED_2_06: return(0);
case cJ1_JPIMMED_2_07: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: return(J__Mpy * 2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: return(0);
case cJ1_JPIMMED_3_04: return(0);
case cJ1_JPIMMED_3_05: return(0);
case cJ1_JPIMMED_4_02: return(0);
case cJ1_JPIMMED_4_03: return(0);
case cJ1_JPIMMED_5_02: return(0);
case cJ1_JPIMMED_5_03: return(0);
case cJ1_JPIMMED_6_02: return(0);
case cJ1_JPIMMED_7_02: return(0);
#endif
} // switch (JU_JPTYPE(Pjp))
return(0); // to make some compilers happy.
} // j__udyGetMemActive()

View File

@ -1,61 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
#ifdef JUDY1
FUNCTION Word_t Judy1MemUsed
#else // JUDYL
FUNCTION Word_t JudyLMemUsed
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
Word_t Words = 0;
if (PArray == (Pcvoid_t) NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Words = JU_LEAFWPOPTOWORDS(Pjlw[0] + 1); // based on pop1.
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
Words = Pjpm->jpm_TotalMemWords;
}
return(Words * sizeof(Word_t)); // convert to bytes.
} // Judy1MemUsed() / JudyLMemUsed()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
// @(#) From generation tool: $Revision$ $Source$
//
#include "Judy1.h"
// Leave the malloc() sizes readable in the binary (via strings(1)):
const char * Judy1MallocSizes = "Judy1MallocSizes = 3, 5, 7, 11, 15, 23, 32, 47, 64, Leaf1 = 20";
// object uses 64 words
// cJU_BITSPERSUBEXPB = 32
const uint8_t
j__1_BranchBJPPopToWords[cJU_BITSPERSUBEXPB + 1] =
{
0,
3, 5, 7, 11, 11, 15, 15, 23,
23, 23, 23, 32, 32, 32, 32, 32,
47, 47, 47, 47, 47, 47, 47, 64,
64, 64, 64, 64, 64, 64, 64, 64
};
// object uses 5 words
// cJ1_LEAF1_MAXPOP1 = 20
const uint8_t
j__1_Leaf1PopToWords[cJ1_LEAF1_MAXPOP1 + 1] =
{
0,
3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 5, 5, 5, 5,
5, 5, 5, 5
};
// object uses 32 words
// cJ1_LEAF2_MAXPOP1 = 64
const uint8_t
j__1_Leaf2PopToWords[cJ1_LEAF2_MAXPOP1 + 1] =
{
0,
3, 3, 3, 3, 3, 3, 5, 5,
5, 5, 7, 7, 7, 7, 11, 11,
11, 11, 11, 11, 11, 11, 15, 15,
15, 15, 15, 15, 15, 15, 23, 23,
23, 23, 23, 23, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32
};
// object uses 32 words
// cJ1_LEAF3_MAXPOP1 = 42
const uint8_t
j__1_Leaf3PopToWords[cJ1_LEAF3_MAXPOP1 + 1] =
{
0,
3, 3, 3, 3, 5, 5, 7, 7,
7, 11, 11, 11, 11, 11, 15, 15,
15, 15, 15, 15, 23, 23, 23, 23,
23, 23, 23, 23, 23, 23, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32
};
// object uses 32 words
// cJ1_LEAFW_MAXPOP1 = 31
const uint8_t
j__1_LeafWPopToWords[cJ1_LEAFW_MAXPOP1 + 1] =
{
0,
3, 3, 5, 5, 7, 7, 11, 11,
11, 11, 15, 15, 15, 15, 23, 23,
23, 23, 23, 23, 23, 23, 32, 32,
32, 32, 32, 32, 32, 32, 32
};

View File

@ -1,296 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
#ifndef JU_WIN
#include <unistd.h> // unavailable on win_*.
#endif
#include <stdlib.h>
#include <stdio.h>
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#define TERMINATOR 999 // terminator for Alloc tables
#define BPW sizeof(Word_t) // define bytes per word
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
FILE *fd;
// Definitions come from header files Judy1.h and JudyL.h:
int AllocSizes[] = ALLOCSIZES;
#define ROUNDUP(BYTES,BPW,OFFSETW) \
((((BYTES) + (BPW) - 1) / (BPW)) + (OFFSETW))
// ****************************************************************************
// G E N T A B L E
//
// Note: "const" is required for newer compilers.
FUNCTION void GenTable(
const char * TableName, // name of table string
const char * TableSize, // dimentioned size string
int IndexBytes, // bytes per Index
int LeafSize, // number elements in object
int ValueBytes, // bytes per Value
int OffsetWords) // 1 for LEAFW
{
int * PAllocSizes = AllocSizes;
int OWord;
int CurWord;
int IWord;
int ii;
int BytesOfIndex;
int BytesOfObject;
int Index;
int LastWords;
int Words [1000] = { 0 };
int Offset[1000] = { 0 };
int MaxWords;
MaxWords = ROUNDUP((IndexBytes + ValueBytes) * LeafSize, BPW, OffsetWords);
Words[0] = 0;
Offset[0] = 0;
CurWord = TERMINATOR;
// Walk through all number of Indexes in table:
for (Index = 1; /* null */; ++Index)
{
// Calculate byte required for next size:
BytesOfIndex = IndexBytes * Index;
BytesOfObject = (IndexBytes + ValueBytes) * Index;
// Round up and calculate words required for next size:
OWord = ROUNDUP(BytesOfObject, BPW, OffsetWords);
IWord = ROUNDUP(BytesOfIndex, BPW, OffsetWords);
// Root-level leaves of population of 1 and 2 do not have the 1 word offset:
// Save minimum value of offset:
Offset[Index] = IWord;
// Round up to next available size of words:
while (OWord > *PAllocSizes) PAllocSizes++;
if (Index == LeafSize)
{
CurWord = Words[Index] = OWord;
break;
}
// end of available sizes ?
if (*PAllocSizes == TERMINATOR)
{
fprintf(stderr, "BUG, in %sPopToWords, sizes not big enough for object\n", TableName);
exit(1);
}
// Save words required and last word:
if (*PAllocSizes < MaxWords) { CurWord = Words[Index] = *PAllocSizes; }
else { CurWord = Words[Index] = MaxWords; }
} // for each index
LastWords = TERMINATOR;
// Round up to largest size in each group of malloc sizes:
for (ii = LeafSize; ii > 0; ii--)
{
if (LastWords > (Words[ii] - ii)) LastWords = Offset[ii];
else Offset[ii] = LastWords;
}
// Print the PopToWords[] table:
fprintf(fd,"\n//\tobject uses %d words\n", CurWord);
fprintf(fd,"//\t%s = %d\n", TableSize, LeafSize);
fprintf(fd,"const uint8_t\n");
fprintf(fd,"%sPopToWords[%s + 1] =\n", TableName, TableSize);
fprintf(fd,"{\n\t 0,");
for (ii = 1; ii <= LeafSize; ii++)
{
// 8 columns per line, starting with 1:
if ((ii % 8) == 1) fprintf(fd,"\n\t");
fprintf(fd,"%2d", Words[ii]);
// If not last number place comma:
if (ii != LeafSize) fprintf(fd,", ");
}
fprintf(fd,"\n};\n");
// Print the Offset table if needed:
if (! ValueBytes) return;
fprintf(fd,"const uint8_t\n");
fprintf(fd,"%sOffset[%s + 1] =\n", TableName, TableSize);
fprintf(fd,"{\n");
fprintf(fd,"\t 0,");
for (ii = 1; ii <= LeafSize; ii++)
{
if ((ii % 8) == 1) fprintf(fd,"\n\t");
fprintf(fd,"%2d", Offset[ii]);
if (ii != LeafSize) fprintf(fd,", ");
}
fprintf(fd,"\n};\n");
} // GenTable()
// ****************************************************************************
// M A I N
FUNCTION int main()
{
int ii;
#ifdef JUDY1
char *fname = "Judy1Tables.c";
#else
char *fname = "JudyLTables.c";
#endif
if ((fd = fopen(fname, "w")) == NULL){
perror("FATAL ERROR: could not write to Judy[1L]Tables.c file\n");
return (-1);
}
fprintf(fd,"// @(#) From generation tool: $Revision$ $Source$\n");
fprintf(fd,"//\n\n");
// ================================ Judy1 =================================
#ifdef JUDY1
fprintf(fd,"#include \"Judy1.h\"\n");
fprintf(fd,"// Leave the malloc() sizes readable in the binary (via "
"strings(1)):\n");
fprintf(fd,"const char * Judy1MallocSizes = \"Judy1MallocSizes =");
for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++)
fprintf(fd," %d,", AllocSizes[ii]);
#ifndef JU_64BIT
fprintf(fd," Leaf1 = %d\";\n\n", cJ1_LEAF1_MAXPOP1);
#else
fprintf(fd,"\";\n\n"); // no Leaf1 in this case.
#endif
// ================================ 32 bit ================================
#ifndef JU_64BIT
GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB,0,0);
GenTable("j__1_Leaf1", "cJ1_LEAF1_MAXPOP1", 1, cJ1_LEAF1_MAXPOP1, 0, 0);
GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0);
GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0);
GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 4, cJ1_LEAFW_MAXPOP1, 0, 1);
#endif
// ================================ 64 bit ================================
#ifdef JU_64BIT
GenTable("j__1_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB,0,0);
GenTable("j__1_Leaf2", "cJ1_LEAF2_MAXPOP1", 2, cJ1_LEAF2_MAXPOP1, 0, 0);
GenTable("j__1_Leaf3", "cJ1_LEAF3_MAXPOP1", 3, cJ1_LEAF3_MAXPOP1, 0, 0);
GenTable("j__1_Leaf4", "cJ1_LEAF4_MAXPOP1", 4, cJ1_LEAF4_MAXPOP1, 0, 0);
GenTable("j__1_Leaf5", "cJ1_LEAF5_MAXPOP1", 5, cJ1_LEAF5_MAXPOP1, 0, 0);
GenTable("j__1_Leaf6", "cJ1_LEAF6_MAXPOP1", 6, cJ1_LEAF6_MAXPOP1, 0, 0);
GenTable("j__1_Leaf7", "cJ1_LEAF7_MAXPOP1", 7, cJ1_LEAF7_MAXPOP1, 0, 0);
GenTable("j__1_LeafW", "cJ1_LEAFW_MAXPOP1", 8, cJ1_LEAFW_MAXPOP1, 0, 1);
#endif
#endif // JUDY1
// ================================ JudyL =================================
#ifdef JUDYL
fprintf(fd,"#include \"JudyL.h\"\n");
fprintf(fd,"// Leave the malloc() sizes readable in the binary (via "
"strings(1)):\n");
fprintf(fd,"const char * JudyLMallocSizes = \"JudyLMallocSizes =");
for (ii = 0; AllocSizes[ii] != TERMINATOR; ii++)
fprintf(fd," %d,", AllocSizes[ii]);
fprintf(fd," Leaf1 = %ld\";\n\n", (Word_t)cJL_LEAF1_MAXPOP1);
#ifndef JU_64BIT
// ================================ 32 bit ================================
GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB", 8, cJU_BITSPERSUBEXPB, 0,0);
GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0);
GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0);
GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0);
GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 4, cJL_LEAFW_MAXPOP1, BPW,1);
GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 4, cJU_BITSPERSUBEXPL, 0,0);
#endif // 32 BIT
#ifdef JU_64BIT
// ================================ 64 bit ================================
GenTable("j__L_BranchBJP","cJU_BITSPERSUBEXPB",16, cJU_BITSPERSUBEXPB, 0,0);
GenTable("j__L_Leaf1", "cJL_LEAF1_MAXPOP1", 1, cJL_LEAF1_MAXPOP1, BPW,0);
GenTable("j__L_Leaf2", "cJL_LEAF2_MAXPOP1", 2, cJL_LEAF2_MAXPOP1, BPW,0);
GenTable("j__L_Leaf3", "cJL_LEAF3_MAXPOP1", 3, cJL_LEAF3_MAXPOP1, BPW,0);
GenTable("j__L_Leaf4", "cJL_LEAF4_MAXPOP1", 4, cJL_LEAF4_MAXPOP1, BPW,0);
GenTable("j__L_Leaf5", "cJL_LEAF5_MAXPOP1", 5, cJL_LEAF5_MAXPOP1, BPW,0);
GenTable("j__L_Leaf6", "cJL_LEAF6_MAXPOP1", 6, cJL_LEAF6_MAXPOP1, BPW,0);
GenTable("j__L_Leaf7", "cJL_LEAF7_MAXPOP1", 7, cJL_LEAF7_MAXPOP1, BPW,0);
GenTable("j__L_LeafW", "cJL_LEAFW_MAXPOP1", 8, cJL_LEAFW_MAXPOP1, BPW,1);
GenTable("j__L_LeafV", "cJU_BITSPERSUBEXPL", 8, cJU_BITSPERSUBEXPL, 0,0);
#endif // 64 BIT
#endif // JUDYL
fclose(fd);
return(0);
} // main()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
INCLUDES = -I. -I.. -I../JudyCommon/
AM_CFLAGS = -DJUDY1 @WARN_CFLAGS@
noinst_LTLIBRARIES = libJudy1.la libnext.la libprev.la libcount.la libinline.la
libJudy1_la_SOURCES = Judy1Test.c Judy1Tables.c Judy1Set.c Judy1SetArray.c Judy1Unset.c Judy1Cascade.c Judy1Count.c Judy1CreateBranch.c Judy1Decascade.c Judy1First.c Judy1FreeArray.c Judy1InsertBranch.c Judy1MallocIF.c Judy1MemActive.c Judy1MemUsed.c
libnext_la_SOURCES = Judy1Next.c Judy1NextEmpty.c
libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT
libprev_la_SOURCES = Judy1Prev.c Judy1PrevEmpty.c
libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV
libcount_la_SOURCES = Judy1ByCount.c
libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB
libinline_la_SOURCES = j__udy1Test.c
libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE
Judy1Tables.c: Judy1TablesGen.c
$(CC) $(INCLUDES) $(AM_CFLAGS) @CFLAGS@ -o Judy1TablesGen Judy1TablesGen.c; ./Judy1TablesGen
Judy1Test.c: copies
copies:
cp -f ../JudyCommon/JudyByCount.c Judy1ByCount.c
cp -f ../JudyCommon/JudyCascade.c Judy1Cascade.c
cp -f ../JudyCommon/JudyCount.c Judy1Count.c
cp -f ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c
cp -f ../JudyCommon/JudyDecascade.c Judy1Decascade.c
cp -f ../JudyCommon/JudyDel.c Judy1Unset.c
cp -f ../JudyCommon/JudyFirst.c Judy1First.c
cp -f ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c
cp -f ../JudyCommon/JudyGet.c Judy1Test.c
cp -f ../JudyCommon/JudyGet.c j__udy1Test.c
cp -f ../JudyCommon/JudyInsArray.c Judy1SetArray.c
cp -f ../JudyCommon/JudyIns.c Judy1Set.c
cp -f ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c
cp -f ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c
cp -f ../JudyCommon/JudyMemActive.c Judy1MemActive.c
cp -f ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Next.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Prev.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c
cp -f ../JudyCommon/JudyTables.c Judy1TablesGen.c

View File

@ -1,558 +0,0 @@
# Makefile.in generated by automake 1.9.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SOURCES = $(libJudy1_la_SOURCES) $(libcount_la_SOURCES) $(libinline_la_SOURCES) $(libnext_la_SOURCES) $(libprev_la_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = src/Judy1
DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libJudy1_la_LIBADD =
am_libJudy1_la_OBJECTS = Judy1Test.lo Judy1Tables.lo Judy1Set.lo \
Judy1SetArray.lo Judy1Unset.lo Judy1Cascade.lo Judy1Count.lo \
Judy1CreateBranch.lo Judy1Decascade.lo Judy1First.lo \
Judy1FreeArray.lo Judy1InsertBranch.lo Judy1MallocIF.lo \
Judy1MemActive.lo Judy1MemUsed.lo
libJudy1_la_OBJECTS = $(am_libJudy1_la_OBJECTS)
libcount_la_LIBADD =
am_libcount_la_OBJECTS = libcount_la-Judy1ByCount.lo
libcount_la_OBJECTS = $(am_libcount_la_OBJECTS)
libinline_la_LIBADD =
am_libinline_la_OBJECTS = libinline_la-j__udy1Test.lo
libinline_la_OBJECTS = $(am_libinline_la_OBJECTS)
libnext_la_LIBADD =
am_libnext_la_OBJECTS = libnext_la-Judy1Next.lo \
libnext_la-Judy1NextEmpty.lo
libnext_la_OBJECTS = $(am_libnext_la_OBJECTS)
libprev_la_LIBADD =
am_libprev_la_OBJECTS = libprev_la-Judy1Prev.lo \
libprev_la-Judy1PrevEmpty.lo
libprev_la_OBJECTS = $(am_libprev_la_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(libJudy1_la_SOURCES) $(libcount_la_SOURCES) \
$(libinline_la_SOURCES) $(libnext_la_SOURCES) \
$(libprev_la_SOURCES)
DIST_SOURCES = $(libJudy1_la_SOURCES) $(libcount_la_SOURCES) \
$(libinline_la_SOURCES) $(libnext_la_SOURCES) \
$(libprev_la_SOURCES)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
F77 = @F77@
FFLAGS = @FFLAGS@
FLAVOR = @FLAVOR@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
VERSION_INFO = @VERSION_INFO@
WARN_CFLAGS = @WARN_CFLAGS@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_F77 = @ac_ct_F77@
ac_ct_LD = @ac_ct_LD@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
INCLUDES = -I. -I.. -I../JudyCommon/
AM_CFLAGS = -DJUDY1 @WARN_CFLAGS@
noinst_LTLIBRARIES = libJudy1.la libnext.la libprev.la libcount.la libinline.la
libJudy1_la_SOURCES = Judy1Test.c Judy1Tables.c Judy1Set.c Judy1SetArray.c Judy1Unset.c Judy1Cascade.c Judy1Count.c Judy1CreateBranch.c Judy1Decascade.c Judy1First.c Judy1FreeArray.c Judy1InsertBranch.c Judy1MallocIF.c Judy1MemActive.c Judy1MemUsed.c
libnext_la_SOURCES = Judy1Next.c Judy1NextEmpty.c
libnext_la_CFLAGS = $(AM_CFLAGS) -DJUDYNEXT
libprev_la_SOURCES = Judy1Prev.c Judy1PrevEmpty.c
libprev_la_CFLAGS = $(AM_CFLAGS) -DJUDYPREV
libcount_la_SOURCES = Judy1ByCount.c
libcount_la_CFLAGS = $(AM_CFLAGS) -DNOSMARTJBB -DNOSMARTJBU -DNOSMARTJLB
libinline_la_SOURCES = j__udy1Test.c
libinline_la_CFLAGS = $(AM_CFLAGS) -DJUDYGETINLINE
all: all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Judy1/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Judy1/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" != "$$p" || dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libJudy1.la: $(libJudy1_la_OBJECTS) $(libJudy1_la_DEPENDENCIES)
$(LINK) $(libJudy1_la_LDFLAGS) $(libJudy1_la_OBJECTS) $(libJudy1_la_LIBADD) $(LIBS)
libcount.la: $(libcount_la_OBJECTS) $(libcount_la_DEPENDENCIES)
$(LINK) $(libcount_la_LDFLAGS) $(libcount_la_OBJECTS) $(libcount_la_LIBADD) $(LIBS)
libinline.la: $(libinline_la_OBJECTS) $(libinline_la_DEPENDENCIES)
$(LINK) $(libinline_la_LDFLAGS) $(libinline_la_OBJECTS) $(libinline_la_LIBADD) $(LIBS)
libnext.la: $(libnext_la_OBJECTS) $(libnext_la_DEPENDENCIES)
$(LINK) $(libnext_la_LDFLAGS) $(libnext_la_OBJECTS) $(libnext_la_LIBADD) $(LIBS)
libprev.la: $(libprev_la_OBJECTS) $(libprev_la_DEPENDENCIES)
$(LINK) $(libprev_la_LDFLAGS) $(libprev_la_OBJECTS) $(libprev_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Cascade.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Count.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1CreateBranch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Decascade.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1First.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1FreeArray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1InsertBranch.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1MallocIF.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1MemActive.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1MemUsed.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Set.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1SetArray.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Tables.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Judy1Unset.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcount_la-Judy1ByCount.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libinline_la-j__udy1Test.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnext_la-Judy1Next.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnext_la-Judy1NextEmpty.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libprev_la-Judy1Prev.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libprev_la-Judy1PrevEmpty.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ if $(LTCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
libcount_la-Judy1ByCount.lo: Judy1ByCount.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcount_la_CFLAGS) $(CFLAGS) -MT libcount_la-Judy1ByCount.lo -MD -MP -MF "$(DEPDIR)/libcount_la-Judy1ByCount.Tpo" -c -o libcount_la-Judy1ByCount.lo `test -f 'Judy1ByCount.c' || echo '$(srcdir)/'`Judy1ByCount.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libcount_la-Judy1ByCount.Tpo" "$(DEPDIR)/libcount_la-Judy1ByCount.Plo"; else rm -f "$(DEPDIR)/libcount_la-Judy1ByCount.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1ByCount.c' object='libcount_la-Judy1ByCount.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcount_la_CFLAGS) $(CFLAGS) -c -o libcount_la-Judy1ByCount.lo `test -f 'Judy1ByCount.c' || echo '$(srcdir)/'`Judy1ByCount.c
libinline_la-j__udy1Test.lo: j__udy1Test.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinline_la_CFLAGS) $(CFLAGS) -MT libinline_la-j__udy1Test.lo -MD -MP -MF "$(DEPDIR)/libinline_la-j__udy1Test.Tpo" -c -o libinline_la-j__udy1Test.lo `test -f 'j__udy1Test.c' || echo '$(srcdir)/'`j__udy1Test.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libinline_la-j__udy1Test.Tpo" "$(DEPDIR)/libinline_la-j__udy1Test.Plo"; else rm -f "$(DEPDIR)/libinline_la-j__udy1Test.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='j__udy1Test.c' object='libinline_la-j__udy1Test.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libinline_la_CFLAGS) $(CFLAGS) -c -o libinline_la-j__udy1Test.lo `test -f 'j__udy1Test.c' || echo '$(srcdir)/'`j__udy1Test.c
libnext_la-Judy1Next.lo: Judy1Next.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -MT libnext_la-Judy1Next.lo -MD -MP -MF "$(DEPDIR)/libnext_la-Judy1Next.Tpo" -c -o libnext_la-Judy1Next.lo `test -f 'Judy1Next.c' || echo '$(srcdir)/'`Judy1Next.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libnext_la-Judy1Next.Tpo" "$(DEPDIR)/libnext_la-Judy1Next.Plo"; else rm -f "$(DEPDIR)/libnext_la-Judy1Next.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1Next.c' object='libnext_la-Judy1Next.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -c -o libnext_la-Judy1Next.lo `test -f 'Judy1Next.c' || echo '$(srcdir)/'`Judy1Next.c
libnext_la-Judy1NextEmpty.lo: Judy1NextEmpty.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -MT libnext_la-Judy1NextEmpty.lo -MD -MP -MF "$(DEPDIR)/libnext_la-Judy1NextEmpty.Tpo" -c -o libnext_la-Judy1NextEmpty.lo `test -f 'Judy1NextEmpty.c' || echo '$(srcdir)/'`Judy1NextEmpty.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libnext_la-Judy1NextEmpty.Tpo" "$(DEPDIR)/libnext_la-Judy1NextEmpty.Plo"; else rm -f "$(DEPDIR)/libnext_la-Judy1NextEmpty.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1NextEmpty.c' object='libnext_la-Judy1NextEmpty.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libnext_la_CFLAGS) $(CFLAGS) -c -o libnext_la-Judy1NextEmpty.lo `test -f 'Judy1NextEmpty.c' || echo '$(srcdir)/'`Judy1NextEmpty.c
libprev_la-Judy1Prev.lo: Judy1Prev.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -MT libprev_la-Judy1Prev.lo -MD -MP -MF "$(DEPDIR)/libprev_la-Judy1Prev.Tpo" -c -o libprev_la-Judy1Prev.lo `test -f 'Judy1Prev.c' || echo '$(srcdir)/'`Judy1Prev.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libprev_la-Judy1Prev.Tpo" "$(DEPDIR)/libprev_la-Judy1Prev.Plo"; else rm -f "$(DEPDIR)/libprev_la-Judy1Prev.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1Prev.c' object='libprev_la-Judy1Prev.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -c -o libprev_la-Judy1Prev.lo `test -f 'Judy1Prev.c' || echo '$(srcdir)/'`Judy1Prev.c
libprev_la-Judy1PrevEmpty.lo: Judy1PrevEmpty.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -MT libprev_la-Judy1PrevEmpty.lo -MD -MP -MF "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Tpo" -c -o libprev_la-Judy1PrevEmpty.lo `test -f 'Judy1PrevEmpty.c' || echo '$(srcdir)/'`Judy1PrevEmpty.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Tpo" "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Plo"; else rm -f "$(DEPDIR)/libprev_la-Judy1PrevEmpty.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='Judy1PrevEmpty.c' object='libprev_la-Judy1PrevEmpty.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libprev_la_CFLAGS) $(CFLAGS) -c -o libprev_la-Judy1PrevEmpty.lo `test -f 'Judy1PrevEmpty.c' || echo '$(srcdir)/'`Judy1PrevEmpty.c
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES)
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
pdf pdf-am ps ps-am tags uninstall uninstall-am \
uninstall-info-am
Judy1Tables.c: Judy1TablesGen.c
$(CC) $(INCLUDES) $(AM_CFLAGS) @CFLAGS@ -o Judy1TablesGen Judy1TablesGen.c; ./Judy1TablesGen
Judy1Test.c: copies
copies:
cp -f ../JudyCommon/JudyByCount.c Judy1ByCount.c
cp -f ../JudyCommon/JudyCascade.c Judy1Cascade.c
cp -f ../JudyCommon/JudyCount.c Judy1Count.c
cp -f ../JudyCommon/JudyCreateBranch.c Judy1CreateBranch.c
cp -f ../JudyCommon/JudyDecascade.c Judy1Decascade.c
cp -f ../JudyCommon/JudyDel.c Judy1Unset.c
cp -f ../JudyCommon/JudyFirst.c Judy1First.c
cp -f ../JudyCommon/JudyFreeArray.c Judy1FreeArray.c
cp -f ../JudyCommon/JudyGet.c Judy1Test.c
cp -f ../JudyCommon/JudyGet.c j__udy1Test.c
cp -f ../JudyCommon/JudyInsArray.c Judy1SetArray.c
cp -f ../JudyCommon/JudyIns.c Judy1Set.c
cp -f ../JudyCommon/JudyInsertBranch.c Judy1InsertBranch.c
cp -f ../JudyCommon/JudyMallocIF.c Judy1MallocIF.c
cp -f ../JudyCommon/JudyMemActive.c Judy1MemActive.c
cp -f ../JudyCommon/JudyMemUsed.c Judy1MemUsed.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Next.c
cp -f ../JudyCommon/JudyPrevNext.c Judy1Prev.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1NextEmpty.c
cp -f ../JudyCommon/JudyPrevNextEmpty.c Judy1PrevEmpty.c
cp -f ../JudyCommon/JudyTables.c Judy1TablesGen.c
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@ -1,11 +0,0 @@
# @(#) $Revision$ $Source$
# This tree contains sources for the Judy1*() functions.
#
# Note: At one time, all of the Judy sources were split between Judy1/ and
# JudyL/ variants, but now most of them are merged in JudyCommon/ and this
# directory is vestigal.
Judy1.h header for following functions
lint.waivers see usage in makefile

File diff suppressed because it is too large Load Diff

View File

@ -1,954 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy*ByCount() function for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DNOSMARTJBB, -DNOSMARTJBU, and/or -DNOSMARTJLB to build a
// version with cache line optimizations deleted, for testing.
//
// Judy*ByCount() is a conceptual although not literal inverse of Judy*Count().
// Judy*Count() takes a pair of Indexes, and allows finding the ordinal of a
// given Index (that is, its position in the list of valid indexes from the
// beginning) as a degenerate case, because in general the count between two
// Indexes, inclusive, is not always just the difference in their ordinals.
// However, it suffices for Judy*ByCount() to simply be an ordinal-to-Index
// mapper.
//
// Note: Like Judy*Count(), this code must "count sideways" in branches, which
// can result in a lot of cache line fills. However, unlike Judy*Count(), this
// code does not receive a specific Index, hence digit, where to start in each
// branch, so it cant accurately calculate cache line fills required in each
// direction. The best it can do is an approximation based on the total
// population of the expanse (pop1 from Pjp) and the ordinal of the target
// Index (see SETOFFSET()) within the expanse.
//
// Compile with -DSMARTMETRICS to obtain global variables containing smart
// cache line metrics. Note: Dont turn this on simultaneously for this file
// and JudyCount.c because they export the same globals.
// ****************************************************************************
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// These are imported from JudyCount.c:
//
// TBD: Should this be in common code? Exported from a header file?
#ifdef JUDY1
extern Word_t j__udy1JPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udy1JPPop1
#else
extern Word_t j__udyLJPPop1(const Pjp_t Pjp);
#define j__udyJPPop1 j__udyLJPPop1
#endif
// Avoid duplicate symbols since this file is multi-compiled:
#ifdef SMARTMETRICS
#ifdef JUDY1
Word_t jbb_upward = 0; // counts of directions taken:
Word_t jbb_downward = 0;
Word_t jbu_upward = 0;
Word_t jbu_downward = 0;
Word_t jlb_upward = 0;
Word_t jlb_downward = 0;
#else
extern Word_t jbb_upward;
extern Word_t jbb_downward;
extern Word_t jbu_upward;
extern Word_t jbu_downward;
extern Word_t jlb_upward;
extern Word_t jlb_downward;
#endif
#endif
// ****************************************************************************
// J U D Y 1 B Y C O U N T
// J U D Y L B Y C O U N T
//
// See the manual entry.
#ifdef JUDY1
FUNCTION int Judy1ByCount
#else
FUNCTION PPvoid_t JudyLByCount
#endif
(
Pcvoid_t PArray, // root pointer to first branch/leaf in SM.
Word_t Count, // ordinal of Index to find, 1..MAX.
Word_t * PIndex, // to return found Index.
PJError_t PJError // optional, for returning error info.
)
{
Word_t Count0; // Count, base-0, to match pop0.
Word_t state; // current state in SM.
Word_t pop1; // of current branch or leaf, or of expanse.
Word_t pop1lower; // pop1 of expanses (JPs) below that for Count.
Word_t digit; // current word in branch.
Word_t jpcount; // JPs in a BranchB subexpanse.
long jpnum; // JP number in a branch (base 0).
long subexp; // for stepping through layer 1 (subexpanses).
int offset; // index ordinal within a leaf, base 0.
Pjp_t Pjp; // current JP in branch.
Pjll_t Pjll; // current Judy linear leaf.
// CHECK FOR EMPTY ARRAY OR NULL PINDEX:
if (PArray == (Pvoid_t) NULL) JU_RET_NOTFOUND;
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Convert Count to Count0; assume special case of Count = 0 maps to ~0, as
// desired, to represent the last index in a full array:
//
// Note: Think of Count0 as a reliable "number of Indexes below the target."
Count0 = Count - 1;
assert((Count || Count0 == ~0)); // ensure CPU is sane about 0 - 1.
pop1lower = 0;
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
if (Count0 > Pjlw[0]) JU_RET_NOTFOUND; // too high.
*PIndex = Pjlw[Count]; // Index, base 1.
JU_RET_FOUND_LEAFW(Pjlw, Pjlw[0] + 1, Count0);
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
if (Count0 > (Pjpm->jpm_Pop0)) JU_RET_NOTFOUND; // too high.
Pjp = &(Pjpm->jpm_JP);
pop1 = (Pjpm->jpm_Pop0) + 1;
// goto SMByCount;
}
// COMMON CODE:
//
// Prepare to handle a root-level or lower-level branch: Save the current
// state, obtain the total population for the branch in a state-dependent way,
// and then branch to common code for multiple cases.
//
// For root-level branches, the state is always cJU_ROOTSTATE, and the array
// population must already be set in pop1; it is not available in jp_DcdPopO.
//
// Note: The total population is only needed in cases where the common code
// "counts down" instead of up to minimize cache line fills. However, its
// available cheaply, and its better to do it with a constant shift (constant
// state value) instead of a variable shift later "when needed".
#define PREPB_ROOT(Next) \
state = cJU_ROOTSTATE; \
goto Next
// Use PREPB_DCD() to first copy the Dcd bytes to *PIndex if there are any
// (only if state < cJU_ROOTSTATE - 1):
#define PREPB_DCD(Pjp,cState,Next) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPB((Pjp), cState, Next)
#define PREPB(Pjp,cState,Next) \
state = (cState); \
pop1 = JU_JPBRANCH_POP0(Pjp, (cState)) + 1; \
goto Next
// Calculate whether the ordinal of an Index within a given expanse falls in
// the lower or upper half of the expanses population, taking care with
// unsigned math and boundary conditions:
//
// Note: Assume the ordinal falls within the expanses population, that is,
// 0 < (Count - Pop1lower) <= Pop1exp (assuming infinite math).
//
// Note: If the ordinal is the middle element, it doesnt matter whether
// LOWERHALF() is TRUE or FALSE.
#define LOWERHALF(Count0,Pop1lower,Pop1exp) \
(((Count0) - (Pop1lower)) < ((Pop1exp) / 2))
// Calculate the (signed) offset within a leaf to the desired ordinal (Count -
// Pop1lower; offset is one less), and optionally ensure its in range:
#define SETOFFSET(Offset,Count0,Pop1lower,Pjp) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) <= JU_JPLEAF_POP0(Pjp))
// Variations for immediate indexes, with and without pop1-specific assertions:
#define SETOFFSET_IMM_CK(Offset,Count0,Pop1lower,cPop1) \
(Offset) = (Count0) - (Pop1lower); \
assert((Offset) >= 0); \
assert((Offset) < (cPop1))
#define SETOFFSET_IMM(Offset,Count0,Pop1lower) \
(Offset) = (Count0) - (Pop1lower)
// STATE MACHINE -- TRAVERSE TREE:
//
// In branches, look for the expanse (digit), if any, where the total pop1
// below or at that expanse would meet or exceed Count, meaning the Index must
// be in this expanse.
SMByCount: // return here for next branch/leaf.
switch (JU_JPTYPE(Pjp))
{
// ----------------------------------------------------------------------------
// LINEAR BRANCH; count populations in JPs in the JBL upwards until finding the
// expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBL; watch out for pop1 == 0.
//
// Note: A JBL should always fit in one cache line => no need to count up
// versus down to save cache line fills.
//
// TBD: The previous is no longer true. Consider enhancing this code to count
// up/down, but it can wait for a later tuning phase. In the meantime, PREPB()
// sets pop1 for the whole array, but that value is not used here. 001215:
// Maybe its true again?
case cJU_JPBRANCH_L2: PREPB_DCD(Pjp, 2, BranchL);
#ifndef JU_64BIT
case cJU_JPBRANCH_L3: PREPB( Pjp, 3, BranchL);
#else
case cJU_JPBRANCH_L3: PREPB_DCD(Pjp, 3, BranchL);
case cJU_JPBRANCH_L4: PREPB_DCD(Pjp, 4, BranchL);
case cJU_JPBRANCH_L5: PREPB_DCD(Pjp, 5, BranchL);
case cJU_JPBRANCH_L6: PREPB_DCD(Pjp, 6, BranchL);
case cJU_JPBRANCH_L7: PREPB( Pjp, 7, BranchL);
#endif
case cJU_JPBRANCH_L: PREPB_ROOT( BranchL);
{
Pjbl_t Pjbl;
// Common code (state-independent) for all cases of linear branches:
BranchL:
Pjbl = P_JBL(Pjp->jp_Addr);
for (jpnum = 0; jpnum < (Pjbl->jbl_NumJPs); ++jpnum)
{
if ((pop1 = j__udyJPPop1((Pjbl->jbl_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, so do not subtract 1 and compare
// >=, but instead use the following expression:
if (pop1lower + pop1 > Count0) // Index is in this expanse.
{
JU_SETDIGIT(*PIndex, Pjbl->jbl_Expanse[jpnum], state);
Pjp = (Pjbl->jbl_jp) + jpnum;
goto SMByCount; // look under this expanse.
}
pop1lower += pop1; // add this JPs pop1.
}
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_L
// ----------------------------------------------------------------------------
// BITMAP BRANCH; count populations in JPs in the JBB upwards or downwards
// until finding the expanse (digit) containing Count, and "recurse".
//
// Note: There are no null JPs in a JBB; watch out for pop1 == 0.
case cJU_JPBRANCH_B2: PREPB_DCD(Pjp, 2, BranchB);
#ifndef JU_64BIT
case cJU_JPBRANCH_B3: PREPB( Pjp, 3, BranchB);
#else
case cJU_JPBRANCH_B3: PREPB_DCD(Pjp, 3, BranchB);
case cJU_JPBRANCH_B4: PREPB_DCD(Pjp, 4, BranchB);
case cJU_JPBRANCH_B5: PREPB_DCD(Pjp, 5, BranchB);
case cJU_JPBRANCH_B6: PREPB_DCD(Pjp, 6, BranchB);
case cJU_JPBRANCH_B7: PREPB( Pjp, 7, BranchB);
#endif
case cJU_JPBRANCH_B: PREPB_ROOT( BranchB);
{
Pjbb_t Pjbb;
// Common code (state-independent) for all cases of bitmap branches:
BranchB:
Pjbb = P_JBB(Pjp->jp_Addr);
// Shorthand for one subexpanse in a bitmap and for one JP in a bitmap branch:
//
// Note: BMPJP0 exists separately to support assertions.
#define BMPJP0(Subexp) (P_JP(JU_JBB_PJP(Pjbb, Subexp)))
#define BMPJP(Subexp,JPnum) (BMPJP0(Subexp) + (JPnum))
// Common code for descending through a JP:
//
// Determine the digit for the expanse and save it in *PIndex; then "recurse".
#define JBB_FOUNDEXPANSE \
{ \
JU_BITMAPDIGITB(digit, subexp, JU_JBB_BITMAP(Pjbb,subexp), jpnum); \
JU_SETDIGIT(*PIndex, digit, state); \
Pjp = BMPJP(subexp, jpnum); \
goto SMByCount; \
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, adding each "below" JPs pop1:
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = 0; jpnum < jpcount; ++jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBB_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
}
#ifndef NOSMARTJBB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" JPs pop1 from the whole expanses
// pop1:
else
{
#ifdef SMARTMETRICS
++jbb_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (subexp = cJU_NUMSUBEXPB - 1; subexp >= 0; --subexp)
{
if ((jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp)))
&& (BMPJP0(subexp) == (Pjp_t) NULL))
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // null ptr.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
// Note: An empty subexpanse (jpcount == 0) is handled "for free":
for (jpnum = jpcount - 1; jpnum >= 0; --jpnum)
{
if ((pop1 = j__udyJPPop1(BMPJP(subexp, jpnum)))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBB_FOUNDEXPANSE; // Index is in this expanse.
}
}
}
#endif // NOSMARTJBB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_B
// ----------------------------------------------------------------------------
// UNCOMPRESSED BRANCH; count populations in JPs in the JBU upwards or
// downwards until finding the expanse (digit) containing Count, and "recurse".
case cJU_JPBRANCH_U2: PREPB_DCD(Pjp, 2, BranchU);
#ifndef JU_64BIT
case cJU_JPBRANCH_U3: PREPB( Pjp, 3, BranchU);
#else
case cJU_JPBRANCH_U3: PREPB_DCD(Pjp, 3, BranchU);
case cJU_JPBRANCH_U4: PREPB_DCD(Pjp, 4, BranchU);
case cJU_JPBRANCH_U5: PREPB_DCD(Pjp, 5, BranchU);
case cJU_JPBRANCH_U6: PREPB_DCD(Pjp, 6, BranchU);
case cJU_JPBRANCH_U7: PREPB( Pjp, 7, BranchU);
#endif
case cJU_JPBRANCH_U: PREPB_ROOT( BranchU);
{
Pjbu_t Pjbu;
// Common code (state-independent) for all cases of uncompressed branches:
BranchU:
Pjbu = P_JBU(Pjp->jp_Addr);
// Common code for descending through a JP:
//
// Save the digit for the expanse in *PIndex, then "recurse".
#define JBU_FOUNDEXPANSE \
{ \
JU_SETDIGIT(*PIndex, jpnum, state); \
Pjp = (Pjbu->jbu_jp) + jpnum; \
goto SMByCount; \
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
// FIGURE OUT WHICH DIRECTION CAUSES FEWER CACHE LINE FILLS; adding the pop1s
// in JPs upwards, or subtracting the pop1s in JPs downwards:
//
// See header comments about limitations of this for Judy*ByCount().
#endif
// COUNT UPWARD, simply adding the pop1 of each JP:
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jbu_upward;
#endif
for (jpnum = 0; jpnum < cJU_BRANCHUNUMJPS; ++jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1((Pjbu->jbu_jp) + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
JBU_FOUNDEXPANSE; // Index is in this expanse.
pop1lower += pop1; // add this JPs pop1.
}
#ifndef NOSMARTJBU // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting the pop1 of each JP above from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jbu_downward;
#endif
pop1lower += pop1; // add whole branch to start.
for (jpnum = cJU_BRANCHUNUMJPS - 1; jpnum >= 0; --jpnum)
{
// shortcut, save a function call:
if ((Pjbu->jbu_jp[jpnum].jp_Type) <= cJU_JPNULLMAX)
continue;
if ((pop1 = j__udyJPPop1(Pjbu->jbu_jp + jpnum))
== cJU_ALLONES)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
assert(pop1 != 0);
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
pop1lower -= pop1;
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
JBU_FOUNDEXPANSE; // Index is in this expanse.
}
}
#endif // NOSMARTJBU
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // case cJU_JPBRANCH_U
// ----------------------------------------------------------------------------
// LINEAR LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf. First
// copy Dcd bytes, if there are any (only if state < cJU_ROOTSTATE - 1), to
// *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (linear leaf) as a side-effect, but dont depend on that (for JUDYL, which
// is the only cases that need it anyway).
#define PREPL_DCD(cState) \
JU_SETDCD(*PIndex, Pjp, cState); \
PREPL
#ifdef JUDY1
#define PREPL_SETPOP1 // not needed in any cases.
#else
#define PREPL_SETPOP1 pop1 = JU_JPLEAF_POP0(Pjp) + 1
#endif
#define PREPL \
Pjll = P_JLL(Pjp->jp_Addr); \
PREPL_SETPOP1; \
SETOFFSET(offset, Count0, pop1lower, Pjp)
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
PREPL_DCD(1);
JU_SETDIGIT1(*PIndex, ((uint8_t *) Pjll)[offset]);
JU_RET_FOUND_LEAF1(Pjll, pop1, offset);
#endif
case cJU_JPLEAF2:
PREPL_DCD(2);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) Pjll)[offset];
JU_RET_FOUND_LEAF2(Pjll, pop1, offset);
#ifndef JU_64BIT
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL;
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
#else
case cJU_JPLEAF3:
{
Word_t lsb;
PREPL_DCD(3);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_LEAF3(Pjll, pop1, offset);
}
case cJU_JPLEAF4:
PREPL_DCD(4);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) Pjll)[offset];
JU_RET_FOUND_LEAF4(Pjll, pop1, offset);
case cJU_JPLEAF5:
{
Word_t lsb;
PREPL_DCD(5);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_LEAF5(Pjll, pop1, offset);
}
case cJU_JPLEAF6:
{
Word_t lsb;
PREPL_DCD(6);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_LEAF6(Pjll, pop1, offset);
}
case cJU_JPLEAF7:
{
Word_t lsb;
PREPL;
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) Pjll) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_LEAF7(Pjll, pop1, offset);
}
#endif
// ----------------------------------------------------------------------------
// BITMAP LEAF:
//
// Return the Index at the proper ordinal (see SETOFFSET()) in the leaf by
// counting bits. First copy Dcd bytes (always present since state 1 <
// cJU_ROOTSTATE) to *PIndex.
//
// Note: The preceding branch traversal code MIGHT set pop1 for this expanse
// (bitmap leaf) as a side-effect, but dont depend on that.
case cJU_JPLEAF_B1:
{
Pjlb_t Pjlb;
JU_SETDCD(*PIndex, Pjp, 1);
Pjlb = P_JLB(Pjp->jp_Addr);
pop1 = JU_JPLEAF_POP0(Pjp) + 1;
// COUNT UPWARD, adding the pop1 of each subexpanse:
//
// The entire bitmap should fit in one cache line, but still try to save some
// CPU time by counting the fewest possible number of subexpanses from the
// bitmap.
//
// See header comments about limitations of this for Judy*ByCount().
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
if (LOWERHALF(Count0, pop1lower, pop1))
{
#endif
#ifdef SMARTMETRICS
++jlb_upward;
#endif
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
pop1 = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Warning: pop1lower and pop1 are unsigned, see earlier comment:
if (pop1lower + pop1 > Count0)
goto LeafB1; // Index is in this subexpanse.
pop1lower += pop1; // add this subexpanses pop1.
}
#ifndef NOSMARTJLB // enable to turn off smart code for comparison purposes.
}
// COUNT DOWNWARD, subtracting each "above" subexpanses pop1 from the whole
// expanses pop1:
else
{
#ifdef SMARTMETRICS
++jlb_downward;
#endif
pop1lower += pop1; // add whole leaf to start.
for (subexp = cJU_NUMSUBEXPL - 1; subexp >= 0; --subexp)
{
pop1lower -= j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
// Beware unsigned math problems:
if ((pop1lower == 0) || (pop1lower - 1 < Count0))
goto LeafB1; // Index is in this subexpanse.
}
}
#endif // NOSMARTJLB
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT); // should never get here.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
// RETURN INDEX FOUND:
//
// Come here with subexp set to the correct subexpanse, and pop1lower set to
// the sum for all lower expanses and subexpanses in the Judy tree. Calculate
// and save in *PIndex the digit corresponding to the ordinal in this
// subexpanse.
LeafB1:
SETOFFSET(offset, Count0, pop1lower, Pjp);
JU_BITMAPDIGITL(digit, subexp, JU_JLB_BITMAP(Pjlb, subexp), offset);
JU_SETDIGIT1(*PIndex, digit);
JU_RET_FOUND_LEAF_B1(Pjlb, subexp, offset);
// == return((PPvoid_t) (P_JV(JL_JLB_PVALUE(Pjlb, subexp)) + offset))
} // case cJU_JPLEAF_B1
#ifdef JUDY1
// ----------------------------------------------------------------------------
// FULL POPULATION:
//
// Copy Dcd bytes (always present since state 1 < cJU_ROOTSTATE) to *PIndex,
// then set the appropriate digit for the ordinal (see SETOFFSET()) in the leaf
// as the LSB in *PIndex.
case cJ1_JPFULLPOPU1:
JU_SETDCD(*PIndex, Pjp, 1);
SETOFFSET(offset, Count0, pop1lower, Pjp);
assert(offset >= 0);
assert(offset <= cJU_JPFULLPOPU1_POP0);
JU_SETDIGIT1(*PIndex, offset);
JU_RET_FOUND_FULLPOPU1;
#endif
// ----------------------------------------------------------------------------
// IMMEDIATE:
//
// Locate the Index with the proper ordinal (see SETOFFSET()) in the Immediate,
// depending on leaf Index Size and pop1. Note: There are no Dcd bytes in an
// Immediate JP, but in a cJU_JPIMMED_*_01 JP, the field holds the least bytes
// of the immediate Index.
#define SET_01(cState) JU_SETDIGITS(*PIndex, JU_JPDCDPOP0(Pjp), cState)
case cJU_JPIMMED_1_01: SET_01(1); goto Imm_01;
case cJU_JPIMMED_2_01: SET_01(2); goto Imm_01;
case cJU_JPIMMED_3_01: SET_01(3); goto Imm_01;
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: SET_01(4); goto Imm_01;
case cJU_JPIMMED_5_01: SET_01(5); goto Imm_01;
case cJU_JPIMMED_6_01: SET_01(6); goto Imm_01;
case cJU_JPIMMED_7_01: SET_01(7); goto Imm_01;
#endif
Imm_01:
DBGCODE(SETOFFSET_IMM_CK(offset, Count0, pop1lower, 1);)
JU_RET_FOUND_IMM_01(Pjp);
// Shorthand for where to find start of Index bytes array:
#ifdef JUDY1
#define PJI (Pjp->jp_1Index)
#else
#define PJI (Pjp->jp_LIndex)
#endif
// Optional code to check the remaining ordinal (see SETOFFSET_IMM()) against
// the Index Size of the Immediate:
#ifndef DEBUG // simple placeholder:
#define IMM(cPop1,Next) \
goto Next
#else // extra pop1-specific checking:
#define IMM(cPop1,Next) \
SETOFFSET_IMM_CK(offset, Count0, pop1lower, cPop1); \
goto Next
#endif
case cJU_JPIMMED_1_02: IMM( 2, Imm1);
case cJU_JPIMMED_1_03: IMM( 3, Imm1);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: IMM( 4, Imm1);
case cJU_JPIMMED_1_05: IMM( 5, Imm1);
case cJU_JPIMMED_1_06: IMM( 6, Imm1);
case cJU_JPIMMED_1_07: IMM( 7, Imm1);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: IMM( 8, Imm1);
case cJ1_JPIMMED_1_09: IMM( 9, Imm1);
case cJ1_JPIMMED_1_10: IMM(10, Imm1);
case cJ1_JPIMMED_1_11: IMM(11, Imm1);
case cJ1_JPIMMED_1_12: IMM(12, Imm1);
case cJ1_JPIMMED_1_13: IMM(13, Imm1);
case cJ1_JPIMMED_1_14: IMM(14, Imm1);
case cJ1_JPIMMED_1_15: IMM(15, Imm1);
#endif
Imm1: SETOFFSET_IMM(offset, Count0, pop1lower);
JU_SETDIGIT1(*PIndex, ((uint8_t *) PJI)[offset]);
JU_RET_FOUND_IMM(Pjp, offset);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: IMM(2, Imm2);
case cJU_JPIMMED_2_03: IMM(3, Imm2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: IMM(4, Imm2);
case cJ1_JPIMMED_2_05: IMM(5, Imm2);
case cJ1_JPIMMED_2_06: IMM(6, Imm2);
case cJ1_JPIMMED_2_07: IMM(7, Imm2);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm2: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(2)))
| ((uint16_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: IMM(2, Imm3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: IMM(3, Imm3);
case cJ1_JPIMMED_3_04: IMM(4, Imm3);
case cJ1_JPIMMED_3_05: IMM(5, Imm3);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
Imm3:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY3_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (3 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(3))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_4_02: IMM(2, Imm4);
case cJ1_JPIMMED_4_03: IMM(3, Imm4);
Imm4: SETOFFSET_IMM(offset, Count0, pop1lower);
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(4)))
| ((uint32_t *) PJI)[offset];
JU_RET_FOUND_IMM(Pjp, offset);
case cJ1_JPIMMED_5_02: IMM(2, Imm5);
case cJ1_JPIMMED_5_03: IMM(3, Imm5);
Imm5:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY5_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (5 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(5))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_6_02: IMM(2, Imm6);
Imm6:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY6_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (6 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(6))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
case cJ1_JPIMMED_7_02: IMM(2, Imm7);
Imm7:
{
Word_t lsb;
SETOFFSET_IMM(offset, Count0, pop1lower);
JU_COPY7_PINDEX_TO_LONG(lsb, ((uint8_t *) PJI) + (7 * offset));
*PIndex = (*PIndex & (~JU_LEASTBYTESMASK(7))) | lsb;
JU_RET_FOUND_IMM(Pjp, offset);
}
#endif // (JUDY1 && JU_64BIT)
// ----------------------------------------------------------------------------
// UNEXPECTED JP TYPES:
default: JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
} // SMByCount switch.
/*NOTREACHED*/
} // Judy1ByCount() / JudyLByCount()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,314 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// Branch creation functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// ****************************************************************************
// J U D Y C R E A T E B R A N C H L
//
// Build a BranchL from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchL. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchL it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchL(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbl_t PjblRaw; // pointer to linear branch.
Pjbl_t Pjbl;
assert(ExpCnt <= cJU_BRANCHLMAXJPS);
PjblRaw = j__udyAllocJBL(Pjpm);
if (PjblRaw == (Pjbl_t) NULL) return(-1);
Pjbl = P_JBL(PjblRaw);
// Build a Linear Branch
Pjbl->jbl_NumJPs = ExpCnt;
// Copy from the Linear branch from splayed leaves
JU_COPYMEM(Pjbl->jbl_Expanse, Exp, ExpCnt);
JU_COPYMEM(Pjbl->jbl_jp, PJPs, ExpCnt);
// Pass back new pointer to the Linear branch in JP
Pjp->jp_Addr = (Word_t) PjblRaw;
return(1);
} // j__udyCreateBranchL()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H B
//
// Build a BranchB from an array of JPs and associated 1 byte digits
// (expanses). Return with Pjp pointing to the BranchB. Caller must
// deallocate passed arrays, if necessary.
//
// We have no idea what kind of BranchB it is, so caller must set the jp_Type.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchB(
Pjp_t Pjp, // Build JPs from this place
Pjp_t PJPs, // Array of JPs to put into Bitmap branch
uint8_t Exp[], // Array of expanses to put into bitmap
Word_t ExpCnt, // Number of above JPs and Expanses
Pvoid_t Pjpm)
{
Pjbb_t PjbbRaw; // pointer to bitmap branch.
Pjbb_t Pjbb;
Word_t ii, jj; // Temps
uint8_t CurrSubExp; // Current sub expanse for BM
// This assertion says the number of populated subexpanses is not too large.
// This function is only called when a BranchL overflows to a BranchB or when a
// cascade occurs, meaning a leaf overflows. Either way ExpCnt cant be very
// large, in fact a lot smaller than cJU_BRANCHBMAXJPS. (Otherwise a BranchU
// would be used.) Popping this assertion means something (unspecified) has
// gone very wrong, or else Judys design criteria have changed, although in
// fact there should be no HARM in creating a BranchB with higher actual
// fanout.
assert(ExpCnt <= cJU_BRANCHBMAXJPS);
// Get memory for a Bitmap branch
PjbbRaw = j__udyAllocJBB(Pjpm);
if (PjbbRaw == (Pjbb_t) NULL) return(-1);
Pjbb = P_JBB(PjbbRaw);
// Get 1st "sub" expanse (0..7) of bitmap branch
CurrSubExp = Exp[0] / cJU_BITSPERSUBEXPB;
// Index thru all 1 byte sized expanses:
for (jj = ii = 0; ii <= ExpCnt; ii++)
{
Word_t SubExp; // Cannot be a uint8_t
// Make sure we cover the last one
if (ii == ExpCnt)
{
SubExp = cJU_ALLONES; // Force last one
}
else
{
// Calculate the "sub" expanse of the byte expanse
SubExp = Exp[ii] / cJU_BITSPERSUBEXPB; // Bits 5..7.
// Set the bit that represents the expanse in Exp[]
JU_JBB_BITMAP(Pjbb, SubExp) |= JU_BITPOSMASKB(Exp[ii]);
}
// Check if a new "sub" expanse range needed
if (SubExp != CurrSubExp)
{
// Get number of JPs in this sub expanse
Word_t NumJP = ii - jj;
Pjp_t PjpRaw;
Pjp_t Pjp;
PjpRaw = j__udyAllocJBBJP(NumJP, Pjpm);
Pjp = P_JP(PjpRaw);
if (PjpRaw == (Pjp_t) NULL) // out of memory.
{
// Free any previous allocations:
while(CurrSubExp--)
{
NumJP = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb,
CurrSubExp));
if (NumJP)
{
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb,
CurrSubExp), NumJP, Pjpm);
}
}
j__udyFreeJBB(PjbbRaw, Pjpm);
return(-1);
}
// Place the array of JPs in bitmap branch:
JU_JBB_PJP(Pjbb, CurrSubExp) = PjpRaw;
// Copy the JPs to new leaf:
JU_COPYMEM(Pjp, PJPs + jj, NumJP);
// On to the next bitmap branch "sub" expanse:
jj = ii;
CurrSubExp = SubExp;
}
} // for each 1-byte expanse
// Pass back some of the JP to the new Bitmap branch:
Pjp->jp_Addr = (Word_t) PjbbRaw;
return(1);
} // j__udyCreateBranchB()
// ****************************************************************************
// J U D Y C R E A T E B R A N C H U
//
// Build a BranchU from a BranchB. Return with Pjp pointing to the BranchU.
// Free the BranchB and its JP subarrays.
//
// Return -1 if error (details in Pjpm), otherwise return 1.
FUNCTION int j__udyCreateBranchU(
Pjp_t Pjp,
Pvoid_t Pjpm)
{
jp_t JPNull;
Pjbu_t PjbuRaw;
Pjbu_t Pjbu;
Pjbb_t PjbbRaw;
Pjbb_t Pjbb;
Word_t ii, jj;
BITMAPB_t BitMap;
Pjp_t PDstJP;
#ifdef JU_STAGED_EXP
jbu_t BranchU; // Staged uncompressed branch
#else
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
#endif
JU_JPSETADT(&JPNull, 0, 0, JU_JPTYPE(Pjp) - cJU_JPBRANCH_B2 + cJU_JPNULL1);
// Get the pointer to the BranchB:
PjbbRaw = (Pjbb_t) (Pjp->jp_Addr);
Pjbb = P_JBB(PjbbRaw);
// Set the pointer to the Uncompressed branch
#ifdef JU_STAGED_EXP
PDstJP = BranchU.jbu_jp;
#else
PDstJP = Pjbu->jbu_jp;
#endif
for (ii = 0; ii < cJU_NUMSUBEXPB; ii++)
{
Pjp_t PjpA;
Pjp_t PjpB;
PjpB = PjpA = P_JP(JU_JBB_PJP(Pjbb, ii));
// Get the bitmap for this subexpanse
BitMap = JU_JBB_BITMAP(Pjbb, ii);
// NULL empty subexpanses
if (BitMap == 0)
{
// But, fill with NULLs
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
PDstJP[jj] = JPNull;
}
PDstJP += cJU_BITSPERSUBEXPB;
continue;
}
// Check if Uncompressed subexpanse
if (BitMap == cJU_FULLBITMAPB)
{
// Copy subexpanse to the Uncompressed branch intact
JU_COPYMEM(PDstJP, PjpA, cJU_BITSPERSUBEXPB);
// Bump to next subexpanse
PDstJP += cJU_BITSPERSUBEXPB;
// Set length of subexpanse
jj = cJU_BITSPERSUBEXPB;
}
else
{
for (jj = 0; jj < cJU_BITSPERSUBEXPB; jj++)
{
// Copy JP or NULLJP depending on bit
if (BitMap & 1) { *PDstJP = *PjpA++; }
else { *PDstJP = JPNull; }
PDstJP++; // advance to next JP
BitMap >>= 1;
}
jj = PjpA - PjpB;
}
// Free the subexpanse:
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, ii), jj, Pjpm);
} // for each JP in BranchU
#ifdef JU_STAGED_EXP
// Allocate memory for a BranchU:
PjbuRaw = j__udyAllocJBU(Pjpm);
if (PjbuRaw == (Pjbu_t) NULL) return(-1);
Pjbu = P_JBU(PjbuRaw);
// Copy staged branch to newly allocated branch:
//
// TBD: I think this code is broken.
*Pjbu = BranchU;
#endif // JU_STAGED_EXP
// Finally free the BranchB and put the BranchU in its place:
j__udyFreeJBB(PjbbRaw, Pjpm);
Pjp->jp_Addr = (Word_t) PjbuRaw;
Pjp->jp_Type += cJU_JPBRANCH_U - cJU_JPBRANCH_B;
return(1);
} // j__udyCreateBranchU()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,213 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy*First[Empty]() and Judy*Last[Empty]() routines for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
//
// These are inclusive versions of Judy*Next[Empty]() and Judy*Prev[Empty]().
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
// ****************************************************************************
// J U D Y 1 F I R S T
// J U D Y L F I R S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1First
#else
FUNCTION PPvoid_t JudyLFirst
#endif
(
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError // optional, for returning error info.
)
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Next(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLNext(PArray, PIndex, PJError));
}
#endif
} // Judy1First() / JudyLFirst()
// ****************************************************************************
// J U D Y 1 L A S T
// J U D Y L L A S T
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1Last(
#else
FUNCTION PPvoid_t JudyLLast(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
JUDY1CODE(return(JERRI );)
JUDYLCODE(return(PPJERR);)
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 1: return(1); // found *PIndex itself.
case 0: return(Judy1Prev(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(PPJERR);
if (PValue != (PPvoid_t) NULL) return(PValue); // found *PIndex.
return(JudyLPrev(PArray, PIndex, PJError));
}
#endif
} // Judy1Last() / JudyLLast()
// ****************************************************************************
// J U D Y 1 F I R S T E M P T Y
// J U D Y L F I R S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1FirstEmpty(
#else
FUNCTION int JudyLFirstEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL) // caller error:
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX);
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1NextEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLNextEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1FirstEmpty() / JudyLFirstEmpty()
// ****************************************************************************
// J U D Y 1 L A S T E M P T Y
// J U D Y L L A S T E M P T Y
//
// See the manual entry for details.
#ifdef JUDY1
FUNCTION int Judy1LastEmpty(
#else
FUNCTION int JudyLLastEmpty(
#endif
Pcvoid_t PArray, // Judy array to search.
Word_t * PIndex, // starting point and result.
PJError_t PJError) // optional, for returning error info.
{
if (PIndex == (PWord_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPINDEX); // caller error.
return(JERRI);
}
#ifdef JUDY1
switch (Judy1Test(PArray, *PIndex, PJError))
{
case 0: return(1); // found *PIndex itself.
case 1: return(Judy1PrevEmpty(PArray, PIndex, PJError));
default: return(JERRI);
}
#else
{
PPvoid_t PValue;
if ((PValue = JudyLGet(PArray, *PIndex, PJError)) == PPJERR)
return(JERRI);
if (PValue == (PPvoid_t) NULL) return(1); // found *PIndex.
return(JudyLPrevEmpty(PArray, PIndex, PJError));
}
#endif
} // Judy1LastEmpty() / JudyLLastEmpty()

View File

@ -1,363 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy1FreeArray() and JudyLFreeArray() functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
// Return the number of bytes freed from the array.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
DBGCODE(extern void JudyCheckPop(Pvoid_t PArray);)
// ****************************************************************************
// J U D Y 1 F R E E A R R A Y
// J U D Y L F R E E A R R A Y
//
// See the Judy*(3C) manual entry for details.
//
// This code is written recursively, at least at first, because thats much
// simpler. Hope its fast enough.
#ifdef JUDY1
FUNCTION Word_t Judy1FreeArray
#else
FUNCTION Word_t JudyLFreeArray
#endif
(
PPvoid_t PPArray, // array to free.
PJError_t PJError // optional, for returning error info.
)
{
jpm_t jpm; // local to accumulate free statistics.
// CHECK FOR NULL POINTER (error by caller):
if (PPArray == (PPvoid_t) NULL)
{
JU_SET_ERRNO(PJError, JU_ERRNO_NULLPPARRAY);
return(JERR);
}
DBGCODE(JudyCheckPop(*PPArray);)
// Zero jpm.jpm_Pop0 (meaning the array will be empty in a moment) for accurate
// logging in TRACEMI2.
jpm.jpm_Pop0 = 0; // see above.
jpm.jpm_TotalMemWords = 0; // initialize memory freed.
// Empty array:
if (P_JLW(*PPArray) == (Pjlw_t) NULL) return(0);
// PROCESS TOP LEVEL "JRP" BRANCHES AND LEAF:
if (JU_LEAFW_POP0(*PPArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(*PPArray); // first word of leaf.
j__udyFreeJLW(Pjlw, Pjlw[0] + 1, &jpm);
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (-(jpm.jpm_TotalMemWords * cJU_BYTESPERWORD)); // see above.
}
else
// Rootstate leaves: just free the leaf:
// Common code for returning the amount of memory freed.
//
// Note: In a an ordinary LEAFW, pop0 = *PPArray[0].
//
// Accumulate (negative) words freed, while freeing objects.
// Return the positive bytes freed.
{
Pjpm_t Pjpm = P_JPM(*PPArray);
Word_t TotalMem = Pjpm->jpm_TotalMemWords;
j__udyFreeSM(&(Pjpm->jpm_JP), &jpm); // recurse through tree.
j__udyFreeJPM(Pjpm, &jpm);
// Verify the array was not corrupt. This means that amount of memory freed
// (which is negative) is equal to the initial amount:
if (TotalMem + jpm.jpm_TotalMemWords)
{
JU_SET_ERRNO(PJError, JU_ERRNO_CORRUPT);
return(JERR);
}
*PPArray = (Pvoid_t) NULL; // make an empty array.
return (TotalMem * cJU_BYTESPERWORD);
}
} // Judy1FreeArray() / JudyLFreeArray()
// ****************************************************************************
// __ J U D Y F R E E S M
//
// Given a pointer to a JP, recursively visit and free (depth first) all nodes
// in a Judy array BELOW the JP, but not the JP itself. Accumulate in *Pjpm
// the total words freed (as a negative value). "SM" = State Machine.
//
// Note: Corruption is not detected at this level because during a FreeArray,
// if the code hasnt already core dumped, its better to remain silent, even
// if some memory has not been freed, than to bother the caller about the
// corruption. TBD: Is this true? If not, must list all legitimate JPNULL
// and JPIMMED above first, and revert to returning bool_t (see 4.34).
FUNCTION void j__udyFreeSM(
Pjp_t Pjp, // top of Judy (top-state).
Pjpm_t Pjpm) // to return words freed.
{
Word_t Pop1;
switch (JU_JPTYPE(Pjp))
{
#ifdef JUDY1
// FULL EXPANSE -- nothing to free for this jp_Type.
case cJ1_JPFULLPOPU1:
break;
#endif
// JUDY BRANCH -- free the sub-tree depth first:
// LINEAR BRANCH -- visit each JP in the JBLs list, then free the JBL:
//
// Note: There are no null JPs in a JBL.
case cJU_JPBRANCH_L:
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif // JU_64BIT
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
Word_t offset;
for (offset = 0; offset < Pjbl->jbl_NumJPs; ++offset)
j__udyFreeSM((Pjbl->jbl_jp) + offset, Pjpm);
j__udyFreeJBL((Pjbl_t) (Pjp->jp_Addr), Pjpm);
break;
}
// BITMAP BRANCH -- visit each JP in the JBBs list based on the bitmap, also
//
// Note: There are no null JPs in a JBB.
case cJU_JPBRANCH_B:
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif // JU_64BIT
{
Word_t subexp;
Word_t offset;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
if (jpcount)
{
for (offset = 0; offset < jpcount; ++offset)
{
j__udyFreeSM(P_JP(JU_JBB_PJP(Pjbb, subexp)) + offset,
Pjpm);
}
j__udyFreeJBBJP(JU_JBB_PJP(Pjbb, subexp), jpcount, Pjpm);
}
}
j__udyFreeJBB((Pjbb_t) (Pjp->jp_Addr), Pjpm);
break;
}
// UNCOMPRESSED BRANCH -- visit each JP in the JBU array, then free the JBU
// itself:
//
// Note: Null JPs are handled during recursion at a lower state.
case cJU_JPBRANCH_U:
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif // JU_64BIT
{
Word_t offset;
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
j__udyFreeSM((Pjbu->jbu_jp) + offset, Pjpm);
j__udyFreeJBU((Pjbu_t) (Pjp->jp_Addr), Pjpm);
break;
}
// -- Cases below here terminate and do not recurse. --
// LINEAR LEAF -- just free the leaf; size is computed from jp_Type:
//
// Note: cJU_JPLEAF1 is a special case, see discussion in ../Judy1/Judy1.h
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL1((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif
case cJU_JPLEAF2:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL2((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF3:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL3((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPLEAF4:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL4((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF5:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL5((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF6:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL6((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPLEAF7:
Pop1 = JU_JPLEAF_POP0(Pjp) + 1;
j__udyFreeJLL7((Pjll_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#endif // JU_64BIT
// BITMAP LEAF -- free sub-expanse arrays of JPs, then free the JBB.
case cJU_JPLEAF_B1:
{
#ifdef JUDYL
Word_t subexp;
Word_t jpcount;
Pjlb_t Pjlb = P_JLB(Pjp->jp_Addr);
// Free the value areas in the bitmap leaf:
for (subexp = 0; subexp < cJU_NUMSUBEXPL; ++subexp)
{
jpcount = j__udyCountBitsL(JU_JLB_BITMAP(Pjlb, subexp));
if (jpcount)
j__udyLFreeJV(JL_JLB_PVALUE(Pjlb, subexp), jpcount, Pjpm);
}
#endif // JUDYL
j__udyFreeJLB1((Pjlb_t) (Pjp->jp_Addr), Pjpm);
break;
} // case cJU_JPLEAF_B1
#ifdef JUDYL
// IMMED*:
//
// For JUDYL, all non JPIMMED_*_01s have a LeafV which must be freed:
case cJU_JPIMMED_1_02:
case cJU_JPIMMED_1_03:
#ifdef JU_64BIT
case cJU_JPIMMED_1_04:
case cJU_JPIMMED_1_05:
case cJU_JPIMMED_1_06:
case cJU_JPIMMED_1_07:
#endif
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_1_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
#ifdef JU_64BIT
case cJU_JPIMMED_2_02:
case cJU_JPIMMED_2_03:
Pop1 = JU_JPTYPE(Pjp) - cJU_JPIMMED_2_02 + 2;
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), Pop1, Pjpm);
break;
case cJU_JPIMMED_3_02:
j__udyLFreeJV((Pjv_t) (Pjp->jp_Addr), 2, Pjpm);
break;
#endif // JU_64BIT
#endif // JUDYL
// OTHER JPNULL, JPIMMED, OR UNEXPECTED TYPE -- nothing to free for this type:
//
// Note: Lump together no-op and invalid JP types; see function header
// comments.
default: break;
} // switch (JU_JPTYPE(Pjp))
} // j__udyFreeSM()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,135 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// BranchL insertion functions for Judy1 and JudyL.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
extern int j__udyCreateBranchL(Pjp_t, Pjp_t, uint8_t *, Word_t, Pvoid_t);
// ****************************************************************************
// __ J U D Y I N S E R T B R A N C H
//
// Insert 2-element BranchL in between Pjp and Pjp->jp_Addr.
//
// Return -1 if out of memory, otherwise return 1.
FUNCTION int j__udyInsertBranch(
Pjp_t Pjp, // JP containing narrow pointer.
Word_t Index, // outlier to Pjp.
Word_t BranchLevel, // of what JP points to, mapped from JP type.
Pjpm_t Pjpm) // for global accounting.
{
jp_t JP2 [2];
jp_t JP;
Pjp_t PjpNull;
Word_t XorExp;
Word_t Inew, Iold;
Word_t DCDMask; // initially for original BranchLevel.
int Ret;
uint8_t Exp2[2];
uint8_t DecodeByteN, DecodeByteO;
// Get the current mask for the DCD digits:
DCDMask = cJU_DCDMASK(BranchLevel);
// Obtain Dcd bits that differ between Index and JP, shifted so the
// digit for BranchLevel is the LSB:
XorExp = ((Index ^ JU_JPDCDPOP0(Pjp)) & (cJU_ALLONES >> cJU_BITSPERBYTE))
>> (BranchLevel * cJU_BITSPERBYTE);
assert(XorExp); // Index must be an outlier.
// Count levels between object under narrow pointer and the level at which
// the outlier diverges from it, which is always at least initial
// BranchLevel + 1, to end up with the level (JP type) at which to insert
// the new intervening BranchL:
do { ++BranchLevel; } while ((XorExp >>= cJU_BITSPERBYTE));
assert((BranchLevel > 1) && (BranchLevel < cJU_ROOTSTATE));
// Get the MSB (highest digit) that differs between the old expanse and
// the new Index to insert:
DecodeByteO = JU_DIGITATSTATE(JU_JPDCDPOP0(Pjp), BranchLevel);
DecodeByteN = JU_DIGITATSTATE(Index, BranchLevel);
assert(DecodeByteO != DecodeByteN);
// Determine sorted order for old expanse and new Index digits:
if (DecodeByteN > DecodeByteO) { Iold = 0; Inew = 1; }
else { Iold = 1; Inew = 0; }
// Copy old JP into staging area for new Branch
JP2 [Iold] = *Pjp;
Exp2[Iold] = DecodeByteO;
Exp2[Inew] = DecodeByteN;
// Create a 2 Expanse Linear branch
//
// Note: Pjp->jp_Addr is set by j__udyCreateBranchL()
Ret = j__udyCreateBranchL(Pjp, JP2, Exp2, 2, Pjpm);
if (Ret == -1) return(-1);
// Get Pjp to the NULL of where to do insert
PjpNull = ((P_JBL(Pjp->jp_Addr))->jbl_jp) + Inew;
// Convert to a cJU_JPIMMED_*_01 at the correct level:
// Build JP and set type below to: cJU_JPIMMED_X_01
JU_JPSETADT(PjpNull, 0, Index, cJU_JPIMMED_1_01 - 2 + BranchLevel);
// Return pointer to Value area in cJU_JPIMMED_X_01
JUDYLCODE(Pjpm->jpm_PValue = (Pjv_t) PjpNull;)
// The old JP now points to a BranchL that is at higher level. Therefore
// it contains excess DCD bits (in the least significant position) that
// must be removed (zeroed); that is, they become part of the Pop0
// subfield. Note that the remaining (lower) bytes in the Pop0 field do
// not change.
//
// Take from the old DCDMask, which went "down" to a lower BranchLevel,
// and zero any high bits that are still in the mask at the new, higher
// BranchLevel; then use this mask to zero the bits in jp_DcdPopO:
// Set old JP to a BranchL at correct level
Pjp->jp_Type = cJU_JPBRANCH_L2 - 2 + BranchLevel;
DCDMask ^= cJU_DCDMASK(BranchLevel);
DCDMask = ~DCDMask & JU_JPDCDPOP0(Pjp);
JP = *Pjp;
JU_JPSETADT(Pjp, JP.jp_Addr, DCDMask, JP.jp_Type);
return(1);
} // j__udyInsertBranch()

View File

@ -1,87 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
// ************************************************************************ //
// JUDY - Memory Allocater //
// -by- //
// Douglas L. Baskins //
// Hewlett Packard //
// Fort Collins, Co //
// (970) 229-2027 //
// //
// ************************************************************************ //
// JUDY INCLUDE FILES
#include "Judy.h"
// ****************************************************************************
// J U D Y M A L L O C
//
// Allocate RAM. This is the single location in Judy code that calls
// malloc(3C). Note: JPM accounting occurs at a higher level.
Word_t JudyMalloc(
Word_t Words)
{
Word_t Addr;
Addr = (Word_t) malloc(Words * sizeof(Word_t));
return(Addr);
} // JudyMalloc()
// ****************************************************************************
// J U D Y F R E E
void JudyFree(
void * PWord,
Word_t Words)
{
(void) Words;
free(PWord);
} // JudyFree()
// ****************************************************************************
// J U D Y M A L L O C
//
// Higher-level "wrapper" for allocating objects that need not be in RAM,
// although at this time they are in fact only in RAM. Later we hope that some
// entire subtrees (at a JPM or branch) can be "virtual", so their allocations
// and frees should go through this level.
Word_t JudyMallocVirtual(
Word_t Words)
{
return(JudyMalloc(Words));
} // JudyMallocVirtual()
// ****************************************************************************
// J U D Y F R E E
void JudyFreeVirtual(
void * PWord,
Word_t Words)
{
JudyFree(PWord, Words);
} // JudyFreeVirtual()

View File

@ -1,782 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Judy malloc/free interface functions for Judy1 and JudyL.
//
// Compile with one of -DJUDY1 or -DJUDYL.
//
// Compile with -DTRACEMI (Malloc Interface) to turn on tracing of malloc/free
// calls at the interface level. (See also TRACEMF in lower-level code.)
// Use -DTRACEMI2 for a terser format suitable for trace analysis.
//
// There can be malloc namespace bits in the LSBs of "raw" addresses from most,
// but not all, of the j__udy*Alloc*() functions; see also JudyPrivate.h. To
// test the Judy code, compile this file with -DMALLOCBITS and use debug flavor
// only (for assertions). This test ensures that (a) all callers properly mask
// the namespace bits out before dereferencing a pointer (or else a core dump
// occurs), and (b) all callers send "raw" (unmasked) addresses to
// j__udy*Free*() calls.
//
// Note: Currently -DDEBUG turns on MALLOCBITS automatically.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
// Set "hidden" global j__uMaxWords to the maximum number of words to allocate
// to any one array (large enough to have a JPM, otherwise j__uMaxWords is
// ignored), to trigger a fake malloc error when the number is exceeded. Note,
// this code is always executed, not #ifdefd, because its virtually free.
//
// Note: To keep the MALLOC macro faster and simpler, set j__uMaxWords to
// MAXINT, not zero, by default.
Word_t j__uMaxWords = ~0UL;
// This macro hides the faking of a malloc failure:
//
// Note: To keep this fast, just compare WordsPrev to j__uMaxWords without the
// complexity of first adding WordsNow, meaning the trigger point is not
// exactly where you might assume, but it shouldnt matter.
#define MALLOC(MallocFunc,WordsPrev,WordsNow) \
(((WordsPrev) > j__uMaxWords) ? 0UL : MallocFunc(WordsNow))
// Clear words starting at address:
//
// Note: Only use this for objects that care; in other cases, it doesnt
// matter if the objects memory is pre-zeroed.
#define ZEROWORDS(Addr,Words) \
{ \
Word_t Words__ = (Words); \
PWord_t Addr__ = (PWord_t) (Addr); \
while (Words__--) *Addr__++ = 0UL; \
}
#ifdef TRACEMI
// TRACING SUPPORT:
//
// Note: For TRACEMI, use a format for address printing compatible with other
// tracing facilities; in particular, %x not %lx, to truncate the "noisy" high
// part on 64-bit systems.
//
// TBD: The trace macros need fixing for alternate address types.
//
// Note: TRACEMI2 supports trace analysis no matter the underlying malloc/free
// engine used.
#include <stdio.h>
static Word_t j__udyMemSequence = 0L; // event sequence number.
#define TRACE_ALLOC5(a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_FREE5( a,b,c,d,e) (void) printf(a, (b), c, d)
#define TRACE_ALLOC6(a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#define TRACE_FREE6( a,b,c,d,e,f) (void) printf(a, (b), c, d, e)
#else
#ifdef TRACEMI2
#include <stdio.h>
#define b_pw cJU_BYTESPERWORD
#define TRACE_ALLOC5(a,b,c,d,e) \
(void) printf("a %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_FREE5( a,b,c,d,e) \
(void) printf("f %lx %lx %lx\n", (b), (d) * b_pw, e)
#define TRACE_ALLOC6(a,b,c,d,e,f) \
(void) printf("a %lx %lx %lx\n", (b), (e) * b_pw, f)
#define TRACE_FREE6( a,b,c,d,e,f) \
(void) printf("f %lx %lx %lx\n", (b), (e) * b_pw, f)
static Word_t j__udyMemSequence = 0L; // event sequence number.
#else
#define TRACE_ALLOC5(a,b,c,d,e) // null.
#define TRACE_FREE5( a,b,c,d,e) // null.
#define TRACE_ALLOC6(a,b,c,d,e,f) // null.
#define TRACE_FREE6( a,b,c,d,e,f) // null.
#endif // ! TRACEMI2
#endif // ! TRACEMI
// MALLOC NAMESPACE SUPPORT:
#if (defined(DEBUG) && (! defined(MALLOCBITS))) // for now, DEBUG => MALLOCBITS:
#define MALLOCBITS 1
#endif
#ifdef MALLOCBITS
#define MALLOCBITS_VALUE 0x3 // bit pattern to use.
#define MALLOCBITS_MASK 0x7 // note: matches mask__ in JudyPrivate.h.
#define MALLOCBITS_SET( Type,Addr) \
((Addr) = (Type) ((Word_t) (Addr) | MALLOCBITS_VALUE))
#define MALLOCBITS_TEST(Type,Addr) \
assert((((Word_t) (Addr)) & MALLOCBITS_MASK) == MALLOCBITS_VALUE); \
((Addr) = (Type) ((Word_t) (Addr) & ~MALLOCBITS_VALUE))
#else
#define MALLOCBITS_SET( Type,Addr) // null.
#define MALLOCBITS_TEST(Type,Addr) // null.
#endif
// SAVE ERROR INFORMATION IN A Pjpm:
//
// "Small" (invalid) Addr values are used to distinguish overrun and no-mem
// errors. (TBD, non-zero invalid values are no longer returned from
// lower-level functions, that is, JU_ERRNO_OVERRUN is no longer detected.)
#define J__UDYSETALLOCERROR(Addr) \
{ \
JU_ERRID(Pjpm) = __LINE__; \
if ((Word_t) (Addr) > 0) JU_ERRNO(Pjpm) = JU_ERRNO_OVERRUN; \
else JU_ERRNO(Pjpm) = JU_ERRNO_NOMEM; \
return(0); \
}
// ****************************************************************************
// ALLOCATION FUNCTIONS:
//
// To help the compiler catch coding errors, each function returns a specific
// object type.
//
// Note: Only j__udyAllocJPM() and j__udyAllocJLW() return multiple values <=
// sizeof(Word_t) to indicate the type of memory allocation failure. Other
// allocation functions convert this failure to a JU_ERRNO.
// Note: Unlike other j__udyAlloc*() functions, Pjpms are returned non-raw,
// that is, without malloc namespace or root pointer type bits:
FUNCTION Pjpm_t j__udyAllocJPM(void)
{
Word_t Words = sizeof(jpm_t) / cJU_BYTESPERWORD;
Pjpm_t Pjpm = (Pjpm_t) MALLOC(JudyMalloc, Words, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jpm_t));
if ((Word_t) Pjpm > sizeof(Word_t))
{
ZEROWORDS(Pjpm, Words);
Pjpm->jpm_TotalMemWords = Words;
}
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJPM(), Words = %lu\n",
Pjpm, j__udyMemSequence++, Words, cJU_LEAFW_MAXPOP1 + 1);
// MALLOCBITS_SET(Pjpm_t, Pjpm); // see above.
return(Pjpm);
} // j__udyAllocJPM()
FUNCTION Pjbl_t j__udyAllocJBL(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
Pjbl_t PjblRaw = (Pjbl_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbl_t));
if ((Word_t) PjblRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBL(PjblRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjblRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBL(), Words = %lu\n", PjblRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbl_t, PjblRaw);
return(PjblRaw);
} // j__udyAllocJBL()
FUNCTION Pjbb_t j__udyAllocJBB(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
Pjbb_t PjbbRaw = (Pjbb_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbb_t));
if ((Word_t) PjbbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JBB(PjbbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBB(), Words = %lu\n", PjbbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbb_t, PjbbRaw);
return(PjbbRaw);
} // j__udyAllocJBB()
FUNCTION Pjp_t j__udyAllocJBBJP(Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
Pjp_t PjpRaw;
PjpRaw = (Pjp_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjpRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjpRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJBBJP(%lu), Words = %lu\n", PjpRaw,
j__udyMemSequence++, NumJPs, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjp_t, PjpRaw);
return(PjpRaw);
} // j__udyAllocJBBJP()
FUNCTION Pjbu_t j__udyAllocJBU(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
Pjbu_t PjbuRaw = (Pjbu_t) MALLOC(JudyMallocVirtual,
Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jbu_t));
if ((Word_t) PjbuRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjbuRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJBU(), Words = %lu\n", PjbuRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjbu_t, PjbuRaw);
return(PjbuRaw);
} // j__udyAllocJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION Pjll_t j__udyAllocJLL1(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL1(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION Pjll_t j__udyAllocJLL2(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL2(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL2()
FUNCTION Pjll_t j__udyAllocJLL3(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL3(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL3()
#ifdef JU_64BIT
FUNCTION Pjll_t j__udyAllocJLL4(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL4(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL4()
FUNCTION Pjll_t j__udyAllocJLL5(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL5(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL5()
FUNCTION Pjll_t j__udyAllocJLL6(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL6(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL6()
FUNCTION Pjll_t j__udyAllocJLL7(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
Pjll_t PjllRaw;
PjllRaw = (Pjll_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjllRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjllRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLL7(%lu), Words = %lu\n", PjllRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjll_t, PjllRaw);
return(PjllRaw);
} // j__udyAllocJLL7()
#endif // JU_64BIT
// Note: Root-level leaf addresses are always whole words (Pjlw_t), and unlike
// other j__udyAlloc*() functions, they are returned non-raw, that is, without
// malloc namespace or root pointer type bits (the latter are added later by
// the caller):
FUNCTION Pjlw_t j__udyAllocJLW(Word_t Pop1)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
Pjlw_t Pjlw = (Pjlw_t) MALLOC(JudyMalloc, Words, Words);
TRACE_ALLOC6("0x%x %8lu = j__udyAllocJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1);
// MALLOCBITS_SET(Pjlw_t, Pjlw); // see above.
return(Pjlw);
} // j__udyAllocJLW()
FUNCTION Pjlb_t j__udyAllocJLB1(Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
Pjlb_t PjlbRaw;
PjlbRaw = (Pjlb_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
assert((Words * cJU_BYTESPERWORD) == sizeof(jlb_t));
if ((Word_t) PjlbRaw > sizeof(Word_t))
{
ZEROWORDS(P_JLB(PjlbRaw), Words);
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjlbRaw); }
TRACE_ALLOC5("0x%x %8lu = j__udyAllocJLB1(), Words = %lu\n", PjlbRaw,
j__udyMemSequence++, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjlb_t, PjlbRaw);
return(PjlbRaw);
} // j__udyAllocJLB1()
#ifdef JUDYL
FUNCTION Pjv_t j__udyLAllocJV(Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
Pjv_t PjvRaw;
PjvRaw = (Pjv_t) MALLOC(JudyMalloc, Pjpm->jpm_TotalMemWords, Words);
if ((Word_t) PjvRaw > sizeof(Word_t))
{
Pjpm->jpm_TotalMemWords += Words;
}
else { J__UDYSETALLOCERROR(PjvRaw); }
TRACE_ALLOC6("0x%x %8lu = j__udyLAllocJV(%lu), Words = %lu\n", PjvRaw,
j__udyMemSequence++, Pop1, Words, (Pjpm->jpm_Pop0) + 2);
MALLOCBITS_SET(Pjv_t, PjvRaw);
return(PjvRaw);
} // j__udyLAllocJV()
#endif // JUDYL
// ****************************************************************************
// FREE FUNCTIONS:
//
// To help the compiler catch coding errors, each function takes a specific
// object type to free.
// Note: j__udyFreeJPM() receives a root pointer with NO root pointer type
// bits present, that is, they must be stripped by the caller using P_JPM():
FUNCTION void j__udyFreeJPM(Pjpm_t PjpmFree, Pjpm_t PjpmStats)
{
Word_t Words = sizeof(jpm_t) / cJU_BYTESPERWORD;
// MALLOCBITS_TEST(Pjpm_t, PjpmFree); // see above.
JudyFree((Pvoid_t) PjpmFree, Words);
if (PjpmStats != (Pjpm_t) NULL) PjpmStats->jpm_TotalMemWords -= Words;
// Note: Log PjpmFree->jpm_Pop0, similar to other j__udyFree*() functions, not
// an assumed value of cJU_LEAFW_MAXPOP1, for when the caller is
// Judy*FreeArray(), jpm_Pop0 is set to 0, and the population after the free
// really will be 0, not cJU_LEAFW_MAXPOP1.
TRACE_FREE6("0x%x %8lu = j__udyFreeJPM(%lu), Words = %lu\n", PjpmFree,
j__udyMemSequence++, Words, Words, PjpmFree->jpm_Pop0);
} // j__udyFreeJPM()
FUNCTION void j__udyFreeJBL(Pjbl_t Pjbl, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbl_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbl_t, Pjbl);
JudyFreeVirtual((Pvoid_t) Pjbl, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBL(), Words = %lu\n", Pjbl,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBL()
FUNCTION void j__udyFreeJBB(Pjbb_t Pjbb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbb_t, Pjbb);
JudyFreeVirtual((Pvoid_t) Pjbb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBB(), Words = %lu\n", Pjbb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBB()
FUNCTION void j__udyFreeJBBJP(Pjp_t Pjp, Word_t NumJPs, Pjpm_t Pjpm)
{
Word_t Words = JU_BRANCHJP_NUMJPSTOWORDS(NumJPs);
MALLOCBITS_TEST(Pjp_t, Pjp);
JudyFree((Pvoid_t) Pjp, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJBBJP(%lu), Words = %lu\n", Pjp,
j__udyMemSequence++, NumJPs, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBBJP()
FUNCTION void j__udyFreeJBU(Pjbu_t Pjbu, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jbu_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjbu_t, Pjbu);
JudyFreeVirtual((Pvoid_t) Pjbu, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJBU(), Words = %lu\n", Pjbu,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJBU()
#if (defined(JUDYL) || (! defined(JU_64BIT)))
FUNCTION void j__udyFreeJLL1(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF1POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL1(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL1()
#endif // (JUDYL || (! JU_64BIT))
FUNCTION void j__udyFreeJLL2(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF2POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL2(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL2()
FUNCTION void j__udyFreeJLL3(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF3POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL3(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL3()
#ifdef JU_64BIT
FUNCTION void j__udyFreeJLL4(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF4POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL4(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL4()
FUNCTION void j__udyFreeJLL5(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF5POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL5(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL5()
FUNCTION void j__udyFreeJLL6(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF6POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL6(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL6()
FUNCTION void j__udyFreeJLL7(Pjll_t Pjll, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAF7POPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjll_t, Pjll);
JudyFree((Pvoid_t) Pjll, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLL7(%lu), Words = %lu\n", Pjll,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLL7()
#endif // JU_64BIT
// Note: j__udyFreeJLW() receives a root pointer with NO root pointer type
// bits present, that is, they are stripped by P_JLW():
FUNCTION void j__udyFreeJLW(Pjlw_t Pjlw, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JU_LEAFWPOPTOWORDS(Pop1);
// MALLOCBITS_TEST(Pjlw_t, Pjlw); // see above.
JudyFree((Pvoid_t) Pjlw, Words);
if (Pjpm) Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyFreeJLW(%lu), Words = %lu\n", Pjlw,
j__udyMemSequence++, Pop1, Words, Pop1 - 1);
} // j__udyFreeJLW()
FUNCTION void j__udyFreeJLB1(Pjlb_t Pjlb, Pjpm_t Pjpm)
{
Word_t Words = sizeof(jlb_t) / cJU_BYTESPERWORD;
MALLOCBITS_TEST(Pjlb_t, Pjlb);
JudyFree((Pvoid_t) Pjlb, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE5("0x%x %8lu = j__udyFreeJLB1(), Words = %lu\n", Pjlb,
j__udyMemSequence++, Words, Pjpm->jpm_Pop0);
} // j__udyFreeJLB1()
#ifdef JUDYL
FUNCTION void j__udyLFreeJV(Pjv_t Pjv, Word_t Pop1, Pjpm_t Pjpm)
{
Word_t Words = JL_LEAFVPOPTOWORDS(Pop1);
MALLOCBITS_TEST(Pjv_t, Pjv);
JudyFree((Pvoid_t) Pjv, Words);
Pjpm->jpm_TotalMemWords -= Words;
TRACE_FREE6("0x%x %8lu = j__udyLFreeJV(%lu), Words = %lu\n", Pjv,
j__udyMemSequence++, Pop1, Words, Pjpm->jpm_Pop0);
} // j__udyLFreeJV()
#endif // JUDYL

View File

@ -1,259 +0,0 @@
// Copyright (C) 2000 - 2002 Hewlett-Packard Company
//
// This program is free software; you can redistribute it and/or modify it
// under the term of the GNU Lesser General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
// for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
// _________________
// @(#) $Revision$ $Source$
//
// Return number of bytes of memory used to support a Judy1/L array.
// Compile with one of -DJUDY1 or -DJUDYL.
#if (! (defined(JUDY1) || defined(JUDYL)))
#error: One of -DJUDY1 or -DJUDYL must be specified.
#endif
#ifdef JUDY1
#include "Judy1.h"
#else
#include "JudyL.h"
#endif
#include "JudyPrivate1L.h"
FUNCTION static Word_t j__udyGetMemActive(Pjp_t);
// ****************************************************************************
// J U D Y 1 M E M A C T I V E
// J U D Y L M E M A C T I V E
#ifdef JUDY1
FUNCTION Word_t Judy1MemActive
#else
FUNCTION Word_t JudyLMemActive
#endif
(
Pcvoid_t PArray // from which to retrieve.
)
{
if (PArray == (Pcvoid_t)NULL) return(0);
if (JU_LEAFW_POP0(PArray) < cJU_LEAFW_MAXPOP1) // must be a LEAFW
{
Pjlw_t Pjlw = P_JLW(PArray); // first word of leaf.
Word_t Words = Pjlw[0] + 1; // population.
#ifdef JUDY1
return((Words + 1) * sizeof(Word_t));
#else
return(((Words * 2) + 1) * sizeof(Word_t));
#endif
}
else
{
Pjpm_t Pjpm = P_JPM(PArray);
return(j__udyGetMemActive(&Pjpm->jpm_JP) + sizeof(jpm_t));
}
} // JudyMemActive()
// ****************************************************************************
// __ J U D Y G E T M E M A C T I V E
FUNCTION static Word_t j__udyGetMemActive(
Pjp_t Pjp) // top of subtree.
{
Word_t offset; // in a branch.
Word_t Bytes = 0; // actual bytes used at this level.
Word_t IdxSz; // bytes per index in leaves
switch (JU_JPTYPE(Pjp))
{
case cJU_JPBRANCH_L2:
case cJU_JPBRANCH_L3:
#ifdef JU_64BIT
case cJU_JPBRANCH_L4:
case cJU_JPBRANCH_L5:
case cJU_JPBRANCH_L6:
case cJU_JPBRANCH_L7:
#endif
case cJU_JPBRANCH_L:
{
Pjbl_t Pjbl = P_JBL(Pjp->jp_Addr);
for (offset = 0; offset < (Pjbl->jbl_NumJPs); ++offset)
Bytes += j__udyGetMemActive((Pjbl->jbl_jp) + offset);
return(Bytes + sizeof(jbl_t));
}
case cJU_JPBRANCH_B2:
case cJU_JPBRANCH_B3:
#ifdef JU_64BIT
case cJU_JPBRANCH_B4:
case cJU_JPBRANCH_B5:
case cJU_JPBRANCH_B6:
case cJU_JPBRANCH_B7:
#endif
case cJU_JPBRANCH_B:
{
Word_t subexp;
Word_t jpcount;
Pjbb_t Pjbb = P_JBB(Pjp->jp_Addr);
for (subexp = 0; subexp < cJU_NUMSUBEXPB; ++subexp)
{
jpcount = j__udyCountBitsB(JU_JBB_BITMAP(Pjbb, subexp));
Bytes += jpcount * sizeof(jp_t);
for (offset = 0; offset < jpcount; ++offset)
{
Bytes += j__udyGetMemActive(P_JP(JU_JBB_PJP(Pjbb, subexp))
+ offset);
}
}
return(Bytes + sizeof(jbb_t));
}
case cJU_JPBRANCH_U2:
case cJU_JPBRANCH_U3:
#ifdef JU_64BIT
case cJU_JPBRANCH_U4:
case cJU_JPBRANCH_U5:
case cJU_JPBRANCH_U6:
case cJU_JPBRANCH_U7:
#endif
case cJU_JPBRANCH_U:
{
Pjbu_t Pjbu = P_JBU(Pjp->jp_Addr);
for (offset = 0; offset < cJU_BRANCHUNUMJPS; ++offset)
{
if (((Pjbu->jbu_jp[offset].jp_Type) >= cJU_JPNULL1)
&& ((Pjbu->jbu_jp[offset].jp_Type) <= cJU_JPNULLMAX))
{
continue; // skip null JP to save time.
}
Bytes += j__udyGetMemActive(Pjbu->jbu_jp + offset);
}
return(Bytes + sizeof(jbu_t));
}
// -- Cases below here terminate and do not recurse. --
#if (defined(JUDYL) || (! defined(JU_64BIT)))
case cJU_JPLEAF1: IdxSz = 1; goto LeafWords;
#endif
case cJU_JPLEAF2: IdxSz = 2; goto LeafWords;
case cJU_JPLEAF3: IdxSz = 3; goto LeafWords;
#ifdef JU_64BIT
case cJU_JPLEAF4: IdxSz = 4; goto LeafWords;
case cJU_JPLEAF5: IdxSz = 5; goto LeafWords;
case cJU_JPLEAF6: IdxSz = 6; goto LeafWords;
case cJU_JPLEAF7: IdxSz = 7; goto LeafWords;
#endif
LeafWords:
#ifdef JUDY1
return(IdxSz * (JU_JPLEAF_POP0(Pjp) + 1));
#else
return((IdxSz + sizeof(Word_t))
* (JU_JPLEAF_POP0(Pjp) + 1));
#endif
case cJU_JPLEAF_B1:
{
#ifdef JUDY1
return(sizeof(jlb_t));
#else
Bytes = (JU_JPLEAF_POP0(Pjp) + 1) * sizeof(Word_t);
return(Bytes + sizeof(jlb_t));
#endif
}
JUDY1CODE(case cJ1_JPFULLPOPU1: return(0);)
#ifdef JUDY1
#define J__Mpy 0
#else
#define J__Mpy sizeof(Word_t)
#endif
case cJU_JPIMMED_1_01: return(0);
case cJU_JPIMMED_2_01: return(0);
case cJU_JPIMMED_3_01: return(0);
#ifdef JU_64BIT
case cJU_JPIMMED_4_01: return(0);
case cJU_JPIMMED_5_01: return(0);
case cJU_JPIMMED_6_01: return(0);
case cJU_JPIMMED_7_01: return(0);
#endif
case cJU_JPIMMED_1_02: return(J__Mpy * 2);
case cJU_JPIMMED_1_03: return(J__Mpy * 3);
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_1_04: return(J__Mpy * 4);
case cJU_JPIMMED_1_05: return(J__Mpy * 5);
case cJU_JPIMMED_1_06: return(J__Mpy * 6);
case cJU_JPIMMED_1_07: return(J__Mpy * 7);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_1_08: return(0);
case cJ1_JPIMMED_1_09: return(0);
case cJ1_JPIMMED_1_10: return(0);
case cJ1_JPIMMED_1_11: return(0);
case cJ1_JPIMMED_1_12: return(0);
case cJ1_JPIMMED_1_13: return(0);
case cJ1_JPIMMED_1_14: return(0);
case cJ1_JPIMMED_1_15: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_2_02: return(J__Mpy * 2);
case cJU_JPIMMED_2_03: return(J__Mpy * 3);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_2_04: return(0);
case cJ1_JPIMMED_2_05: return(0);
case cJ1_JPIMMED_2_06: return(0);
case cJ1_JPIMMED_2_07: return(0);
#endif
#if (defined(JUDY1) || defined(JU_64BIT))
case cJU_JPIMMED_3_02: return(J__Mpy * 2);
#endif
#if (defined(JUDY1) && defined(JU_64BIT))
case cJ1_JPIMMED_3_03: return(0);
case cJ1_JPIMMED_3_04: return(0);
case cJ1_JPIMMED_3_05: return(0);
case cJ1_JPIMMED_4_02: return(0);
case cJ1_JPIMMED_4_03: return(0);
case cJ1_JPIMMED_5_02: return(0);
case cJ1_JPIMMED_5_03: return(0);
case cJ1_JPIMMED_6_02: return(0);
case cJ1_JPIMMED_7_02: return(0);
#endif
} // switch (JU_JPTYPE(Pjp))
return(0); // to make some compilers happy.
} // j__udyGetMemActive()

Some files were not shown because too many files have changed in this diff Show More