~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-12-20 16:16:34 UTC
  • mfrom: (3123.5.18 hardlinks)
  • Revision ID: pqm@pqm.ubuntu.com-20071220161634-2kcjb650o21ydko4
Accelerate build_tree using similar workingtrees (abentley)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1322
1322
    return file_ids
1323
1323
 
1324
1324
 
1325
 
def build_tree(tree, wt):
 
1325
def build_tree(tree, wt, accelerator_tree=None):
1326
1326
    """Create working tree for a branch, using a TreeTransform.
1327
1327
    
1328
1328
    This function should be used on empty trees, having a tree root at most.
1335
1335
    - Otherwise, if the content on disk matches the content we are building,
1336
1336
      it is silently replaced.
1337
1337
    - Otherwise, conflict resolution will move the old file to 'oldname.moved'.
 
1338
 
 
1339
    :param tree: The tree to convert wt into a copy of
 
1340
    :param wt: The working tree that files will be placed into
 
1341
    :param accelerator_tree: A tree which can be used for retrieving file
 
1342
        contents more quickly than tree itself, i.e. a workingtree.  tree
 
1343
        will be used for cases where accelerator_tree's content is different.
1338
1344
    """
1339
1345
    wt.lock_tree_write()
1340
1346
    try:
1341
1347
        tree.lock_read()
1342
1348
        try:
1343
 
            return _build_tree(tree, wt)
 
1349
            if accelerator_tree is not None:
 
1350
                accelerator_tree.lock_read()
 
1351
            try:
 
1352
                return _build_tree(tree, wt, accelerator_tree)
 
1353
            finally:
 
1354
                if accelerator_tree is not None:
 
1355
                    accelerator_tree.unlock()
1344
1356
        finally:
1345
1357
            tree.unlock()
1346
1358
    finally:
1347
1359
        wt.unlock()
1348
1360
 
1349
1361
 
1350
 
def _build_tree(tree, wt):
 
1362
def _build_tree(tree, wt, accelerator_tree):
1351
1363
    """See build_tree."""
1352
1364
    if len(wt.inventory) > 1:  # more than just a root
1353
1365
        raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
1424
1436
                    old_parent = tt.trans_id_tree_path(tree_path)
1425
1437
                    _reparent_children(tt, old_parent, new_trans_id)
1426
1438
            for num, (trans_id, bytes) in enumerate(
1427
 
                tree.iter_files_bytes(deferred_contents)):
 
1439
                _iter_files_bytes_accelerated(tree, accelerator_tree,
 
1440
                                              deferred_contents)):
1428
1441
                tt.create_file(bytes, trans_id)
1429
1442
                pb.update('Adding file contents',
1430
1443
                          (num + len(tree.inventory) - len(deferred_contents)),
1442
1455
            wt.add_conflicts(conflicts)
1443
1456
        except errors.UnsupportedOperation:
1444
1457
            pass
1445
 
        result = tt.apply()
 
1458
        result = tt.apply(no_conflicts=True)
1446
1459
    finally:
1447
1460
        tt.finalize()
1448
1461
        top_pb.finished()
1449
1462
    return result
1450
1463
 
1451
1464
 
 
1465
def _iter_files_bytes_accelerated(tree, accelerator_tree, desired_files):
 
1466
    if accelerator_tree is None:
 
1467
        new_desired_files = desired_files
 
1468
    else:
 
1469
        iter = accelerator_tree._iter_changes(tree, include_unchanged=True)
 
1470
        unchanged = dict((f, p[0]) for (f, p, c, v, d, n, k, e)
 
1471
                         in iter if not c)
 
1472
        new_desired_files = []
 
1473
        for file_id, identifier in desired_files:
 
1474
            accelerator_path = unchanged.get(file_id)
 
1475
            if accelerator_path is None:
 
1476
                new_desired_files.append((file_id, identifier))
 
1477
                continue
 
1478
            contents = accelerator_tree.get_file(file_id, accelerator_path)
 
1479
            try:
 
1480
                want_new = False
 
1481
                contents_bytes = (contents.read(),)
 
1482
            finally:
 
1483
                contents.close()
 
1484
            yield identifier, contents_bytes
 
1485
    for result in tree.iter_files_bytes(new_desired_files):
 
1486
        yield result
 
1487
 
 
1488
 
1452
1489
def _reparent_children(tt, old_parent, new_parent):
1453
1490
    for child in tt.iter_tree_children(old_parent):
1454
1491
        tt.adjust_path(tt.final_name(child), new_parent, child)