~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to tools/history2weaves.py

  • Committer: Martin Pool
  • Date: 2005-08-19 22:41:41 UTC
  • Revision ID: mbp@sourcefrog.net-20050819224141-b43244067d36eee7
- add a tool script to convert past history into weaves

  this is not quite finished yet but does pretty well.  
  we still need to upgrade the inventories as we go to make
  them store file revision_ids, so that we can get the right
  file back out of the weave.

  the results compare quite well: the history of bzr up to 
  this point is 25688kB in the full-text store, gzipped, and 
  3676kB in the weave store, and 1460kB in the weave store
  gzipped.  so about 20x compression before gzip.  a full
  working directory is 3084kB.

  using this we can get accurate fast annotations of all past
  versions, though you do need to map the weave version numbers
  back to revisions by hand for the moment.

Show diffs side-by-side

added added

removed removed

Lines of Context:
41
41
    inv_weave = Weave()
42
42
 
43
43
    last_text_sha = {}
44
 
    text_rfs = {}
 
44
 
 
45
    # holds in-memory weaves for all files
 
46
    text_weaves = {}
45
47
 
46
48
    b = bzrlib.branch.find_branch('.')
47
49
 
48
50
    revno = 1
49
51
    rev_history = b.revision_history()
50
52
    last_idx = None
51
 
    parents = []
 
53
    inv_parents = []
 
54
    text_count = 0
52
55
    
53
56
    for rev_id in rev_history:
54
57
        pb.update('converting inventory', revno, len(rev_history))
55
58
        
56
59
        inv_xml = b.get_inventory_xml(rev_id).readlines()
57
60
 
58
 
        new_idx = inv_weave.add(rev_id, parents, inv_xml)
59
 
        parents = [new_idx]
60
 
 
61
 
#         tree = b.revision_tree(rev_id)
62
 
#         inv = tree.inventory
63
 
 
64
 
#         # for each file in the inventory, put it into its own revfile
65
 
#         for file_id in inv:
66
 
#             ie = inv[file_id]
67
 
#             if ie.kind != 'file':
68
 
#                 continue
69
 
#             if last_text_sha.get(file_id) == ie.text_sha1:
70
 
#                 # same as last time
71
 
#                 continue
72
 
#             last_text_sha[file_id] = ie.text_sha1
73
 
 
74
 
#             # new text (though possibly already stored); need to store it
75
 
#             text = tree.get_file(file_id).read()
76
 
            
77
 
#             if file_id not in text_rfs:
78
 
#                 text_rfs[file_id] = Revfile('revfiles/' + file_id, 'w')
79
 
#             rf = text_rfs[file_id]
80
 
 
81
 
#             last = len(rf)
82
 
#             if last == 0:
83
 
#                 last = None
84
 
#             else:
85
 
#                 last -= 1
86
 
#             rf.add(text, last, compress=True)
 
61
        new_idx = inv_weave.add(rev_id, inv_parents, inv_xml)
 
62
        inv_parents = [new_idx]
 
63
 
 
64
        tree = b.revision_tree(rev_id)
 
65
        inv = tree.inventory
 
66
 
 
67
        # for each file in the inventory, put it into its own revfile
 
68
        for file_id in inv:
 
69
            ie = inv[file_id]
 
70
            if ie.kind != 'file':
 
71
                continue
 
72
            if last_text_sha.get(file_id) == ie.text_sha1:
 
73
                # same as last time
 
74
                continue
 
75
            last_text_sha[file_id] = ie.text_sha1
 
76
 
 
77
            # new text (though possibly already stored); need to store it
 
78
            text_lines = tree.get_file(file_id).readlines()
 
79
 
 
80
            # if the file's created for the first time in this
 
81
            # revision then make a new weave; else find the old one
 
82
            if file_id not in text_weaves:
 
83
                text_weaves[file_id] = Weave()
 
84
                
 
85
            w = text_weaves[file_id]
 
86
 
 
87
            # base the new text version off whatever was last
 
88
            # (actually it'd be better to track this, to allow for
 
89
            # files that are deleted and then reappear)
 
90
            last = len(w)
 
91
            if last == 0:
 
92
                parents = []
 
93
            else:
 
94
                parents = [last-1]
 
95
 
 
96
            w.add(rev_id, parents, text_lines)
 
97
            text_count += 1
87
98
 
88
99
        revno += 1
89
100
 
90
 
    inv_wf = AtomicFile('/tmp/inventory.weave')
 
101
    pb.clear()
 
102
    print '%6d revisions and inventories' % revno
 
103
    print '%6d texts' % text_count
 
104
 
 
105
    i = 0
 
106
    # TODO: commit them all atomically at the end, not one by one
 
107
    write_atomic_weave(inv_weave, 'weaves/inventory.weave')
 
108
    for file_id, file_weave in text_weaves.items():
 
109
        pb.update('writing weave', i, text_count)
 
110
        write_atomic_weave(file_weave, 'weaves/%s.weave' % file_id)
 
111
        i += 1
 
112
 
 
113
    pb.clear()
 
114
 
 
115
 
 
116
def write_atomic_weave(weave, filename):
 
117
    inv_wf = AtomicFile(filename)
91
118
    try:
92
 
        write_weave(inv_weave, inv_wf)
 
119
        write_weave(weave, inv_wf)
93
120
        inv_wf.commit()
94
121
    finally:
95
122
        inv_wf.close()
96
123
 
97
 
    pb.clear()
 
124
    
98
125
 
99
126
 
100
127
def profile_convert():