[med-svn] [Git][med-team/libgclib][upstream] New upstream version 0.11.9
Michael R. Crusoe
gitlab at salsa.debian.org
Mon Jun 1 15:07:21 BST 2020
Michael R. Crusoe pushed to branch upstream at Debian Med / libgclib
Commits:
34c651e5 by Michael R. Crusoe at 2020-06-01T15:48:17+02:00
New upstream version 0.11.9
- - - - -
18 changed files:
- GBase.cpp
- GBase.h
- GFastaIndex.cpp
- GHash.hh
- GIntHash.hh
- + GResUsage.cpp
- + GResUsage.h
- GThreads.cpp
- GThreads.h
- Makefile
- README.md
- gcdb.cpp
- gcdb.h
- gsocket.cpp
- gsocket.h
- gstopwatch.cpp
- gstopwatch.h
- + htest.cpp
Changes:
=====================================
GBase.cpp
=====================================
@@ -10,6 +10,10 @@
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
#endif
+//#ifdef _WIN32
+// int (WINAPIV * __vsnprintf)(char *, size_t, const char*, va_list) = _vsnprintf;
+//#endif
+
//************************* Debug helpers **************************
// Assert failed routine
void GAssert(const char* expression, const char* filename, unsigned int lineno){
@@ -25,7 +29,7 @@ void GAssert(const char* expression, const char* filename, unsigned int lineno){
// Error routine (prints error message and exits!)
void GError(const char* format,...){
- #ifdef __WIN32__
+ #ifdef _WIN32
char msg[4096];
va_list arguments;
va_start(arguments,format);
@@ -50,7 +54,7 @@ void GError(const char* format,...){
// Warning routine (just print message without exiting)
void GMessage(const char* format,...){
- #ifdef __WIN32__
+ #ifdef _WIN32
char msg[4096];
va_list arguments;
va_start(arguments,format);
@@ -71,7 +75,8 @@ void GMessage(const char* format,...){
// Allocate memory
bool GMalloc(pointer* ptr,unsigned long size){
//GASSERT(ptr);
- if (size!=0) *ptr=malloc(size);
+ if (size!=0)
+ *ptr=malloc(size);
return *ptr!=NULL;
}
@@ -150,16 +155,17 @@ int Gstrcmp(const char* a, const char* b, int n) {
int G_mkdir(const char* path, int perms = (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ) {
//int perms=(S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) ) {
- #ifdef __WIN32__
- return _mkdir(path);
+ #ifdef _WIN32
+ //return _mkdir(path);
+ return CreateDirectoryA(path, NULL);
#else
- return mkdir(path, perms);
+ return mkdir(path, perms);
#endif
}
void Gmktempdir(char* templ) {
-#ifdef __WIN32__
+#ifdef _WIN32
int blen=strlen(templ);
if (_mktemp_s(templ, blen)!=0)
GError("Error creating temp dir %s!\n", templ);
@@ -379,6 +385,7 @@ char* rstrchr(char* str, char ch) { /* returns a pointer to the rightmost
}
+
/* DOS/UNIX safer fgets : reads a text line from a (binary) file and
update the file position accordingly and the buffer capacity accordingly.
The given buf is resized to read the entire line in memory
@@ -717,9 +724,9 @@ int fileExists(const char* fname) {
}
int64 fileSize(const char* fpath) {
-#ifdef __WIN32__
+#ifdef _WIN32
WIN32_FILE_ATTRIBUTE_DATA fad;
- if (!GetFileAttributesEx(name, GetFileExInfoStandard, &fad))
+ if (!GetFileAttributesEx(fpath, GetFileExInfoStandard, &fad))
return -1; // error condition, could call GetLastError to find out more
LARGE_INTEGER size;
size.HighPart = fad.nFileSizeHigh;
=====================================
GBase.h
=====================================
@@ -1,10 +1,22 @@
#ifndef G_BASE_DEFINED
#define G_BASE_DEFINED
-#define GCLIB_VERSION "0.11.8"
+#define GCLIB_VERSION "0.11.9"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
+
+#if defined(__WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW64__) || defined(__WINDOWS__)
+ #ifndef _WIN32
+ #define _WIN32
+ #endif
+ #ifndef _WIN64
+ #define _WIN64
+ #endif
+ #define __USE_MINGW_ANSI_STDIO 1
+ //#define __ISO_C_VISIBLE 1999
+#endif
+
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -15,19 +27,9 @@
#include <stdint.h>
#include <stdarg.h>
-#if defined __WIN32 || defined __WIN32__ || defined _WIN32 || defined _WIN32_ || defined _WINDOWS
- #ifndef __WIN32__
- #define __WIN32__
- #endif
+#ifdef _WIN32
#include <windows.h>
- #include <direct.h>
#include <io.h>
- #ifndef strcasecmp
- #define strcasecmp _stricmp
- #endif
- #ifndef strncasecmp
- #define strncasecmp _strnicmp
- #endif
#define CHPATHSEP '\\'
#undef off_t
#define off_t int64_t
@@ -204,7 +206,6 @@ bool GCalloc(pointer* ptr, unsigned long size); // Allocate and initialize memor
bool GRealloc(pointer* ptr,unsigned long size); // Resize memory
void GFree(pointer* ptr); // Free memory, resets ptr to NULL
-
//int saprintf(char **retp, const char *fmt, ...);
void GError(const char* format,...); // Error routine (aborts program)
@@ -233,6 +234,7 @@ char* loCase(const char* str);
char* strlower(char * str);
char* strupper(char * str);
+
//strstr but for memory zones: scans a memory region
//for a substring:
void* Gmemscan(void *mem, unsigned int len,
@@ -436,7 +438,7 @@ template<class OBJ> class GDynArray {
Clear();
return *this;
}
- increaseCapacity(a.fCapacity); //set size
+ growTo(a.fCapacity); //set size
memcpy(fArray, a.fArray, sizeof(OBJ)*a.fCount);
return *this;
}
@@ -451,7 +453,7 @@ template<class OBJ> class GDynArray {
if (GDynArray_MAXCOUNT-delta<=fCapacity)
delta=GDynArray_MAXCOUNT-fCapacity;
if (delta<=1) GError("Error at GDynArray::Grow(): max capacity reached!\n");
- increaseCapacity(fCapacity + delta);
+ growTo(fCapacity + delta);
}
#define GDynArray_ADD(item) \
if (fCount==MAX_UINT-1) GError("Error at GDynArray: cannot add item, maximum count reached!\n"); \
@@ -483,12 +485,27 @@ template<class OBJ> class GDynArray {
uint Count() { return fCount; } // get size of array (elements)
uint Capacity() { return fCapacity; }
- void increaseCapacity(uint newcap) {
+ void growTo(uint newcap) {
if (newcap==0) { Clear(); return; }
- if (newcap <= fCapacity) return; //never shrinks (use Pack() for this)
+ if (newcap <= fCapacity) return; //never shrink! (use Pack() for shrinking)
GREALLOC(fArray, newcap*sizeof(OBJ));
fCapacity=newcap;
}
+
+ void append(OBJ* arr, uint count) {
+ //fast adding of a series of objects
+ growTo(fCount+count);
+ memcpy(fArray+fCount, arr, count*sizeof(OBJ));
+ fCount+=count;
+ }
+
+ void append(GDynArray<OBJ> arr) {
+ //fast adding of a series of objects
+ growTo(fCount+arr.fCount);
+ memcpy(fArray+fCount, arr.fArray, arr.fCount*sizeof(OBJ));
+ fCount+=arr.fCount;
+ }
+
void Trim(int tcount=1) {
//simply cut (discard) the last tcount items
//new Count is now fCount-tcount
@@ -503,6 +520,15 @@ template<class OBJ> class GDynArray {
fCapacity=newcap;
}
+ void zPack(OBJ z) { //shrink capacity to fCount+1 and adds a z terminator
+ if (fCapacity-fCount<=1) { fArray[fCount]=z; return; }
+ int newcap=fCount+1;
+ GREALLOC(fArray, newcap*sizeof(OBJ));
+ fCapacity=newcap;
+ fArray[fCount]=z;
+ }
+
+
inline void Shrink() { Pack(); }
void Delete(uint idx) {
@@ -527,7 +553,7 @@ template<class OBJ> class GDynArray {
OBJ* operator()() { return fArray; }
- //use below to prevent freeing the fArray pointer
+ //use methods below in order to prevent deallocation of fArray pointer on destruct
//could be handy for adopting stack objects (e.g. cheap dynamic strings)
void ForgetPtr() { byptr=true; }
void DetachPtr() { byptr=true; }
@@ -547,7 +573,6 @@ int strsplit(char* str, GDynArray<char*>& fields, int maxfields=MAX_INT); //spli
//splits a string by placing 0 where tab or space is found, setting fields[] to the beginning
//of each field (stopping after maxfields); returns number of fields parsed
-//--------------------------------------------------------
// ************** simple line reading class for text files
//GLineReader -- text line reading/buffering class
class GLineReader {
=====================================
GFastaIndex.cpp
=====================================
@@ -47,7 +47,7 @@ int GFastaIndex::loadIndex(const char* finame) { //load record info from existin
p++;
uint len=0;
int line_len=0, line_blen=0;
-#ifdef __WIN32__
+#ifdef _WIN32
long offset=-1;
sscanf(p, "%d%ld%d%d", &len, &offset, &line_len, &line_blen);
#else
@@ -164,7 +164,7 @@ int GFastaIndex::storeIndex(FILE* fai) {
}
//reclist has records sorted by file offset
for (int i=0;i<reclist.Count();i++) {
-#ifdef __WIN32__
+#ifdef _WIN32
int written=fprintf(fai, "%s\t%d\t%ld\t%d\t%d\n",
reclist[i]->seqname,reclist[i]->seqlen,(long)reclist[i]->fpos,
reclist[i]->line_len, reclist[i]->line_blen);
=====================================
GHash.hh
=====================================
@@ -1,139 +1,129 @@
/********************************************************************************
-* Hash table class template (char* based) *
-*********************************************************************************/
+ * Hash table class template (char* based) *
+ *********************************************************************************/
#ifndef GHash_HH
#define GHash_HH
#include "GBase.h"
/**
-* This class maintains a fast-access hash table of entities
-* indexed by a character string (essentially, maps strings to pointers)
-*/
+ * This class maintains a fast-access hash table of entities
+ * indexed by a character string (essentially, maps strings to pointers)
+ */
//#define HASH_DBG_PRINT 1
#define GSTR_HASH(s) strhash(s)
//#define GSTR_HASH(s) djb_hash(s)
//#define GSTR_HASH(s) fnv1a_hash(s)
+//#define GSTR_HASH(s) murmur3(s)
template <class OBJ> class GHash {
- protected:
+protected:
struct GHashEntry {
- char* key; // Key string
- bool keyalloc; //shared key flag (to not free the key chars)
- int hash; // Hash value of key
- pointer data; // Data
- bool mark; // Entry is marked
- };
- GHashEntry* hash; // Hash
- int fCapacity; // table size
- int fCount; // number of valid entries
- int fCurrentEntry;
- char* lastkeyptr; //pointer to last key string added
- //---------- Raw data retrieval (including empty entries
- // Return key at position pos.
- const char* Key(uint pos) const { return hash[pos].key; }
- // return data OBJ* at given position
- OBJ* Data(uint pos) const { return (OBJ*) hash[pos].data; }
- // Return mark flag of entry at position pos.
- bool Mark(uint pos) const { return hash[pos].mark; }
- // Return position of first filled slot, or >= fCapacity
- int First() const;
- // Return position of last filled slot or -1
- int Last() const;
- // Return position of next filled slot in hash table
- // or a value greater than or equal to fCapacity if no filled
- // slot was found
- int Next(int pos) const;
- //Return position of previous filled slot in hash table
- //or a -1 if no filled slot was found
- int Prev(int pos) const;
+ char* key; // Key string
+ bool keyalloc; // shared key flag (to free/not the key)
+ int hash; // Hash value of key
+ pointer data; // Data
+ };
+ GHashEntry* hash; // Hash
+ int fCapacity; // table size
+ int fCount; // number of valid entries
+ int fCurrentEntry;
+ char* lastkeyptr; //pointer to last key string added
+ //---------- Raw data retrieval (including empty entries)
+ // Return key at position pos.
+ const char* Key(uint pos) const { return hash[pos].key; }
+ // return data OBJ* at given position
+ OBJ* Data(uint pos) const { return (OBJ*) hash[pos].data; }
+ // Return position of first filled slot, or >= fCapacity
+ int First() const;
+ // Return position of last filled slot or -1
+ int Last() const;
+ // Return position of next filled slot in hash table
+ // or a value greater than or equal to fCapacity if no filled
+ // slot was found
+ int Next(int pos) const;
+ //Return position of previous filled slot in hash table
+ //or a -1 if no filled slot was found
+ int Prev(int pos) const;
private:
- GHash(const GHash&);
- GHash &operator=(const GHash&);
- GFreeProc* fFreeProc; //procedure to free item data
+ GHash(const GHash&);
+ GHash &operator=(const GHash&);
+ GFreeProc* fFreeProc; //procedure to free item data
protected:
public:
- static void DefaultFreeProc(pointer item) {
- delete (OBJ*)item;
- }
+ static void DefaultFreeProc(pointer item) {
+ delete (OBJ*)item;
+ }
public:
- GHash(GFreeProc* freeProc); // constructs of an empty hash
- GHash(bool doFree=true); // constructs of an empty hash (free the item objects)
- void setFreeItem(GFreeProc *freeProc) { fFreeProc=freeProc; }
- void setFreeItem(bool doFree) { fFreeProc=(doFree)? &DefaultFreeProc : NULL; }
- int Capacity() const { return fCapacity; } // table's size, including the empty slots.
- void Resize(int m); // Resize the table to the given size.
- int Count() const { return fCount; }// the total number of entries in the table.
-
- // Insert a new entry into the table given key and mark.
- // If there is already an entry with that key, leave it unchanged
- OBJ* Add(const char* ky, OBJ* ptr=NULL, bool mrk=false);
-
- //same with Add, but frees the old element if it's a replacement
- OBJ* fAdd(const char* ky, OBJ* ptr=NULL);
-
- //same as Add, but the key pointer is stored directly, no string duplicate
- //is made (shared-key-Add)
- OBJ* shkAdd(const char* ky, OBJ* ptr, bool mrk=false);
-
- // Replace data at key, if the entry's mark is less than
- // or equal to the given mark. If there was no existing entry,
- // a new entry is inserted with the given mark.
- OBJ* Replace(const char* ky, OBJ* ptr, bool mrk=false);
- // Remove a given key and its data
- OBJ* Remove(const char* ky);
- // Find data OBJ* given key.
- OBJ* Find(const char* ky, char** keyptr=NULL);
- bool hasKey(const char* ky);
- char* getLastKey() { return lastkeyptr; }
- OBJ* operator[](const char* ky) { return Find(ky); }
- void startIterate(); //iterator-like initialization
- char* NextKey(); //returns next valid key in the table (NULL if no more)
- OBJ* NextData(); //returns next valid hash[].data
- OBJ* NextData(char*& nextkey); //returns next valid hash[].data
- //or NULL if no more
- //nextkey is SET to the corresponding key
- GHashEntry* NextEntry() { //returns a pointer to a GHashEntry
- int pos=fCurrentEntry;
- while (pos<fCapacity && hash[pos].hash<0) pos++;
- if (pos==fCapacity) {
- fCurrentEntry=fCapacity;
- return NULL;
- }
- else {
- fCurrentEntry=pos+1;
- return &hash[pos];
- }
- }
- /// Clear all entries
- void Clear();
-
- /// Destructor
- virtual ~GHash();
- };
+ GHash(GFreeProc* freeProc); // constructs of an empty hash
+ GHash(bool doFree=true); // constructs of an empty hash (free the item objects)
+ void setFreeItem(GFreeProc *freeProc) { fFreeProc=freeProc; }
+ void setFreeItem(bool doFree) { fFreeProc=(doFree)? &DefaultFreeProc : NULL; }
+ int Capacity() const { return fCapacity; } // table's size, including the empty slots.
+ void Resize(int m); // Resize the table to the given size.
+ int Count() const { return fCount; }// the total number of entries in the table.
+
+ // Insert a new entry into the table given key.
+ // If there is already an entry with that key, leave it unchanged
+ OBJ* Add(const char* ky, OBJ* ptr=NULL);
+
+ //same with Add, but frees the old element if it's a replacement
+ OBJ* fAdd(const char* ky, OBJ* ptr=NULL);
+
+ //same as Add, but the key pointer is stored directly, no string copy needed
+ //(shared-key-Add)
+ OBJ* shkAdd(const char* ky, OBJ* ptr);
+
+ // Replace data at key. If there was no existing entry,
+ // a new entry is inserted.
+ OBJ* Replace(const char* ky, OBJ* ptr);
+ // Remove a given key and its data
+ OBJ* Remove(const char* ky);
+ // Find data OBJ* given key.
+ OBJ* Find(const char* ky, char** keyptr=NULL);
+ bool hasKey(const char* ky);
+ char* getLastKey() { return lastkeyptr; }
+ OBJ* operator[](const char* ky) { return Find(ky); }
+ void startIterate(); //iterator-like initialization
+ char* NextKey(); //returns next valid key in the table (NULL if no more)
+ OBJ* NextData(); //returns next valid hash[].data
+ OBJ* NextData(char*& nextkey); //returns next valid hash[].data
+ //or NULL if no more
+ //nextkey is SET to the corresponding key
+ GHashEntry* NextEntry() { //returns a pointer to a GHashEntry
+ int pos=fCurrentEntry;
+ while (pos<fCapacity && hash[pos].hash<0) pos++;
+ if (pos==fCapacity) {
+ fCurrentEntry=fCapacity;
+ return NULL;
+ }
+ else {
+ fCurrentEntry=pos+1;
+ return &hash[pos];
+ }
+ }
+ /// Clear all entries
+ void Clear();
+
+ /// Destructor
+ virtual ~GHash();
+};
//
//======================== method definitions ========================
//
/*
Notes:
- - The hash algorithm should yield a fCount in the range [0...GHash::EMPTY)
- GHash::EMPTY and GHash::UNUSED are needed for flag purposes.
- Since the algorithm doubles the table size when exceeding MAX_LOAD,
it would be prudent to keep MIN_LOAD less than 1/2 MAX_LOAD;
- otherwise, the algorithm might hip-hop between halving and doubling,
- which would be quite expensive!!
- - Not many people seem to know that hash tables don't have to be prime
- numbers; in fact, a table size of 2**n and odd probe distance are very
- easy to arrange, and this works just as well!
- - We store the hash key, so that 99.999% of the time we can compare hash numbers;
- only when hash numbers match do we need to compare keys.
- Thus, with a good hash function, the fCount of calls to strcmp() should be
+ otherwise, the algorithm might flip between halving and doubling!
+ - We store the key hash value so that 99.999% of the time we can compare hash numbers;
+ only when hash numbers match we need to compare keys.
+ - Thus with a good hash function the fCount of calls to strcmp() should be
roughly the same as the fCount of successful lookups.
- - The hash table should NEVER get full, or stuff will loop forever!!
-*/
+ */
// Initial table size (MUST be power of 2)
#define DEF_HASH_SIZE 32
@@ -141,6 +131,7 @@ public:
#define MAX_LOAD 80
// Minimum hash table load factor (%)
#define MIN_LOAD 10
+
// Probe Position [0..n-1]
#define HASH1(x,n) (((unsigned int)(x)*13)%(n))
// Probe Distance [1..n-1]
@@ -151,544 +142,462 @@ public:
/*******************************************************************************/
// Construct empty hash
template <class OBJ> GHash<OBJ>::GHash(GFreeProc* freeProc) {
- GMALLOC(hash, sizeof(GHashEntry)*DEF_HASH_SIZE);
- fCurrentEntry=-1;
- fFreeProc=freeProc;
- lastkeyptr=NULL;
- for (uint i=0; i<DEF_HASH_SIZE; i++)
- hash[i].hash=-1; //this will be an indicator for 'empty' entries
- fCapacity=DEF_HASH_SIZE;
- fCount=0;
- }
+ GMALLOC(hash, sizeof(GHashEntry)*DEF_HASH_SIZE);
+ fCurrentEntry=-1;
+ fFreeProc=freeProc;
+ lastkeyptr=NULL;
+ for (uint i=0; i<DEF_HASH_SIZE; i++)
+ hash[i].hash=-1; //this will be an indicator for 'empty' entries
+ fCapacity=DEF_HASH_SIZE;
+ fCount=0;
+}
template <class OBJ> GHash<OBJ>::GHash(bool doFree) {
- GMALLOC(hash, sizeof(GHashEntry)*DEF_HASH_SIZE);
- fCurrentEntry=-1;
- lastkeyptr=NULL;
- fFreeProc = (doFree)?&DefaultFreeProc : NULL;
- for (uint i=0; i<DEF_HASH_SIZE; i++)
- hash[i].hash=-1; //this will be an indicator for 'empty' entries
- fCapacity=DEF_HASH_SIZE;
- fCount=0;
- }
+ GMALLOC(hash, sizeof(GHashEntry)*DEF_HASH_SIZE);
+ fCurrentEntry=-1;
+ lastkeyptr=NULL;
+ fFreeProc = (doFree)?&DefaultFreeProc : NULL;
+ for (uint i=0; i<DEF_HASH_SIZE; i++)
+ hash[i].hash=-1; //this will be an indicator for 'empty' entries
+ fCapacity=DEF_HASH_SIZE;
+ fCount=0;
+}
// Resize table
-template <class OBJ> void GHash<OBJ>::Resize(int m){
- int i,n,p,x,h;
- GHashEntry *k;
- GASSERT(fCount<=fCapacity);
- if(m<DEF_HASH_SIZE) m=DEF_HASH_SIZE;
- n=fCapacity;
- while((n>>2)>m) n>>=1; // Shrink until n/4 <= m
- while((n>>1)<m) n<<=1; // Grow until m <= n/2
- GASSERT(m<=(n>>1));
- GASSERT(DEF_HASH_SIZE<=n);
- if(n!=fCapacity){
- GASSERT(m<=n);
- GMALLOC(k, sizeof(GHashEntry)*n);
- for(i=0; i<n; i++) k[i].hash=-1;
- for(i=0; i<fCapacity; i++){
- h=hash[i].hash;
- if(0<=h){
- p=HASH1(h,n);
- GASSERT(0<=p && p<n);
- x=HASH2(h,n);
- GASSERT(1<=x && x<n);
- while(k[p].hash!=-1) p=(p+x)%n;
- GASSERT(k[p].hash<0);
- k[p]=hash[i];
- }
- }
- GFREE(hash);
- hash=k;
- fCapacity=n;
- }
- }
+template <class OBJ> void GHash<OBJ>::Resize(int m) {
+ int i,n,p,x,h;
+ GHashEntry *k;
+ GASSERT(fCount<=fCapacity);
+ if(m<DEF_HASH_SIZE) m=DEF_HASH_SIZE;
+ n=fCapacity;
+ while((n>>2)>m) n>>=1; // Shrink until n/4 <= m
+ while((n>>1)<m) n<<=1; // Grow until m <= n/2
+ GASSERT(m<=(n>>1));
+ GASSERT(DEF_HASH_SIZE<=n);
+ if(n!=fCapacity){
+ GASSERT(m<=n);
+ GMALLOC(k, sizeof(GHashEntry)*n);
+ for(i=0; i<n; i++) k[i].hash=-1;
+ for(i=0; i<fCapacity; i++){
+ h=hash[i].hash;
+ if(h>=0){
+ p=HASH1(h,n);
+ GASSERT(0<=p && p<n);
+ x=HASH2(h,n);
+ GASSERT(1<=x && x<n);
+ while(k[p].hash!=-1) p=(p+x)%n;
+ GASSERT(k[p].hash<0);
+ k[p]=hash[i];
+ }
+ }
+ GFREE(hash);
+ hash=k;
+ fCapacity=n;
+ }
+}
// add a new entry, or update it if it already exists
-template <class OBJ> OBJ* GHash<OBJ>::Add(const char* ky,
- OBJ* pdata, bool mrk){
- int p,i,x,h,n;
- if(!ky) GError("GHash::insert: NULL key argument.\n");
- GASSERT(fCount<fCapacity);
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- i=-1;
- n=fCapacity;
+template <class OBJ> OBJ* GHash<OBJ>::Add(const char* ky, OBJ* pdata) {
+ int p,i,x,h,n;
+ if(!ky) GError("GHash::insert: NULL key argument.\n");
+ GASSERT(fCount<fCapacity);
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ i=-1;
+ n=fCapacity;
#ifdef HASH_DBG_PRINT
- int iterations=0;
- int init_p=p;
- int init_x=x;
+ int iterations=0;
+ int init_p=p;
+ int init_x=x;
#endif
- while(n && hash[p].hash!=-1) {
- if ((i==-1)&&(hash[p].hash==-2)) i=p;
- if (hash[p].hash==h && strcmp(hash[p].key,ky)==0) {
- //replace hash data for this key!
- lastkeyptr=hash[p].key;
- OBJ* r = (OBJ*) hash[p].data;
- hash[p].data = (void*) pdata;
+ while(n && hash[p].hash!=-1) {
+ if ((i==-1)&&(hash[p].hash==-2)) i=p;
+ if (hash[p].hash==h && strcmp(hash[p].key,ky)==0) {
+ //replace hash data for this key!
+ lastkeyptr=hash[p].key;
+ OBJ* r = (OBJ*) hash[p].data;
+ hash[p].data = (void*) pdata;
#ifdef HASH_DBG_PRINT
- GMessage("Add.R\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
- ky, h,init_p,init_x, iterations, fCount, fCapacity);
+ GMessage("Add.R\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
+ ky, h,init_p,init_x, iterations, fCount, fCapacity);
#endif
- //return (OBJ*)hash[p].data;
- return r;
- }
- p=(p+x)%fCapacity;
- n--;
- }
- if(i==-1) i=p;
+ return r;
+ }
+ p=(p+x)%fCapacity;
+ n--;
+ }
+ if(i==-1) i=p;
#ifdef HASH_DBG_PRINT
- GMessage("Add.N\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
- ky, h,init_p,init_x, iterations, fCount, fCapacity);
+ GMessage("Add.N\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
+ ky, h,init_p,init_x, iterations, fCount, fCapacity);
#endif
- GTRACE(("GHash::insert: key=\"%s\"\n",ky));
- //GMessage("GHash::insert: key=\"%s\"\n",ky);
- GASSERT(0<=i && i<fCapacity);
- GASSERT(hash[i].hash<0);
- hash[i].hash=h;
- hash[i].mark=mrk;
- hash[i].key=Gstrdup(ky);
- hash[i].keyalloc=true;
- lastkeyptr=hash[i].key;
- hash[i].data= (void*) pdata;
- fCount++;
- if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
- GASSERT(fCount<fCapacity);
- return pdata;
- }
+ GTRACE(("GHash::insert: key=\"%s\"\n",ky));
+ //GMessage("GHash::insert: key=\"%s\"\n",ky);
+ GASSERT(0<=i && i<fCapacity);
+ GASSERT(hash[i].hash<0);
+ hash[i].hash=h;
+ hash[i].key=Gstrdup(ky);
+ hash[i].keyalloc=true;
+ lastkeyptr=hash[i].key;
+ hash[i].data= (void*) pdata;
+ fCount++;
+ if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
+ GASSERT(fCount<fCapacity);
+ return pdata;
+}
-/*
- int p,i,x,h;
- if(!ky) GError("GHash::insert: NULL key argument.\n");
- GASSERT(fCount<fCapacity);
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- if (checkReplace(ky, pdata, p, i, h, x)) {
- return (OBJ*)hash[p].data;
- }
- GTRACE(("GHash::insert: key=\"%s\"\n",ky));
- //GMessage("GHash::insert: key=\"%s\"\n",ky);
- GASSERT(0<=i && i<fCapacity);
- GASSERT(hash[i].hash<0);
- hash[i].hash=h;
- hash[i].mark=mrk;
- hash[i].key=Gstrdup(ky);
- hash[i].keyalloc=true;
- lastkeyptr=hash[i].key;
- hash[i].data= (void*) pdata;
- fCount++;
- if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
- GASSERT(fCount<fCapacity);
- return pdata;
- }
-*/
-template <class OBJ> OBJ* GHash<OBJ>::fAdd(const char* ky,
- OBJ* pdata){
- int p,i,x,h,n;
- if(!ky) GError("GHash::insert: NULL key argument.\n");
- GASSERT(fCount<fCapacity);
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- i=-1;
- n=fCapacity;
+template <class OBJ> OBJ* GHash<OBJ>::fAdd(const char* ky, OBJ* pdata) {
+ int p,i,x,h,n;
+ if(!ky) GError("GHash::insert: NULL key argument.\n");
+ GASSERT(fCount<fCapacity);
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ i=-1;
+ n=fCapacity;
#ifdef HASH_DBG_PRINT
- int iterations=0;
- int init_p=p;
- int init_x=x;
+ int iterations=0;
+ int init_p=p;
+ int init_x=x;
#endif
- while(n && hash[p].hash!=-1) {
- if ((i==-1)&&(hash[p].hash==-2)) i=p;
- if (hash[p].hash==h && strcmp(hash[p].key,ky)==0) {
- //replace hash data for this key!
- lastkeyptr=hash[p].key;
- if (FREEDATA) (*fFreeProc)(hash[p].data);
- hash[p].data = (void*) pdata;
+ while(n && hash[p].hash!=-1) {
+ if ((i==-1)&&(hash[p].hash==-2)) i=p;
+ if (hash[p].hash==h && strcmp(hash[p].key,ky)==0) {
+ //replace hash data for this key!
+ lastkeyptr=hash[p].key;
+ if (FREEDATA) (*fFreeProc)(hash[p].data);
+ hash[p].data = (void*) pdata;
#ifdef HASH_DBG_PRINT
- GMessage("Add.R\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
- ky, h,init_p,init_x, iterations, fCount, fCapacity);
+ GMessage("Add.R\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
+ ky, h,init_p,init_x, iterations, fCount, fCapacity);
#endif
- return pdata;
- }
- p=(p+x)%fCapacity;
+ return pdata;
+ }
+ p=(p+x)%fCapacity;
#ifdef HASH_DBG_PRINT
- ++iterations;
+ ++iterations;
#endif
- n--;
- }
- if(i==-1) i=p;
+ n--;
+ }
+ if(i==-1) i=p;
#ifdef HASH_DBG_PRINT
- GMessage("Add.N\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
- ky, h,init_p,init_x, iterations, fCount, fCapacity);
+ GMessage("Add.N\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
+ ky, h,init_p,init_x, iterations, fCount, fCapacity);
#endif
- GTRACE(("GHash::insert: key=\"%s\"\n",ky));
- //GMessage("GHash::insert: key=\"%s\"\n",ky);
- GASSERT(0<=i && i<fCapacity);
- GASSERT(hash[i].hash<0);
- hash[i].hash=h;
- hash[i].mark=false;
- hash[i].key=Gstrdup(ky);
- hash[i].keyalloc=true;
- lastkeyptr=hash[i].key;
- hash[i].data= (void*) pdata;
- fCount++;
- if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
- GASSERT(fCount<fCapacity);
- return pdata;
- }
-
-
-
-template <class OBJ> OBJ* GHash<OBJ>::shkAdd(const char* ky,
- OBJ* pdata,bool mrk){
- int p,i,x,h,n;
- if(!ky) GError("GHash::insert: NULL key argument.\n");
- GASSERT(fCount<fCapacity);
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- i=-1;
- n=fCapacity;
- while(n && hash[p].hash!=-1){
- if((i==-1)&&(hash[p].hash==-2)) i=p;
- if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
- //replace hash data for this key!
- lastkeyptr=hash[p].key;
- hash[p].data = (void*) pdata;
- return (OBJ*)hash[p].data;
- }
- p=(p+x)%fCapacity;
- n--;
- }
- if(i==-1) i=p;
- GTRACE(("GHash::insert: key=\"%s\"\n",ky));
- //GMessage("GHash::insert: key=\"%s\"\n",ky);
- GASSERT(0<=i && i<fCapacity);
- GASSERT(hash[i].hash<0);
- hash[i].hash=h;
- hash[i].mark=mrk;
- hash[i].key=(char *)ky;
- lastkeyptr=hash[i].key;
- hash[i].keyalloc=false;
- hash[i].data= (void*) pdata;
- fCount++;
- if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
- GASSERT(fCount<fCapacity);
- return pdata;
- }
+ GTRACE(("GHash::insert: key=\"%s\"\n",ky));
+ //GMessage("GHash::insert: key=\"%s\"\n",ky);
+ GASSERT(0<=i && i<fCapacity);
+ GASSERT(hash[i].hash<0);
+ hash[i].hash=h;
+ hash[i].key=Gstrdup(ky);
+ hash[i].keyalloc=true;
+ lastkeyptr=hash[i].key;
+ hash[i].data= (void*) pdata;
+ fCount++;
+ if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
+ GASSERT(fCount<fCapacity);
+ return pdata;
+}
+template <class OBJ> OBJ* GHash<OBJ>::shkAdd(const char* ky, OBJ* pdata) {
+ int p,i,x,h,n;
+ if(!ky) GError("GHash::insert: NULL key argument.\n");
+ GASSERT(fCount<fCapacity);
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ i=-1;
+ n=fCapacity;
+ while(n && hash[p].hash!=-1){
+ if((i==-1)&&(hash[p].hash==-2)) i=p;
+ if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
+ //replace hash data for this key!
+ lastkeyptr=hash[p].key;
+ hash[p].data = (void*) pdata;
+ return (OBJ*)hash[p].data;
+ }
+ p=(p+x)%fCapacity;
+ n--;
+ }
+ if(i==-1) i=p;
+ GTRACE(("GHash::insert: key=\"%s\"\n",ky));
+ //GMessage("GHash::insert: key=\"%s\"\n",ky);
+ GASSERT(0<=i && i<fCapacity);
+ GASSERT(hash[i].hash<0);
+ hash[i].hash=h;
+ hash[i].key=(char *)ky;
+ lastkeyptr=hash[i].key;
+ hash[i].keyalloc=false;
+ hash[i].data= (void*) pdata;
+ fCount++;
+ if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
+ GASSERT(fCount<fCapacity);
+ return pdata;
+}
// Add or replace entry
-template <class OBJ> OBJ* GHash<OBJ>::Replace(const char* ky, OBJ* pdata, bool mrk){
- int p,i,x,h,n;
- if(!ky){ GError("GHash::replace: NULL key argument.\n"); }
- GASSERT(fCount<fCapacity);
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- i=-1;
- n=fCapacity;
- while(n && hash[p].hash!=-1){
- if((i==-1)&&(hash[p].hash==-2)) i=p;
- if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
- if(hash[p].mark<=mrk){
- GTRACE(("GHash::replace: %08x: replacing: \"%s\"\n",this,ky));
- if (FREEDATA) (*fFreeProc)(hash[p].data);
- hash[p].mark=mrk;
- hash[p].data=pdata;
- }
- return hash[p].data;
- }
- p=(p+x)%fCapacity;
- n--;
- }
- if(i==-1) i=p;
- GTRACE(("GHash::replace: %08x: inserting: \"%s\"\n",this,ky));
- GASSERT(0<=i && i<fCapacity);
- GASSERT(hash[i].hash<0);
- hash[i].hash=h;
- hash[i].mark=mrk;
- hash[i].key=Gstrdup(ky);
- hash[i].data=pdata;
- fCount++;
- if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
- GASSERT(fCount<fCapacity);
- return pdata;
- }
+template <class OBJ> OBJ* GHash<OBJ>::Replace(const char* ky, OBJ* pdata){
+ int p,i,x,h,n;
+ if(!ky){ GError("GHash::replace: NULL key argument.\n"); }
+ GASSERT(fCount<fCapacity);
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ i=-1;
+ n=fCapacity;
+ while(n && hash[p].hash!=-1){
+ if((i==-1)&&(hash[p].hash==-2)) i=p;
+ if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
+ GTRACE(("GHash::replace: %08x: replacing: \"%s\"\n",this,ky));
+ if (FREEDATA) (*fFreeProc)(hash[p].data);
+ hash[p].data=pdata;
+ return hash[p].data;
+ }
+ p=(p+x)%fCapacity;
+ n--;
+ }
+ if(i==-1) i=p;
+ GTRACE(("GHash::replace: %08x: inserting: \"%s\"\n",this,ky));
+ GASSERT(0<=i && i<fCapacity);
+ GASSERT(hash[i].hash<0);
+ hash[i].hash=h;
+ hash[i].key=Gstrdup(ky);
+ hash[i].data=pdata;
+ fCount++;
+ if((100*fCount)>=(MAX_LOAD*fCapacity)) Resize(fCount);
+ GASSERT(fCount<fCapacity);
+ return pdata;
+}
// Remove entry
template <class OBJ> OBJ* GHash<OBJ>::Remove(const char* ky){
- int p,x,h,n;
- if(!ky){ GError("GHash::remove: NULL key argument.\n"); }
- OBJ* removed=NULL;
- if(0<fCount){
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- GASSERT(fCount<fCapacity);
- n=fCapacity;
- while(n && hash[p].hash!=-1){
- if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
- GTRACE(("GHash::remove: %08x removing: \"%s\"\n",this,ky));
- hash[p].hash=-2;
- hash[p].mark=false;
- if (hash[p].keyalloc) GFREE((hash[p].key));
- if (FREEDATA) (*fFreeProc)(hash[p].data);
- else removed=(OBJ*)hash[p].data;
- hash[p].key=NULL;
- hash[p].data=NULL;
- fCount--;
- if((100*fCount)<=(MIN_LOAD*fCapacity)) Resize(fCount);
- GASSERT(fCount<fCapacity);
- return removed;
- }
- p=(p+x)%fCapacity;
- n--;
- }
- }
- return removed;
- }
+ int p,x,h,n;
+ if(!ky){ GError("GHash::remove: NULL key argument.\n"); }
+ OBJ* removed=NULL;
+ if(0<fCount){
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ GASSERT(fCount<fCapacity);
+ n=fCapacity;
+ while(n && hash[p].hash!=-1){
+ if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
+ GTRACE(("GHash::remove: %08x removing: \"%s\"\n",this,ky));
+ hash[p].hash=-2;
+ if (hash[p].keyalloc) GFREE((hash[p].key));
+ if (FREEDATA) (*fFreeProc)(hash[p].data);
+ else removed=(OBJ*)hash[p].data;
+ hash[p].key=NULL;
+ hash[p].data=NULL;
+ fCount--;
+ if((100*fCount)<=(MIN_LOAD*fCapacity)) Resize(fCount);
+ GASSERT(fCount<fCapacity);
+ return removed;
+ }
+ p=(p+x)%fCapacity;
+ n--;
+ }
+ }
+ return removed;
+}
// Find entry
template <class OBJ> bool GHash<OBJ>::hasKey(const char* ky) {
- int p,x,h,n;
- if(!ky){ GError("GHash::find: NULL key argument.\n"); }
- if(0<fCount){
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- GASSERT(fCount<fCapacity);
- n=fCapacity;
- while(n && hash[p].hash!=-1){
- if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
- return true;
- }
- p=(p+x)%fCapacity;
- n--;
- }
- }
- return false;
+ int p,x,h,n;
+ if(!ky){ GError("GHash::find: NULL key argument.\n"); }
+ if(0<fCount){
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ GASSERT(fCount<fCapacity);
+ n=fCapacity;
+ while(n && hash[p].hash!=-1){
+ if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
+ return true;
+ }
+ p=(p+x)%fCapacity;
+ n--;
+ }
+ }
+ return false;
}
template <class OBJ> OBJ* GHash<OBJ>::Find(const char* ky, char** keyptr){
- int p,x,h,n;
- if(!ky){ GError("GHash::find: NULL key argument.\n"); }
- if (fCount==0) return NULL;
- h=GSTR_HASH(ky);
- GASSERT(0<=h);
- p=HASH1(h,fCapacity);
- GASSERT(0<=p && p<fCapacity);
- x=HASH2(h,fCapacity);
- GASSERT(1<=x && x<fCapacity);
- GASSERT(fCount<fCapacity);
- n=fCapacity;
+ int p,x,h,n;
+ if(!ky){ GError("GHash::find: NULL key argument.\n"); }
+ if (fCount==0) return NULL;
+ h=GSTR_HASH(ky);
+ GASSERT(0<=h);
+ p=HASH1(h,fCapacity);
+ GASSERT(0<=p && p<fCapacity);
+ x=HASH2(h,fCapacity);
+ GASSERT(1<=x && x<fCapacity);
+ GASSERT(fCount<fCapacity);
+ n=fCapacity;
#ifdef HASH_DBG_PRINT
- int iterations=0;
- int init_p=p;
- int init_x=x;
+ int iterations=0;
+ int init_p=p;
+ int init_x=x;
#endif
- while(n && hash[p].hash!=-1){
- if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
- if (keyptr!=NULL) *keyptr = hash[p].key;
+ while(n && hash[p].hash!=-1){
+ if(hash[p].hash==h && strcmp(hash[p].key,ky)==0){
+ if (keyptr!=NULL) *keyptr = hash[p].key;
#ifdef HASH_DBG_PRINT
- GMessage("Found \t%s\t%d,%d,%d\t%d\t%d\t%d\n",
- ky, h,init_p,init_x, iterations, fCount, fCapacity);
+ GMessage("Found \t%s\t%d,%d,%d\t%d\t%d\t%d\n",
+ ky, h,init_p,init_x, iterations, fCount, fCapacity);
#endif
- return (OBJ*)hash[p].data;
- }
- p=(p+x)%fCapacity;
- n--;
+ return (OBJ*)hash[p].data;
+ }
+ p=(p+x)%fCapacity;
+ n--;
#ifdef HASH_DBG_PRINT
- ++iterations;
+ ++iterations;
#endif
- }
+ }
#ifdef HASH_DBG_PRINT
- GMessage("Nfound\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
- ky, h,init_p,init_x, iterations, fCount, fCapacity);
+ GMessage("Nfound\t%s\t%d,%d,%d\t%d\t%d\t%d\n",
+ ky, h,init_p,init_x, iterations, fCount, fCapacity);
#endif
- return NULL;
- }
+ return NULL;
+}
template <class OBJ> void GHash<OBJ>::startIterate() {// initialize a key iterator; call
- fCurrentEntry=0;
+ fCurrentEntry=0;
}
template <class OBJ> char* GHash<OBJ>::NextKey() {
- int pos=fCurrentEntry;
- while (pos<fCapacity && hash[pos].hash<0) pos++;
- if (pos==fCapacity) {
- fCurrentEntry=fCapacity;
- return NULL;
- }
- else {
- fCurrentEntry=pos+1;
- return hash[pos].key;
- }
+ int pos=fCurrentEntry;
+ while (pos<fCapacity && hash[pos].hash<0) pos++;
+ if (pos==fCapacity) {
+ fCurrentEntry=fCapacity;
+ return NULL;
+ }
+ else {
+ fCurrentEntry=pos+1;
+ return hash[pos].key;
+ }
}
template <class OBJ> OBJ* GHash<OBJ>::NextData() {
- int pos=fCurrentEntry;
- while (pos<fCapacity && hash[pos].hash<0) pos++;
- if (pos==fCapacity) {
- fCurrentEntry=fCapacity;
- return NULL;
- }
- else {
- fCurrentEntry=pos+1;
- return (OBJ*)hash[pos].data;
- }
+ int pos=fCurrentEntry;
+ while (pos<fCapacity && hash[pos].hash<0) pos++;
+ if (pos==fCapacity) {
+ fCurrentEntry=fCapacity;
+ return NULL;
+ }
+ else {
+ fCurrentEntry=pos+1;
+ return (OBJ*)hash[pos].data;
+ }
}
template <class OBJ> OBJ* GHash<OBJ>::NextData(char* &nextkey) {
- int pos=fCurrentEntry;
- while (pos<fCapacity && hash[pos].hash<0) pos++;
- if (pos==fCapacity) {
- fCurrentEntry=fCapacity;
- nextkey=NULL;
- return NULL;
- }
- else {
- fCurrentEntry=pos+1;
- nextkey=hash[pos].key;
- return (OBJ*)hash[pos].data;
- }
+ int pos=fCurrentEntry;
+ while (pos<fCapacity && hash[pos].hash<0) pos++;
+ if (pos==fCapacity) {
+ fCurrentEntry=fCapacity;
+ nextkey=NULL;
+ return NULL;
+ }
+ else {
+ fCurrentEntry=pos+1;
+ nextkey=hash[pos].key;
+ return (OBJ*)hash[pos].data;
+ }
}
// Get first non-empty entry
template <class OBJ> int GHash<OBJ>::First() const {
- int pos=0;
- while(pos<fCapacity){ if(0<=hash[pos].hash) break; pos++; }
- GASSERT(fCapacity<=pos || 0<=hash[pos].hash);
- return pos;
- }
+ int pos=0;
+ while(pos<fCapacity){ if(0<=hash[pos].hash) break; pos++; }
+ GASSERT(fCapacity<=pos || 0<=hash[pos].hash);
+ return pos;
+}
// Get last non-empty entry
template <class OBJ> int GHash<OBJ>::Last() const {
- int pos=fCapacity-1;
- while(0<=pos){ if(0<=hash[pos].hash) break; pos--; }
- GASSERT(pos<0 || 0<=hash[pos].hash);
- return pos;
- }
+ int pos=fCapacity-1;
+ while(0<=pos){ if(0<=hash[pos].hash) break; pos--; }
+ GASSERT(pos<0 || 0<=hash[pos].hash);
+ return pos;
+}
// Find next valid entry
template <class OBJ> int GHash<OBJ>::Next(int pos) const {
- GASSERT(0<=pos && pos<fCapacity);
- while(++pos <= fCapacity-1){ if(0<=hash[pos].hash) break; }
- GASSERT(fCapacity<=pos || 0<=hash[pos].hash);
- return pos;
- }
+ GASSERT(0<=pos && pos<fCapacity);
+ while(++pos <= fCapacity-1){ if(0<=hash[pos].hash) break; }
+ GASSERT(fCapacity<=pos || 0<=hash[pos].hash);
+ return pos;
+}
// Find previous valid entry
template <class OBJ> int GHash<OBJ>::Prev(int pos) const {
- GASSERT(0<=pos && pos<fCapacity);
- while(--pos >= 0){ if(0<=hash[pos].hash) break; }
- GASSERT(pos<0 || 0<=hash[pos].hash);
- return pos;
- }
+ GASSERT(0<=pos && pos<fCapacity);
+ while(--pos >= 0){ if(0<=hash[pos].hash) break; }
+ GASSERT(pos<0 || 0<=hash[pos].hash);
+ return pos;
+}
// Remove all
template <class OBJ> void GHash<OBJ>::Clear(){
- int i;
- for(i=0; i<fCapacity; i++){
- if(hash[i].hash>=0){
- if (hash[i].keyalloc) GFREE((hash[i].key));
- if (FREEDATA)
- (*fFreeProc)(hash[i].data);
- }
- }
- GFREE(hash);
- GMALLOC(hash, sizeof(GHashEntry)*DEF_HASH_SIZE);
- //reinitialize it
- for (i=0; i<DEF_HASH_SIZE; i++)
- hash[i].hash=-1; //this will be an indicator for 'empty' entries
- fCapacity=DEF_HASH_SIZE;
- fCount=0;
- }
-
-
-// Save data
-/*
-void GHash::Save(Stream& store) const {
- Object::save(store);
- store << fCapacity;
- store << fCount;
- for(int i=0; i<fCapacity; i++){
- store << hash[i].hash;
- if(hash[i].hash>=0){
- uint len=strlen(hash[i].key);
- store << len;
- store << hash[i].mark;
- store.save(hash[i].key,len);
- }
- }
- }
-
-
-// Load data
-void GHash::Load(Stream& store){
- Object::load(store);
- store >> fCapacity;
- store >> fCount;
- for(int i=0; i<fCapacity; i++){
- store >> hash[i].hash;
- if(hash[i].hash>=0){
- uint len;
- store >> len;
- store >> hash[i].mark;
- GMALLOC(hash[i].key,len+1);
- store.load(hash[i].key,len);
- hash[i].key[len]='\0';
- }
- }
- }
-*/
+ int i;
+ for(i=0; i<fCapacity; i++){
+ if(hash[i].hash>=0){
+ if (hash[i].keyalloc) GFREE((hash[i].key));
+ if (FREEDATA)
+ (*fFreeProc)(hash[i].data);
+ }
+ }
+ GFREE(hash);
+ GMALLOC(hash, sizeof(GHashEntry)*DEF_HASH_SIZE);
+ //reinitialize it
+ for (i=0; i<DEF_HASH_SIZE; i++)
+ hash[i].hash=-1; //this will be an indicator for 'empty' entries
+ fCapacity=DEF_HASH_SIZE;
+ fCount=0;
+}
// Destroy table
template <class OBJ> GHash<OBJ>::~GHash(){
- for(int i=0; i<fCapacity; i++){
- if(hash[i].hash>=0){
- if (hash[i].keyalloc) GFREE((hash[i].key));
- if (FREEDATA) (*fFreeProc)(hash[i].data);
- }
- }
- GFREE(hash);
- }
+ for(int i=0; i<fCapacity; i++){
+ if(hash[i].hash>=0){
+ if (hash[i].keyalloc) GFREE((hash[i].key));
+ if (FREEDATA) (*fFreeProc)(hash[i].data);
+ }
+ }
+ GFREE(hash);
+}
class GStrSet:public GHash<int> {
protected:
=====================================
GIntHash.hh
=====================================
@@ -228,7 +228,7 @@ public:
};
-// from code.google.com/p/smhasher/wiki/MurmurHash3
+// -- from code.google.com/p/smhasher/wiki/MurmurHash3
inline uint32_t integerHash(uint32_t h)
{
h ^= h >> 16;
@@ -239,15 +239,19 @@ inline uint32_t integerHash(uint32_t h)
return h;
}
-// from code.google.com/p/smhasher/wiki/MurmurHash3
-inline uint64_t integerHash(uint64_t k)
-{
- k ^= k >> 33;
- k *= 0xff51afd7ed558ccd;
- k ^= k >> 33;
- k *= 0xc4ceb9fe1a85ec53;
- k ^= k >> 33;
- return k;
+inline int32_t int_hashfunc_Wang(int32_t key) {
+ key += ~(key << 15);
+ key ^= (key >> 10);
+ key += (key << 3);
+ key ^= (key >> 6);
+ key += ~(key << 11);
+ key ^= (key >> 16);
+ return key;
+}
+
+// -- from Heng Li's khash.h:
+inline uint32_t int64_hashfunc(uint64_t k) {
+ return (uint32_t)(k>>33^k^k<<11);
}
#define GIHASH_FIRST_CELL(hash) (m_cells + ((hash) & (m_arraySize - 1)))
=====================================
GResUsage.cpp
=====================================
@@ -0,0 +1,278 @@
+#include "GResUsage.h"
+
+#if defined(__APPLE__) && defined(__MACH__)
+ #include <AvailabilityMacros.h>
+ #include <sys/resource.h>
+ #include <mach/mach.h>
+ #include <mach/task_info.h>
+
+ #ifndef MAC_OS_X_VERSION_10_12
+ #define MAC_OS_X_VERSION_10_12 101200
+ #endif
+ #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
+ #define G_gettime(s) clock_gettime(CLOCK_MONOTONIC, &s);
+ #else
+ #include <mach/mach_time.h>
+ #define MACHGT_NANO (+1.0E-9)
+ #define MACHGT_GIGA UINT64_C(1000000000)
+ void mach_gettime( struct timespec* t) {
+ // be more careful in a multithreaded environement
+ static double machgt_timebase = 0.0;
+ static uint64_t machgt_timestart = 0;
+ if (!machgt_timestart) {
+ mach_timebase_info_data_t tb;
+ tb.numer=0;tb.denom=0;
+ mach_timebase_info(&tb);
+ machgt_timebase = tb.numer;
+ machgt_timebase /= tb.denom;
+ machgt_timestart = mach_absolute_time();
+ }
+ ;
+ double diff = (mach_absolute_time() - machgt_timestart) * machgt_timebase;
+ t->tv_sec = diff * MACHGT_NANO;
+ t->tv_nsec = diff - (t->tv_sec * MACHGT_GIGA);
+ }
+ #define G_gettime(s) mach_gettime(&s)
+ #endif
+#else
+ #ifdef _WIN32
+ //Windows implementation:
+ #include <psapi.h>
+ LARGE_INTEGER
+ getFILETIMEoffset() {
+ SYSTEMTIME s;
+ FILETIME f;
+ LARGE_INTEGER t;
+ s.wYear = 1970; s.wMonth = 1; s.wDay = 1;
+ s.wHour = 0; s.wMinute = 0; s.wSecond = 0;
+ s.wMilliseconds = 0;
+ SystemTimeToFileTime(&s, &f);
+ t.QuadPart = f.dwHighDateTime;
+ t.QuadPart <<= 32;
+ t.QuadPart |= f.dwLowDateTime;
+ return (t);
+ }
+
+ static void usage_to_timeval(FILETIME *ft, struct timeval *tv) {
+ ULARGE_INTEGER time;
+ time.LowPart = ft->dwLowDateTime;
+ time.HighPart = ft->dwHighDateTime;
+
+ tv->tv_sec = time.QuadPart / 10000000;
+ tv->tv_usec = (time.QuadPart % 10000000) / 10;
+ }
+
+ //implementation of getrusage for Windows
+ int getrusage(int who, rusage *usage) {
+ FILETIME creation_time, exit_time, kernel_time, user_time;
+ PROCESS_MEMORY_COUNTERS pmc;
+
+ memset(usage, 0, sizeof(rusage));
+
+ if (who == RUSAGE_SELF) {
+ if (!GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
+ &kernel_time, &user_time)) {
+ GMessage("Error: GetProcessTimes() failed!\n");
+ return -1;
+ }
+
+ if (!GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
+ GMessage("Error: GetProcessMemoryInfo() failed!\n");
+ return -1;
+ }
+
+ usage_to_timeval(&kernel_time, &usage->ru_stime);
+ usage_to_timeval(&user_time, &usage->ru_utime);
+ usage->ru_majflt = pmc.PageFaultCount;
+ usage->ru_maxrss = pmc.PeakWorkingSetSize / 1024;
+ return 0;
+ } else if (who == RUSAGE_THREAD) {
+ if (!GetThreadTimes(GetCurrentThread(), &creation_time, &exit_time,
+ &kernel_time, &user_time)) {
+ GMessage("Error: GetThreadTimes() failed!\n");
+ return -1;
+ }
+ usage_to_timeval(&kernel_time, &usage->ru_stime);
+ usage_to_timeval(&user_time, &usage->ru_utime);
+ return 0;
+ } else {
+ return -1;
+ }
+ }
+
+
+ void win_gettime(struct timespec* ts) {
+ LARGE_INTEGER t;
+ FILETIME f;
+ double microseconds;
+ static LARGE_INTEGER offset;
+ static double frequencyToMicroseconds;
+ static int initialized = 0;
+ static BOOL usePerformanceCounter = 0;
+
+ if (!initialized) {
+ LARGE_INTEGER performanceFrequency;
+ initialized = 1;
+ usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency);
+ if (usePerformanceCounter) {
+ QueryPerformanceCounter(&offset);
+ frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.;
+ } else {
+ offset = getFILETIMEoffset();
+ frequencyToMicroseconds = 10.;
+ }
+ }
+ if (usePerformanceCounter) QueryPerformanceCounter(&t);
+ else {
+ GetSystemTimeAsFileTime(&f);
+ t.QuadPart = f.dwHighDateTime;
+ t.QuadPart <<= 32;
+ t.QuadPart |= f.dwLowDateTime;
+ }
+
+ t.QuadPart -= offset.QuadPart;
+ microseconds = (double)t.QuadPart / frequencyToMicroseconds;
+ t.QuadPart = microseconds;
+ ts->tv_sec = t.QuadPart / 1000000;
+ ts->tv_nsec = (t.QuadPart % 1000000)*1000;
+ }
+ #define G_gettime(s) win_gettime(&s)
+ #else //assume Linux compatible
+ #define G_gettime(s) clock_gettime(CLOCK_MONOTONIC, &s)
+ #endif
+#endif
+
+// Returns the peak (maximum so far) resident set size (physical
+// memory use) measured in bytes
+size_t getPeakMemUse() {
+#if defined(_WIN32)
+ // -- Windows
+ PROCESS_MEMORY_COUNTERS info;
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
+ return (size_t)info.PeakWorkingSetSize/1024;
+#else // defined(__unix__) || defined(__unix) || defined(unix) || (defined(__APPLE__) && defined(__MACH__))
+ // asssume BSD, Linux, or OSX
+ struct rusage rusage;
+ getrusage( RUSAGE_SELF, &rusage );
+ #if defined(__APPLE__) && defined(__MACH__)
+ return (size_t)rusage.ru_maxrss/1024;
+ #else
+ return (size_t)(rusage.ru_maxrss);
+ #endif
+#endif
+}
+
+/**
+ * Returns the current resident set size (physical memory use) measured
+ * in bytes, or zero if the value cannot be determined on this OS.
+ */
+size_t getCurrentMemUse() {
+#if defined(_WIN32)
+ // -- Windows
+ PROCESS_MEMORY_COUNTERS info;
+ GetProcessMemoryInfo( GetCurrentProcess( ), &info, sizeof(info) );
+ return (size_t)info.WorkingSetSize;
+
+#elif defined(__APPLE__) && defined(__MACH__)
+#if defined MACH_TASK_BASIC_INFO
+ struct mach_task_basic_info info;
+#else
+ struct task_basic_info info;
+ #define MACH_TASK_BASIC_INFO TASK_BASIC_INFO
+ #define MACH_TASK_BASIC_INFO_COUNT TASK_BASIC_INFO_COUNT
+#endif
+
+ mach_msg_type_number_t infoCount = MACH_TASK_BASIC_INFO_COUNT;
+ if ( task_info( mach_task_self( ), MACH_TASK_BASIC_INFO,
+ (task_info_t)&info, &infoCount ) != KERN_SUCCESS )
+ return (size_t)0L; // Can't access?
+ return (size_t)info.resident_size;
+#else
+ //-- assume Linux
+ long progsize = 0L;
+ FILE* fp = NULL;
+ if ( (fp = fopen( "/proc/self/statm", "r" )) == NULL )
+ return (size_t)0L; /* Can't open? */
+ //if ( fscanf( fp, "%*s%ld", &rss ) != 1 )
+ if ( fscanf( fp, "%*s%ld", &progsize ) != 1 )
+ {
+ fclose( fp );
+ return (size_t)0L; /* Can't read? */
+ }
+ fclose( fp );
+ int page_size=sysconf(_SC_PAGESIZE);
+ return ((size_t)progsize * (size_t)page_size)/1024;
+#endif
+}
+
+// get_mem_usage(double &, double &) - takes two doubles by reference,
+// attempts to read the system-dependent data for a process' virtual memory
+// size and resident set size, and return the results in KB.
+//
+// On failure, returns 0.0, 0.0
+void printMemUsage(FILE* fout) {
+ double rs= getCurrentMemUse();
+ rs/=1024;
+ fprintf(fout, "Resident Size: %6.1fMB\n", rs);
+}
+
+double get_usecTime() {
+ struct timespec start_ts;
+ G_gettime(start_ts);
+ return (((double)start_ts.tv_sec)*1000000.0 + ((double)start_ts.tv_nsec)/1000.0);
+}
+
+double GResUsage::start() {
+ started=true;
+ stopped=false;
+ start_mem=getCurrentMemUse();
+ getrusage(RUSAGE_SELF, &start_ru);
+ G_gettime(start_ts);
+ double tm=start_ts.tv_sec*1000000.0 + start_ts.tv_nsec/1000.0;
+ return tm;
+}
+
+double GResUsage::stop() {
+ if (started!=true)
+ GError("Error: calling GResUsage::stop() without starting it first?\n");
+ stopped=true;
+ G_gettime(stop_ts);
+ getrusage(RUSAGE_SELF, &stop_ru);
+ double tm=stop_ts.tv_sec*1000000.0 + stop_ts.tv_nsec/1000.0;
+ stop_mem=getCurrentMemUse();
+ return tm;
+}
+
+#define RUSAGE_STOPCHECK
+
+void GResUsage::stopCheck(const char* s) {
+ if (!started || !stopped)
+ GError("Error: GResUsage::%s() cannot be used before start&stop\n", s);
+}
+
+double GResUsage::elapsed() {
+ stopCheck("elapsed");
+ double st=start_ts.tv_sec*1000000.0 + start_ts.tv_nsec/1000.0;
+ double et=stop_ts.tv_sec*1000000.0 + stop_ts.tv_nsec/1000.0;
+ return (et-st);
+}
+
+double GResUsage::u_elapsed() {
+ stopCheck("u_elapsed");
+ double st=start_ru.ru_utime.tv_sec*1000000.0 + start_ru.ru_utime.tv_usec;
+ double et=stop_ru.ru_utime.tv_sec*1000000.0 + stop_ru.ru_utime.tv_usec;
+ return (et-st);
+}
+
+double GResUsage::s_elapsed() {
+ stopCheck("s_elapsed");
+ double st=start_ru.ru_stime.tv_sec*1000000.0 + start_ru.ru_stime.tv_usec;
+ double et=stop_ru.ru_stime.tv_sec*1000000.0 + stop_ru.ru_stime.tv_usec;
+ return (et-st);
+}
+
+size_t GResUsage::memoryUsed() {
+ stopCheck("memoryUsed");
+ return (stop_mem-start_mem);
+}
+
=====================================
GResUsage.h
=====================================
@@ -0,0 +1,53 @@
+#ifndef _GRESUSAGE_
+#define _GRESUSAGE_
+#include "GBase.h"
+#if defined _WIN32 && ! defined __CYGWIN__
+ #define RUSAGE_SELF 0 /* calling process */
+ #define RUSAGE_CHILDREN -1 /* terminated child processes */
+ #define RUSAGE_THREAD 1
+
+ struct rusage {
+ struct timeval ru_utime; /* user time used */
+ struct timeval ru_stime; /* system time used */
+ long ru_maxrss;
+ long ru_majflt;
+ };
+#else
+ #include <sys/resource.h>
+#endif
+#include <time.h>
+
+// report the memory usage of the current process, rounded to kilobytes
+size_t getCurrentMemUse(); //current memory usage of the program (RSS)
+size_t getPeakMemUse(); //maximum memory usage (RSS) for the program until now
+
+void printMemUsage(FILE* fout=stderr);
+
+double get_usecTime();
+
+class GResUsage {
+ protected:
+ bool started;
+ bool stopped;
+ size_t start_mem;
+ size_t stop_mem;
+ struct rusage start_ru;
+ struct rusage stop_ru;
+ struct timespec start_ts;
+ struct timespec stop_ts;
+ void stopCheck(const char* s);
+ public:
+ GResUsage(bool do_start=false):started(false),
+ stopped(false), start_mem(0), stop_mem(0) {
+ if (do_start) start();
+ }
+
+ double start(); //returns microseconds time using clock_gettime(CLOCK_MONOTONIC
+ double stop(); //stop the stopwatch, returns the current time in microseconds
+ double elapsed(); //microseconds elapsed between start and stop (wallclock time)
+ double u_elapsed(); //microseconds of user time elapsed
+ double s_elapsed(); //microseconds of system time elapsed
+ size_t memoryUsed(); //memory increase between start and stop in KB (can be negative)
+};
+
+#endif
=====================================
GThreads.cpp
=====================================
@@ -1,6 +1,6 @@
/*
Copyright (c) 2010 Marcus Geelnard
-(with minor modifications by Geo Pertea)
+(with minor modifications and naming changes by Geo Pertea)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
=====================================
GThreads.h
=====================================
@@ -2,16 +2,13 @@
#define _GTHREADS_
/*
-GThread - multi-platform threads utility class
-This is heavily based on the source code of TinyThread++ 1.0 package
-by Marcus Geelnard (with only minor modifications),
-so all merits for the code go to Marcus, except the bugs which
-were probably introduced by me.
+GThread - multi-platform thread management utility class
+This code is taken from the TinyThread++ 1.0 package
+by Marcus Geelnard (with only very minor alterations and
+naming changes).
-Original Copyright notice below
-*/
-
-/*
+Original Copyright notice follows:
+----
Copyright (c) 2010 Marcus Geelnard
This software is provided 'as-is', without any express or implied
=====================================
Makefile
=====================================
@@ -95,20 +95,23 @@ endif
.PHONY : all
-all: mdtest
+all: htest
+#mdtest
nodebug: all
release: all
debug: all
-OBJS := GBase.o GStr.o GArgs.o
+OBJS := GBase.o GStr.o GArgs.o GResUsage.o
version: ; @echo "GCC Version is: "$(GCC_MAJOR)":"$(GCC_MINOR)":"$(GCC_SUB)
@echo "> GCC Opt. string is: "$(GCC45OPTS)
+htest: $(OBJS) htest.o GHash.hh
+ ${LINKER} ${LDFLAGS} $(GCC45OPTS) $(GCC45OPTMAIN) -o $@ ${filter-out %.a %.so, $^} ${LIBS}
mdtest: $(OBJS) mdtest.o
${LINKER} ${LDFLAGS} $(GCC45OPTS) $(GCC45OPTMAIN) -o $@ ${filter-out %.a %.so, $^} ${LIBS}
# target for removing all object files
.PHONY : clean
clean::
- @${RM} $(OBJS) *.o mdtest$(EXE)
+ @${RM} $(OBJS) *.o mdtest$(EXE) htest$(EXE)
@${RM} core.*
=====================================
README.md
=====================================
@@ -1,9 +1,8 @@
-## GCLib - Genomic C++/Code Library
-This is an eclectic gathering of (mostly) C++ code which I am using for some of my bioinformatics projects.
-The main idea is to provide lean code and efficient data structures, trying to avoid too many code
-dependencies of heavy libraries while minimizing production cycles (and this also implies a decent compile/build time --
-I am looking at you, bloated configure scripts and lengthy compile times of Boost code or other heavy C++ template code..).
+## GCLib - Genomic C++ Library
+This is an eclectic collection of basic C++ code (functions, classes, templates) which is shared between a few of my bioinformatics projects. The main idea was to provide a core collection of data structures, trying to avoid unnecessary code dependencies of other heavy libraries, while minimizing build time.
+
+I had started gathering this code even before the C++ STL had been fully adopted as a cross-platform "standard". Even STL itself seems a bit on the heavy side (and keeps growing) compared to what I need in practice for many of my C++ projects, so often times I prefer to just use these simpler and leaner C++ classes and templates to provide most common data structures needed for my projects.
+
+## Build/Install
+Do not build. Do not install. This is not meant to be built into an object library, it's a simple _source code library_ for other projects to include and link statically into the final executable(s). The makefile included here is just for simple, extemporaneous tests I occasionally perform as new functionality is added to this code collection.
-I had started gathering this code even before the C++ STL had been fully adopted as a cross-platform "standard", and because
-I also think that STL by itself is a bit heavier for most of my C++ needs, I do prefer to use simpler&leaner C++
-classes or templates for basic strings, containers, basic algorithms etc.
=====================================
gcdb.cpp
=====================================
@@ -1,14 +1,14 @@
#include "gcdb.h"
#include <errno.h>
-#ifdef __WIN32__
-/* m m a p === from imagick sources
+#ifdef _WIN32
+/* mmap on Windows (from imagick sources)
% Method mmap emulates the Unix method of the same name.
% The format of the mmap method is:
% void *mmap(char *address,size_t length,int protection,
% int access,int file,off_t offset)
*/
-void *mmap(char *address,size_t length,int protection,int access,
+void *mmap(char *address, size_t length, int protection, int access,
int file, off_t offset) {
void *map;
HANDLE handle;
@@ -65,7 +65,7 @@ void *mmap(char *address,size_t length,int protection,int access,
% > length: The length of the binary large object.
%
*/
-int munmap(void *map,size_t length) {
+int munmap(void *map, size_t length) {
if (!UnmapViewOfFile(map))
return(-1);
return(0);
@@ -580,7 +580,7 @@ GCdbWrite::GCdbWrite(int afd) {
}
GCdbWrite::GCdbWrite(char* afname) {
-#ifdef __WIN32__
+#ifdef _WIN32
fd = open(afname,O_WRONLY | O_TRUNC | O_BINARY | O_CREAT, S_IREAD|S_IWRITE);
#else
fd = open(afname,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT, 0664);
@@ -604,7 +604,7 @@ GCdbWrite::GCdbWrite(char* afname) {
GCdbWrite::~GCdbWrite() {
cdbuf->flush();
- #ifndef __WIN32__
+ #ifndef _WIN32
/* NFS silliness */
if (fsync(fd) == -1)
GError("GCdbWrite: Error at fsync() for file '%s'\n",
@@ -828,7 +828,7 @@ GCdbRead::GCdbRead(char* afname):map(NULL) {
gcvt_endian_setup();
findstart();
- #ifdef __WIN32__
+ #ifdef _WIN32
fd = open(afname, O_RDONLY|O_BINARY);
#else
fd = open(afname, O_RDONLY);
=====================================
gcdb.h
=====================================
@@ -4,7 +4,7 @@
#include <stddef.h>
#include <fcntl.h>
-#ifdef __WIN32__
+#ifdef _WIN32
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_READWRITE 3
@@ -99,9 +99,10 @@ class GCDBuffer {
//=====================================================
//------------- cdb utils -------------------
//=====================================================
-#ifndef __WIN32__
+#ifndef _WIN32
extern int errno;
#endif
+
extern int error_intr;
extern int error_nomem;
extern int error_proto;
=====================================
gsocket.cpp
=====================================
@@ -1,7 +1,7 @@
#include "gsocket.h"
#include <errno.h> // For errno
-#ifdef WIN32
+#ifdef _WIN32
static bool initialized = false;
#endif
@@ -33,7 +33,7 @@ static void fillAddr(const GStr &address, unsigned short port,
// GSocket Code
GSocket::GSocket(int type, int protocol) {
- #ifdef WIN32
+ #ifdef _WIN32
if (!initialized) {
WORD wVersionRequested;
WSADATA wsaData;
@@ -53,7 +53,7 @@ GSocket::GSocket(int type, int protocol) {
}
GSocket::~GSocket() {
- #ifdef WIN32
+ #ifdef _WIN32
::closesocket(sockDesc);
#else
::close(sockDesc);
@@ -106,7 +106,7 @@ void GSocket::setLocalAddressAndPort(const GStr &localAddress,
}
void GSocket::cleanUp() {
- #ifdef WIN32
+ #ifdef _WIN32
if (WSACleanup() != 0) {
GSocketErr("WSACleanup() failed");
}
@@ -125,7 +125,7 @@ unsigned short GSocket::resolveService(const GStr &service,
// GCommSocket Code
void GCommSocket::setTimeout(int microsecs) {
- #ifdef WIN32
+ #ifdef _WIN32
DWORD timeout = microsecs;
setsockopt(sockDesc, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
#else
@@ -241,7 +241,7 @@ void GUDPSocket::disconnect() {
// Try to disconnect
if (::connect(sockDesc, (sockaddr *) &nullAddr, sizeof(nullAddr)) < 0) {
- #ifdef WIN32
+ #ifdef _WIN32
if (errno != WSAEAFNOSUPPORT) {
#else
if (errno != EAFNOSUPPORT) {
=====================================
gsocket.h
=====================================
@@ -3,7 +3,7 @@
#include "GBase.h"
#include "GStr.h"
-#ifdef WIN32
+#ifdef _WIN32
#include <winsock.h> // For socket(), connect(), send(), and recv()
typedef int socklen_t;
typedef char raw_type; // Type used for raw data on this platform
=====================================
gstopwatch.cpp
=====================================
@@ -1,6 +1,6 @@
#include "gstopwatch.h"
-#ifdef __WIN32__
+#ifdef _WIN32
double GStopWatch::LIToSecs( LARGE_INTEGER & L) {
return ((double)L.QuadPart /(double)frequency.QuadPart);
}
=====================================
gstopwatch.h
=====================================
@@ -2,7 +2,7 @@
#define __GSTOPWATCH_H
#include "GBase.h"
-#ifdef __WIN32__
+#ifdef _WIN32
typedef struct {
LARGE_INTEGER start;
LARGE_INTEGER stop;
=====================================
htest.cpp
=====================================
@@ -0,0 +1,104 @@
+#include "GBase.h"
+#include "GArgs.h"
+#include "GStr.h"
+#include "GVec.hh"
+#include "GHash.hh"
+#include "GResUsage.h"
+
+#define USAGE "Usage:\n\
+ htest textfile.. \n\
+ \n\
+ "
+static void strFreeProc(pointer item) {
+ GFREE(item);
+}
+
+struct HStrData {
+ int cmd; // 0=add, 1=remove, 2=clear
+ GStr str;
+ HStrData(char* s=NULL, int c=0):cmd(c), str(s) { }
+};
+
+int loadStrings(FILE* f, GPVec<HStrData>& strgsuf, GPVec<HStrData>& strgs) {
+ int num=0;
+ GLineReader lr(f);
+ char* line=NULL;
+ while ((line=lr.nextLine())!=NULL) {
+ int len=strlen(line);
+ if (len<4) continue;
+ if (strcmp(line, "HCLR")==0) {
+ strgs.Add(new HStrData(NULL, 2));
+ strgsuf.Add(new HStrData(NULL, 2));
+ continue;
+ }
+ if (startsWith(line, "RM ")) {
+ strgsuf.Add(new HStrData(line+3,1) );
+ line[len-3]=0;
+ strgs.Add(new HStrData(line+3,1));
+ continue;
+ }
+ strgsuf.Add(new HStrData(line));
+ line[len-3]=0;
+ strgs.Add(new HStrData(line));
+ num++;
+ } //while line
+ return num;
+}
+
+int main(int argc, char* argv[]) {
+ GPVec<HStrData> strs;
+ GPVec<HStrData> sufstrs;
+ GHash<int> thash;
+ GHash<int> sufthash;
+ strs.setFreeItem(strFreeProc);
+ sufstrs.setFreeItem(strFreeProc);
+ //GArgs args(argc, argv, "hg:c:s:t:o:p:help;genomic-fasta=COV=PID=seq=out=disable-flag;test=");
+ GArgs args(argc, argv, "h");
+ //fprintf(stderr, "Command line was:\n");
+ //args.printCmdLine(stderr);
+ args.printError(USAGE, true);
+ if (args.getOpt('h') || args.getOpt("help")) GMessage(USAGE);
+ int numargs=args.startNonOpt();
+ if (numargs>0) {
+ char* a=NULL;
+ FILE* f=NULL;
+ int total=0;
+ while ((a=args.nextNonOpt())) {
+ f=fopen(a, "r");
+ if (f==NULL) GError("Error: could not open file %s !\n", a);
+ int num=loadStrings(f, sufstrs, strs);
+ total+=num;
+ }
+ GResUsage swatch;
+ //timing starts here
+ GMessage("----------------- loading no-suffix strings ----------------\n");
+ swatch.start();
+ for (int i=0;i<strs.Count();i++) {
+ switch (strs[i]->cmd) {
+ case 0:thash.fAdd(strs[i]->str.chars(), new int(1)); break;
+ case 1:thash.Remove(strs[i]->str.chars()); break;
+ case 2:thash.Clear(); break;
+ }
+ }
+ swatch.stop();
+ GMessage("Elapsed time (microseconds): %.0f us\n", swatch.elapsed());
+ GMessage(" user time: %.0f us\n", swatch.u_elapsed());
+ GMessage(" system time: %.0f us\n", swatch.s_elapsed());
+ // timing here
+
+ GMessage("----------------- loading suffix strings ----------------\n");
+ swatch.start();
+ for (int i=0;i<sufstrs.Count();i++) {
+ switch (sufstrs[i]->cmd) {
+ case 0:sufthash.fAdd(sufstrs[i]->str.chars(), new int(1)); break;
+ case 1:sufthash.Remove(sufstrs[i]->str.chars()); break;
+ case 2:sufthash.Clear(); break;
+ }
+ }
+ swatch.stop();
+ GMessage("Elapsed time (microseconds): %.0f us\n", swatch.elapsed());
+ GMessage(" user time: %.0f us\n", swatch.u_elapsed());
+ GMessage(" system time: %.0f us\n", swatch.s_elapsed());
+
+ }
+}
View it on GitLab: https://salsa.debian.org/med-team/libgclib/-/commit/34c651e55e08e96c3cdd8a7bc8367d43ab609582
--
View it on GitLab: https://salsa.debian.org/med-team/libgclib/-/commit/34c651e55e08e96c3cdd8a7bc8367d43ab609582
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20200601/43e8c8e3/attachment-0001.html>
More information about the debian-med-commit
mailing list