| 265 | # repeatedly |
| 266 | |
| 267 | def __chain_b(self): |
| 268 | # Because isjunk is a user-defined (not C) function, and we test |
| 269 | # for junk a LOT, it's important to minimize the number of calls. |
| 270 | # Before the tricks described here, __chain_b was by far the most |
| 271 | # time-consuming routine in the whole module! If anyone sees |
| 272 | # Jim Roskind, thank him again for profile.py -- I never would |
| 273 | # have guessed that. |
| 274 | # The first trick is to build b2j ignoring the possibility |
| 275 | # of junk. I.e., we don't call isjunk at all yet. Throwing |
| 276 | # out the junk later is much cheaper than building b2j "right" |
| 277 | # from the start. |
| 278 | b = self.b |
| 279 | self.b2j = b2j = {} |
| 280 | |
| 281 | for i, elt in enumerate(b): |
| 282 | indices = b2j.setdefault(elt, []) |
| 283 | indices.append(i) |
| 284 | |
| 285 | # Purge junk elements |
| 286 | self.bjunk = junk = set() |
| 287 | isjunk = self.isjunk |
| 288 | if isjunk: |
| 289 | for elt in b2j.keys(): |
| 290 | if isjunk(elt): |
| 291 | junk.add(elt) |
| 292 | for elt in junk: # separate loop avoids separate list of keys |
| 293 | del b2j[elt] |
| 294 | |
| 295 | # Purge popular elements that are not junk |
| 296 | self.bpopular = popular = set() |
| 297 | n = len(b) |
| 298 | if self.autojunk and n >= 200: |
| 299 | ntest = n // 100 + 1 |
| 300 | for elt, idxs in b2j.items(): |
| 301 | if len(idxs) > ntest: |
| 302 | popular.add(elt) |
| 303 | for elt in popular: # ditto; as fast for 1% deletion |
| 304 | del b2j[elt] |
| 305 | |
| 306 | def find_longest_match(self, alo=0, ahi=None, blo=0, bhi=None): |
| 307 | """Find longest matching block in a[alo:ahi] and b[blo:bhi]. |