Show More
@@ -386,53 +386,11 b' class dirstate(object):' | |||
|
386 | 386 | raise |
|
387 | 387 | |
|
388 | 388 | def _read(self): |
|
389 | self._map = dirstatemap(self._ui, self._opener, self._root) | |
|
390 | ||
|
391 | 389 | # ignore HG_PENDING because identity is used only for writing |
|
392 | 390 | self._identity = util.filestat.frompath( |
|
393 | 391 | self._opener.join(self._filename)) |
|
394 | try: | |
|
395 |
|
|
|
396 | try: | |
|
397 | st = fp.read() | |
|
398 | finally: | |
|
399 | fp.close() | |
|
400 | except IOError as err: | |
|
401 | if err.errno != errno.ENOENT: | |
|
402 | raise | |
|
403 | return | |
|
404 | if not st: | |
|
405 | return | |
|
406 | ||
|
407 | if util.safehasattr(parsers, 'dict_new_presized'): | |
|
408 | # Make an estimate of the number of files in the dirstate based on | |
|
409 | # its size. From a linear regression on a set of real-world repos, | |
|
410 | # all over 10,000 files, the size of a dirstate entry is 85 | |
|
411 | # bytes. The cost of resizing is significantly higher than the cost | |
|
412 | # of filling in a larger presized dict, so subtract 20% from the | |
|
413 | # size. | |
|
414 | # | |
|
415 | # This heuristic is imperfect in many ways, so in a future dirstate | |
|
416 | # format update it makes sense to just record the number of entries | |
|
417 | # on write. | |
|
418 | self._map._map = parsers.dict_new_presized(len(st) / 71) | |
|
419 | ||
|
420 | # Python's garbage collector triggers a GC each time a certain number | |
|
421 | # of container objects (the number being defined by | |
|
422 | # gc.get_threshold()) are allocated. parse_dirstate creates a tuple | |
|
423 | # for each file in the dirstate. The C version then immediately marks | |
|
424 | # them as not to be tracked by the collector. However, this has no | |
|
425 | # effect on when GCs are triggered, only on what objects the GC looks | |
|
426 | # into. This means that O(number of files) GCs are unavoidable. | |
|
427 | # Depending on when in the process's lifetime the dirstate is parsed, | |
|
428 | # this can get very expensive. As a workaround, disable GC while | |
|
429 | # parsing the dirstate. | |
|
430 | # | |
|
431 | # (we cannot decorate the function directly since it is in a C module) | |
|
432 | parse_dirstate = util.nogc(parsers.parse_dirstate) | |
|
433 | p = parse_dirstate(self._map._map, self._map.copymap, st) | |
|
434 | if not self._map._dirtyparents: | |
|
435 | self._map.setparents(*p) | |
|
392 | self._map = dirstatemap(self._ui, self._opener, self._root) | |
|
393 | self._map.read() | |
|
436 | 394 | |
|
437 | 395 | def invalidate(self): |
|
438 | 396 | '''Causes the next access to reread the dirstate. |
@@ -1399,3 +1357,47 b' class dirstatemap(object):' | |||
|
1399 | 1357 | def setparents(self, p1, p2): |
|
1400 | 1358 | self._parents = (p1, p2) |
|
1401 | 1359 | self._dirtyparents = True |
|
1360 | ||
|
1361 | def read(self): | |
|
1362 | try: | |
|
1363 | fp = self._opendirstatefile() | |
|
1364 | try: | |
|
1365 | st = fp.read() | |
|
1366 | finally: | |
|
1367 | fp.close() | |
|
1368 | except IOError as err: | |
|
1369 | if err.errno != errno.ENOENT: | |
|
1370 | raise | |
|
1371 | return | |
|
1372 | if not st: | |
|
1373 | return | |
|
1374 | ||
|
1375 | if util.safehasattr(parsers, 'dict_new_presized'): | |
|
1376 | # Make an estimate of the number of files in the dirstate based on | |
|
1377 | # its size. From a linear regression on a set of real-world repos, | |
|
1378 | # all over 10,000 files, the size of a dirstate entry is 85 | |
|
1379 | # bytes. The cost of resizing is significantly higher than the cost | |
|
1380 | # of filling in a larger presized dict, so subtract 20% from the | |
|
1381 | # size. | |
|
1382 | # | |
|
1383 | # This heuristic is imperfect in many ways, so in a future dirstate | |
|
1384 | # format update it makes sense to just record the number of entries | |
|
1385 | # on write. | |
|
1386 | self._map = parsers.dict_new_presized(len(st) / 71) | |
|
1387 | ||
|
1388 | # Python's garbage collector triggers a GC each time a certain number | |
|
1389 | # of container objects (the number being defined by | |
|
1390 | # gc.get_threshold()) are allocated. parse_dirstate creates a tuple | |
|
1391 | # for each file in the dirstate. The C version then immediately marks | |
|
1392 | # them as not to be tracked by the collector. However, this has no | |
|
1393 | # effect on when GCs are triggered, only on what objects the GC looks | |
|
1394 | # into. This means that O(number of files) GCs are unavoidable. | |
|
1395 | # Depending on when in the process's lifetime the dirstate is parsed, | |
|
1396 | # this can get very expensive. As a workaround, disable GC while | |
|
1397 | # parsing the dirstate. | |
|
1398 | # | |
|
1399 | # (we cannot decorate the function directly since it is in a C module) | |
|
1400 | parse_dirstate = util.nogc(parsers.parse_dirstate) | |
|
1401 | p = parse_dirstate(self._map, self.copymap, st) | |
|
1402 | if not self._dirtyparents: | |
|
1403 | self.setparents(*p) |
General Comments 0
You need to be logged in to leave comments.
Login now