Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfe5289e

Browse files
committed
tree now uses less memory for its cache as it stores the bare deserialized information - this also speeds up later serialization after changes. its clear though that retrieving actual objects is slower currently as these are not cached anymore. Its worth thinking about moving these encoding, decoding routines to gitdb
1 parent28ed48c commitfe5289e

File tree

1 file changed

+63
-55
lines changed

1 file changed

+63
-55
lines changed

‎lib/git/objects/tree.py

Lines changed: 63 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,13 @@
1313
importutils
1414
fromgit.utilsimportjoin_path
1515

16+
join=os.path.join
1617

1718
defsha_to_hex(sha):
1819
"""Takes a string and returns the hex of the sha within"""
1920
hexsha=binascii.hexlify(sha)
2021
returnhexsha
21-
22+
2223

2324
classTree(base.IndexObject,diff.Diffable,utils.Traversable,utils.Serializable):
2425
"""
@@ -47,38 +48,46 @@ class Tree(base.IndexObject, diff.Diffable, utils.Traversable, utils.Serializabl
4748
symlink_id=012
4849
tree_id=004
4950

51+
_map_id_to_type= {
52+
commit_id :Submodule,
53+
blob_id :Blob,
54+
symlink_id :Blob
55+
# tree id added once Tree is defined
56+
}
57+
5058

5159
def__init__(self,repo,sha,mode=0,path=None):
5260
super(Tree,self).__init__(repo,sha,mode,path)
5361

5462
@classmethod
5563
def_get_intermediate_items(cls,index_object):
5664
ifindex_object.type=="tree":
57-
returnindex_object._cache
65+
returntuple(index_object._iter_convert_to_object(index_object._cache))
5866
returntuple()
5967

60-
6168
def_set_cache_(self,attr):
6269
ifattr=="_cache":
6370
# Set the data when we need it
64-
self._cache=self._get_tree_cache()
71+
self._cache=self._get_tree_cache(self.data)
6572
else:
6673
super(Tree,self)._set_cache_(attr)
6774

68-
def_get_tree_cache(self,data=None):
75+
def_get_tree_cache(self,data):
6976
""" :return: list(object_instance, ...)
70-
:param data: if not None, a byte string representing the tree data
71-
If None, self.data will be used instead"""
72-
out=list()
73-
ifdataisNone:
74-
data=self.data
75-
forobjinself._iter_from_data(data):
76-
ifobjisnotNone:
77-
out.append(obj)
78-
# END if object was handled
79-
# END for each line from ls-tree
80-
returnout
77+
:param data: data string containing our serialized information"""
78+
returnlist(self._iter_from_data(data))
8179

80+
def_iter_convert_to_object(self,iterable):
81+
"""Iterable yields tuples of (hexsha, mode, name), which will be converted
82+
to the respective object representation"""
83+
forhexsha,mode,nameiniterable:
84+
path=join(self.path,name)
85+
type_id=mode>>12
86+
try:
87+
yieldself._map_id_to_type[type_id](self.repo,hexsha,mode,path)
88+
exceptKeyError:
89+
raiseTypeError("Unknown type %i found in tree data for path '%s'"% (type_id,path))
90+
# END for each item
8291

8392
def_iter_from_data(self,data):
8493
"""
@@ -87,8 +96,7 @@ def _iter_from_data(self, data):
8796
8897
Note: This method was inspired by the parse_tree method in dulwich.
8998
90-
Returns
91-
list(IndexObject, ...)
99+
:yield: Tuple(hexsha, mode, tree_relative_path)
92100
"""
93101
ord_zero=ord('0')
94102
len_data=len(data)
@@ -105,7 +113,6 @@ def _iter_from_data(self, data):
105113
mode= (mode<<3)+ (ord(data[i])-ord_zero)
106114
i+=1
107115
# END while reading mode
108-
type_id=mode>>12
109116

110117
# byte is space now, skip it
111118
i+=1
@@ -117,22 +124,13 @@ def _iter_from_data(self, data):
117124
i+=1
118125
# END while not reached NULL
119126
name=data[ns:i]
120-
path=join_path(self.path,name)
121127

122128
# byte is NULL, get next 20
123129
i+=1
124130
sha=data[i:i+20]
125131
i=i+20
126132

127-
hexsha=sha_to_hex(sha)
128-
iftype_id==self.blob_idortype_id==self.symlink_id:
129-
yieldBlob(self.repo,hexsha,mode,path)
130-
eliftype_id==self.tree_id:
131-
yieldTree(self.repo,hexsha,mode,path)
132-
eliftype_id==self.commit_id:
133-
yieldSubmodule(self.repo,hexsha,mode,path)
134-
else:
135-
raiseTypeError("Unknown type found in tree data %i for path '%s'"% (type_id,path))
133+
yield (sha_to_hex(sha),mode,name)
136134
# END for each byte in data stream
137135

