1030434acSRandall Stewart #ifndef __tailq_hash__ 2030434acSRandall Stewart #define __tailq_hash__ 3030434acSRandall Stewart 4030434acSRandall Stewart /* Must be powers of 2 */ 5030434acSRandall Stewart #define MAX_HASH_ENTRIES 128 6030434acSRandall Stewart #define SEQ_BUCKET_SIZE 262144 7030434acSRandall Stewart /* 8030434acSRandall Stewart * The max seq range that can be stored is 9030434acSRandall Stewart * 64 x 262144 or 16Meg. We have one extra slot 10030434acSRandall Stewart * for fall-over but must keep it so we never have 11030434acSRandall Stewart * wrap in hashing over valid other entries. 12030434acSRandall Stewart */ 13030434acSRandall Stewart #define MAX_ALLOWED_SEQ_RANGE (SEQ_BUCKET_SIZE * (MAX_HASH_ENTRIES-1)) 14030434acSRandall Stewart 15030434acSRandall Stewart struct tailq_hash { 16030434acSRandall Stewart uint32_t min; 17030434acSRandall Stewart uint32_t max; 18030434acSRandall Stewart uint32_t count; 19*e18b97bdSRandall Stewart struct rack_sendmap *rsm_min; 20*e18b97bdSRandall Stewart struct rack_sendmap *rsm_max; 21*e18b97bdSRandall Stewart struct rack_head ht[MAX_HASH_ENTRIES]; 22030434acSRandall Stewart }; 23030434acSRandall Stewart 24030434acSRandall Stewart struct rack_sendmap * 25030434acSRandall Stewart tqhash_min(struct tailq_hash *hs); 26030434acSRandall Stewart 27030434acSRandall Stewart struct rack_sendmap * 28030434acSRandall Stewart tqhash_max(struct tailq_hash *hs); 29030434acSRandall Stewart 30030434acSRandall Stewart int 31030434acSRandall Stewart tqhash_empty(struct tailq_hash *hs); 32030434acSRandall Stewart 33030434acSRandall Stewart struct rack_sendmap * 34030434acSRandall Stewart tqhash_find(struct tailq_hash *hs, uint32_t seq); 35030434acSRandall Stewart 36030434acSRandall Stewart struct rack_sendmap * 37030434acSRandall Stewart tqhash_next(struct tailq_hash *hs, struct rack_sendmap *rsm); 38030434acSRandall Stewart 39030434acSRandall Stewart struct rack_sendmap * 40030434acSRandall Stewart tqhash_prev(struct tailq_hash *hs, struct rack_sendmap *rsm); 41030434acSRandall Stewart 42030434acSRandall Stewart #define REMOVE_TYPE_CUMACK 1 /* Cumack moved */ 43030434acSRandall Stewart #define REMOVE_TYPE_MERGE 2 /* Merging two blocks */ 44030434acSRandall Stewart #define REMOVE_TYPE_FINI 3 /* The connection is over */ 45030434acSRandall Stewart 46030434acSRandall Stewart void 47030434acSRandall Stewart tqhash_remove(struct tailq_hash *hs, struct rack_sendmap *rsm, int type); 48030434acSRandall Stewart 49030434acSRandall Stewart int 50030434acSRandall Stewart tqhash_insert(struct tailq_hash *hs, struct rack_sendmap *rsm); 51030434acSRandall Stewart 52030434acSRandall Stewart void 53030434acSRandall Stewart tqhash_init(struct tailq_hash *hs); 54030434acSRandall Stewart 55030434acSRandall Stewart int 56030434acSRandall Stewart tqhash_trim(struct tailq_hash *hs, uint32_t th_ack); 57030434acSRandall Stewart 58*e18b97bdSRandall Stewart void 59*e18b97bdSRandall Stewart tqhash_update_end(struct tailq_hash *hs, struct rack_sendmap *rsm, 60*e18b97bdSRandall Stewart uint32_t th_ack); 61*e18b97bdSRandall Stewart 62030434acSRandall Stewart 63030434acSRandall Stewart #define TQHASH_FOREACH(var, head) \ 64030434acSRandall Stewart for ((var) = tqhash_min((head)); \ 65030434acSRandall Stewart (var); \ 66030434acSRandall Stewart (var) = tqhash_next((head), (var))) 67030434acSRandall Stewart 68030434acSRandall Stewart #define TQHASH_FOREACH_FROM(var, head, fvar) \ 69030434acSRandall Stewart for ((var) = ((fvar) ? (fvar) : tqhash_min((head))); \ 70030434acSRandall Stewart (var); \ 71030434acSRandall Stewart (var) = tqhash_next((head), (var))) 72030434acSRandall Stewart 73030434acSRandall Stewart #define TQHASH_FOREACH_REVERSE_FROM(var, head) \ 74030434acSRandall Stewart for ((var) = ((var) ? (var) : tqhash_max((head))); \ 75030434acSRandall Stewart (var); \ 76030434acSRandall Stewart (var) = tqhash_prev((head), (var))) 77030434acSRandall Stewart 78030434acSRandall Stewart 79030434acSRandall Stewart #endif 80