//-------+---------+---------+---------+---------+---------+---------+--------= // // File: diag_hash.h // //---------- #ifndef diag_hash_H // (prevent multiple inclusion) #define diag_hash_H // other files #include "utilities.h" // utility stuff #include "sequences.h" // sequence stuff // establish ownership of global variables #ifdef diag_hash_owner #define global #else #define global extern #endif // debugging defines //#define noSeedHitQueue // if this is defined, the seed hit queue is // .. NOT used for finding twin seed hits (they // .. are found using other techniques) //---------- // // diagonal hash-- // (see diag_hash.c for details) // // Helpful formulas: // diag = pos1 - pos2 diagNumber(pos1,pos2) // pos1 = diag + pos2 diagToPos1(diag,pos2) // pos2 = pos1 - diag diagToPos2(diag,pos1) // //---------- // note that diagHashSize must be a power of two #ifdef puny_diag_hash // test case; very small hash forces collisions #define diagHashSize ((u32) 16) #else #ifdef tiny_diag_hash // test case; small hash forces collisions #define diagHashSize ((u32) 1024) #else #ifdef huge_diag_hash // test case; no collisions on 1M vs 1M #define diagHashSize ((u32) 4194304) #else #ifdef diag_hash_size // override; beware: diag_hash_size must be a power of 2 #define diagHashSize ((u32) diag_hash_size) #else // normal case #define diagHashSize ((u32) 65536) #endif #endif #endif #endif #define diagNumber(pos1,pos2) (((sgnpos)(pos1))-((sgnpos)(pos2))) #define hashedDiag(pos1,pos2) ((diagNumber(pos1,pos2)) & (diagHashSize-1)) #define diagToPos1(diag,pos2) (((unspos)(diag))+((unspos)(pos2))) #define diagToPos2(diag,pos1) (((unspos)(pos1))-((unspos)(diag))) //--- initialized variables for this module --- #ifdef diag_hash_owner unspos* diagEnd = NULL; // arrays (indexed by 0..diagHashSize-1) to unspos* diagStart = NULL; // .. track the extent of discovered hits on a sgnpos* diagActual = NULL; // .. given diagonal (modulo diagHashSize); // .. no values in any of these arrays are valid // .. if the corresponding value in diagEnd is // .. hashInactiveEnd; diagEnd (in addition to // .. indicating validity) records the end of // .. of the most recent hit or extension, as a // .. position in sequence 2; diagStart records // .. the start of the most recent hit (or // .. series of overlapping hits in some cases); // .. diagActual records the actual diagonal // .. represented (this is used only to // .. detect/resolve collisions) u32* diagActive = NULL; // array (indexed by 0..numdiagActive-1) of int numDiagActive; // .. positions in diagEnd and diagStart that // .. have a non-zero value //--- external access to the variables, for other modules --- #else extern unspos* diagEnd; extern unspos* diagStart; extern sgnpos* diagActual; extern u32* diagActive; extern int numDiagActive; #endif // macros for accessing the hash #define activate_hashed_diag(h) diagActive[numDiagActive++] = h; #define hashInactiveEnd ((unspos) -1) //---------- // // seed hit queue-- // (see diag_hash.c for details) // //---------- #ifndef noSeedHitQueue #define defaultSeedHitQueueSize 256*1024 typedef struct shqhit // seed hit queue element { u64 prevHit; // the number of the most recent seed hit on // .. this hashed diagonal; 0 indicates no hit int isBlock; // true => this is an end-of-extension // false => this is a seed hit unspos pos2; // the position of the seed hit in sequence 2; // .. this is the position following the end of // .. the hit (or extension) sgnpos diag; // the diagonal containing the seed hit } shqhit; #ifdef diag_hash_owner int seedHitQueueSize = 0; // (N) number of entries in seedHitQueue[] shqhit* seedHitQueue = NULL; // the most recent N hits, as a cyclic queue u64* lastSeedHit = NULL; // the number of the most recent seed hit on // .. each hashed diagonal; lastSeedHit mod N // .. is the index into seedHitQueue[] of that // .. seed hit; 0 indicates no hit u32 seedHitQueueColumns = 0;// the desired number of sequence 2 positions // .. covered by the queue; this is only used // .. to generate a warning if we drop below it u64 seedHitNum; // identifying number of the most recent seed // .. hit (the first seed hit is number N+1) #else extern int seedHitQueueSize; extern shqhit* seedHitQueue; extern u64* lastSeedHit; extern u32 seedHitQueueColumns; extern u64 seedHitNum; #endif #endif // not noSeedHitQueue //---------- // // prototypes for routines in diag_hash.c // //---------- void empty_diag_hash (void); void free_diag_hash (void); #ifndef noSeedHitQueue void _enqueue_seed_hit (unspos pos1, unspos pos2, int isBlock); #ifndef diag_hash_owner #define enqueue_seed_hit(pos1,pos2,isBlock) \ if (seedHitQueueSize > 0) _enqueue_seed_hit(pos1,pos2,isBlock) #endif #endif // not noSeedHitQueue #undef global #endif // diag_hash_H