138136

@@ -165,17 +163,17 @@ def __div__(self, file):
165163
else:
166164
# safety assertion - blobs are at the end of the path
167165
ifi!=len(tokens)-1:
168-
raiseKeyError(msg%file)
166+
raiseKeyError(msg%file)
169167
returnitem
170168
# END handle item type
171169
# END for each token of split path
172170
ifitem==self:
173171
raiseKeyError(msg%file)
174172
returnitem
175173
else:
176-
forobjinself._cache:
177-
ifobj.name==file:
178-
returnobj
174+
forinfoinself._cache:
175+
ifinfo[2]==file:# [2] == name
176+
returnself._map_id_to_type[info[1]>>12](self.repo,info[0],info[1],join(self.path,info[2]))
179177
# END for each obj
180178
raiseKeyError(msg%file )
181179
# END handle long paths
@@ -210,18 +208,19 @@ def traverse( self, predicate = lambda i,d: True,
210208
returnsuper(Tree,self).traverse(predicate,prune,depth,branch_first,visit_once,ignore_self)
211209

212210
# List protocol
213-
def__getslice__(self,i,j):
214-
returnself._cache[i:j]
211+
def__getslice__(self,i,j):
212+
returnlist(self._iter_convert_to_object(self._cache[i:j]))
215213

216214
def__iter__(self):
217-
returniter(self._cache)
215+
returnself._iter_convert_to_object(self._cache)
218216

219217
def__len__(self):
220218
returnlen(self._cache)
221219

222-
def__getitem__(self,item):
220+
def__getitem__(self,item):
223221
ifisinstance(item,int):
224-
returnself._cache[item]
222+
info=self._cache[item]
223+
returnself._map_id_to_type[info[1]>>12](self.repo,info[0],info[1],join(self.path,info[2]))
225224

226225
ifisinstance(item,basestring):
227226
# compatability
@@ -231,19 +230,26 @@ def __getitem__(self,item):
231230
raiseTypeError("Invalid index type: %r"%item )
232231

233232

234-
def__contains__(self,item):
233+
def__contains__(self,item):
235234
ifisinstance(item,base.IndexObject):
236-
returniteminself._cache
237-
235+
forinfoinself._cache:
236+
ifitem.sha==info[0]:
237+
returnTrue
238+
# END compare sha
239+
# END for each entry
240+
# END handle item is index object
238241
# compatability
239-
forobjinself._cache:
240-
ifitem==obj.path:
242+
243+
# treat item as repo-relative path
244+
path=self.path
245+
forinfoinself._cache:
246+
ifitem==join(path,info[2]):
241247
returnTrue
242248
# END for each item
243249
returnFalse
244250

245251
def__reversed__(self):
246-
returnreversed(self._cache)
252+
returnreversed(self._iter_convert_to_object(self._cache))
247253

248254
def_serialize(self,stream,presort=False):
249255
"""Serialize this tree into the stream. Please note that we will assume
@@ -256,25 +262,27 @@ def _serialize(self, stream, presort=False):
256262
bit_mask=7# 3 bits set
257263
hex_to_bin=binascii.a2b_hex
258264

259-
foriteminself._cache:
260-
mode=''
261-
mb=item.mode
265+
forhexsha,mode,nameinself._cache:
266+
mode_str=''
262267
foriinxrange(6):
263-
mode=chr(((mb>> (i*3))&bit_mask)+ord_zero)+mode
268+
mode_str=chr(((mode>> (i*3))&bit_mask)+ord_zero)+mode_str
264269
# END for each 8 octal value
270+
265271
# git slices away the first octal if its zero
266-
ifmode[0]=='0':
267-
mode=mode[1:]
272+
ifmode_str[0]=='0':
273+
mode_str=mode_str[1:]
268274
# END save a byte
269275

270-
# note: the cache currently contains repo-relative paths, not
271-
# tree-relative ones. Maybe the cache should only contain
272-
# actual tuples, which are converted to objects later
273-
# TODO: do it so
274-
stream.write("%s %s\0%s"% (mode,os.path.basename(item.path),hex_to_bin(item.sha)))
276+
stream.write("%s %s\0%s"% (mode_str,name,hex_to_bin(hexsha)))
275277
# END for each item
276278
returnself
277279

278280
def_deserialize(self,stream):
279281
self._cache=self._get_tree_cache(stream.read())
280282
returnself
283+
284+
285+
# END tree
286+
287+
# finalize map definition
288+
Tree._map_id_to_type[Tree.tree_id]=Tree

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp