1313/// @brief The maximum filepath length of a file in the index.
1414#define INDEXMAXFP 512
1515
16- /// @brief Hashes the filepath string into an index bucket.
16+ /// @brief Hashes the filepath string.
17+ /// @note 64-bit FNV-1a implementation is used for hashing.
1718/// @param fp The filepath string to hash
18- /// @return The index bucket number.
19- static int indexhash (const char * fp ) {
20- int h = 0 ;
21- for (const char * p = fp ; * p != '\0' ; p ++ ) h = (h << 5 ) - h + * p ;
22- if (h < 0 ) h = - h ;
23- return h % INDEXBUCKETS ;
19+ /// @return The hashed value of the filepath.
20+ static uint64_t indexhash (const char * fp ) {
21+ uint64_t hash = 14695981039346656037u ;// FNV offset basis
22+ while (* fp ) {
23+ hash ^= (uint8_t ) * fp ;// XOR byte into hash
24+ hash *= 1099511628211 ;// FNV prime
25+ fp ++ ;
26+ }
27+ return hash ;
2428}
2529
30+ /// @def indexbucket
31+ /// @brief Maps and casts the hash value to a bucket index via the last N bits
32+ /// (where N is the number of buckets, `INDEXBUCKETS`).
33+ #define indexbucket (hash ) ((int) (hash & INDEXBUCKETSMASK))
34+
2635struct inode_s * indexfind (const struct index_s * idx , const char * fp ) {
27- struct inode_s * head = idx -> buckets [indexhash (fp )];
36+ const uint64_t hash = indexhash (fp );
37+ struct inode_s * head = idx -> buckets [indexbucket (hash )];
2838 while (head != NULL ) {
2939 if (strcmp (head -> fp , fp ) == 0 ) return head ;
3040 head = head -> next ;
@@ -72,8 +82,11 @@ int indexread(struct index_s* idx, FILE* s) {
7282 & b .st .fsze ) == 3 ) {
7383 // duplicate the string onto the heap
7484 if ((b .fp = strdup (b .fp )) == NULL ) return -1 ;
75- if (indexput (idx , b ) == NULL ) return -1 ;
76- b .fp = fp ;
85+ if (indexput (idx , b ) == NULL ) {
86+ free (b .fp );
87+ return -1 ;
88+ }
89+ b .fp = fp ;// reset to static buffer
7790 }
7891
7992 return 0 ;
@@ -93,10 +106,11 @@ static struct inode_s* indexprepend(struct inode_s* idx,
93106}
94107
95108struct inode_s * indexput (struct index_s * idx , const struct inode_s node ) {
96- struct inode_s * bucket = idx -> buckets [indexhash (node .fp )];
109+ const int bi = indexbucket (indexhash (node .fp ));
110+ struct inode_s * bucket = idx -> buckets [bi ];
97111 struct inode_s * head = indexprepend (bucket , node );
98112 if (head == NULL ) return NULL ;
99- idx -> buckets [indexhash ( node . fp ) ] = head ;
113+ idx -> buckets [bi ] = head ;
100114 idx -> size ++ ;
101115 return head ;
102116}
0 commit comments