| 138 | |
| 139 | |
| 140 | static void hash_search(int f,struct sum_struct *s, |
| 141 | struct map_struct *buf, OFF_T len) |
| 142 | { |
| 143 | OFF_T offset, aligned_offset, end; |
| 144 | int32 k, want_i, aligned_i, backup; |
| 145 | char sum2[MAX_DIGEST_LEN]; |
| 146 | uint32 s1, s2, sum; |
| 147 | int more; |
| 148 | schar *map; |
| 149 | |
| 150 | // prevent possible memory leaks |
| 151 | memset(sum2, 0, sizeof sum2); |
| 152 | |
| 153 | /* want_i is used to encourage adjacent matches, allowing the RLL |
| 154 | * coding of the output to work more efficiently. */ |
| 155 | want_i = 0; |
| 156 | |
| 157 | if (DEBUG_GTE(DELTASUM, 2)) { |
| 158 | rprintf(FINFO, "hash search b=%ld len=%s\n", |
| 159 | (long)s->blength, big_num(len)); |
| 160 | } |
| 161 | |
| 162 | k = (int32)MIN(len, (OFF_T)s->blength); |
| 163 | |
| 164 | map = (schar *)map_ptr(buf, 0, k); |
| 165 | |
| 166 | sum = get_checksum1((char *)map, k); |
| 167 | s1 = sum & 0xFFFF; |
| 168 | s2 = sum >> 16; |
| 169 | if (DEBUG_GTE(DELTASUM, 3)) |
| 170 | rprintf(FINFO, "sum=%.8x k=%ld\n", sum, (long)k); |
| 171 | |
| 172 | offset = aligned_offset = aligned_i = 0; |
| 173 | |
| 174 | end = len + 1 - s->sums[s->count-1].len; |
| 175 | |
| 176 | if (DEBUG_GTE(DELTASUM, 3)) { |
| 177 | rprintf(FINFO, "hash search s->blength=%ld len=%s count=%s\n", |
| 178 | (long)s->blength, big_num(len), big_num(s->count)); |
| 179 | } |
| 180 | |
| 181 | do { |
| 182 | int done_csum2 = 0; |
| 183 | uint32 hash_entry; |
| 184 | int32 i, *prev; |
| 185 | |
| 186 | if (DEBUG_GTE(DELTASUM, 4)) { |
| 187 | rprintf(FINFO, "offset=%s sum=%04x%04x\n", |
| 188 | big_num(offset), s2 & 0xFFFF, s1 & 0xFFFF); |
| 189 | } |
| 190 | |
| 191 | if (tablesize == TRADITIONAL_TABLESIZE) { |
| 192 | hash_entry = SUM2HASH2(s1,s2); |
| 193 | if ((i = hash_table[hash_entry]) < 0) |
| 194 | goto null_hash; |
| 195 | sum = (s1 & 0xffff) | (s2 << 16); |
| 196 | } else { |
| 197 | sum = (s1 & 0xffff) | (s2 << 16); |
no test coverage detected