Skip to content

Commit 0650892

Browse files
committed
moved all info and stream base classes into new module, base, as well as the respective tests were moved to test_base
Adjusted PackStream and PackInfo classes not to contain the sha field anymore streams: DecompressMemMapReader now parses its header on demand if it is not set, using the mose useful 3 lines ever, LazyMixin
1 parent 3b902ed commit 0650892

9 files changed

Lines changed: 461 additions & 345 deletions

File tree

__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ def _init_externals():
1414

1515
# default imports
1616
from db import *
17+
from base import *
1718
from stream import *
1819

base.py

Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
"""Module with basic data structures - they are designed to be lightweight and fast"""
2+
from util import (
3+
to_hex_sha,
4+
to_bin_sha,
5+
zlib
6+
)
7+
8+
from fun import type_id_to_type_map
9+
10+
__all__ = ('OInfo', 'OPackInfo', 'ODeltaPackInfo',
11+
'OStream', 'OPackStream', 'ODeltaPackStream',
12+
'IStream', 'InvalidOInfo', 'InvalidOStream' )
13+
14+
#{ ODB Bases
15+
16+
class OInfo(tuple):
17+
"""Carries information about an object in an ODB, provdiing information
18+
about the sha of the object, the type_string as well as the uncompressed size
19+
in bytes.
20+
21+
It can be accessed using tuple notation and using attribute access notation::
22+
23+
assert dbi[0] == dbi.sha
24+
assert dbi[1] == dbi.type
25+
assert dbi[2] == dbi.size
26+
27+
The type is designed to be as lighteight as possible."""
28+
__slots__ = tuple()
29+
30+
def __new__(cls, sha, type, size):
31+
return tuple.__new__(cls, (sha, type, size))
32+
33+
def __init__(self, *args):
34+
tuple.__init__(self)
35+
36+
#{ Interface
37+
@property
38+
def sha(self):
39+
return self[0]
40+
41+
@property
42+
def type(self):
43+
return self[1]
44+
45+
@property
46+
def size(self):
47+
return self[2]
48+
#} END interface
49+
50+
51+
class OPackInfo(tuple):
52+
"""As OInfo, but provides a type_id property to retrieve the numerical type id, and
53+
does not include a sha"""
54+
__slots__ = tuple()
55+
56+
def __new__(cls, type, size):
57+
return tuple.__new__(cls, (type, size))
58+
59+
def __init__(self, *args):
60+
tuple.__init__(self)
61+
62+
#{ Interface
63+
64+
@property
65+
def type(self):
66+
return type_id_to_type_map[self[0]]
67+
68+
@property
69+
def type_id(self):
70+
return self[0]
71+
72+
@property
73+
def size(self):
74+
return self[1]
75+
76+
#} END interface
77+
78+
79+
class ODeltaPackInfo(OPackInfo):
80+
"""Adds delta specific information,
81+
Either the 20 byte sha which points to some object in the database,
82+
or the base_offset, being an offset into the pack at which our base
83+
can be found"""
84+
__slots__ = tuple()
85+
86+
def __new__(cls, type, size, delta_info):
87+
return tuple.__new__(cls, (type, size, delta_info))
88+
89+
#{ Interface
90+
@property
91+
def delta_info(self):
92+
return self[2]
93+
#} END interface
94+
95+
96+
class OStream(OInfo):
97+
"""Base for object streams retrieved from the database, providing additional
98+
information about the stream.
99+
Generally, ODB streams are read-only as objects are immutable"""
100+
__slots__ = tuple()
101+
102+
def __new__(cls, sha, type, size, stream, *args, **kwargs):
103+
"""Helps with the initialization of subclasses"""
104+
return tuple.__new__(cls, (sha, type, size, stream))
105+
106+
107+
def __init__(self, *args, **kwargs):
108+
tuple.__init__(self)
109+
110+
#{ Stream Reader Interface
111+
112+
def read(self, size=-1):
113+
return self[3].read(size)
114+
115+
@property
116+
def stream(self):
117+
return self[3]
118+
#} END stream reader interface
119+
120+
121+
class OPackStream(OPackInfo):
122+
"""Next to pack object information, a stream outputting an undeltified base object
123+
is provided"""
124+
__slots__ = tuple()
125+
126+
def __new__(cls, type, size, stream, *args):
127+
"""Helps with the initialization of subclasses"""
128+
return tuple.__new__(cls, (type, size, stream))
129+
130+
#{ Stream Reader Interface
131+
def read(self, size=-1):
132+
return self[2].read(size)
133+
134+
@property
135+
def stream(self):
136+
return self[2]
137+
#} END stream reader interface
138+
139+
140+
class ODeltaPackStream(ODeltaPackInfo):
141+
"""Provides a stream outputting the uncompressed offset delta information"""
142+
__slots__ = tuple()
143+
144+
def __new__(cls, type, size, delta_info, stream):
145+
return tuple.__new__(cls, (type, size, delta_info, stream))
146+
147+
148+
#{ Stream Reader Interface
149+
def read(self, size=-1):
150+
return self[3].read(size)
151+
152+
@property
153+
def stream(self):
154+
return self[3]
155+
#} END stream reader interface
156+
157+
158+
class IStream(list):
159+
"""Represents an input content stream to be fed into the ODB. It is mutable to allow
160+
the ODB to record information about the operations outcome right in this instance.
161+
162+
It provides interfaces for the OStream and a StreamReader to allow the instance
163+
to blend in without prior conversion.
164+
165+
The only method your content stream must support is 'read'"""
166+
__slots__ = tuple()
167+
168+
def __new__(cls, type, size, stream, sha=None):
169+
return list.__new__(cls, (sha, type, size, stream, None))
170+
171+
def __init__(self, type, size, stream, sha=None):
172+
list.__init__(self, (sha, type, size, stream, None))
173+
174+
#{ Interface
175+
176+
@property
177+
def hexsha(self):
178+
""":return: our sha, hex encoded, 40 bytes"""
179+
return to_hex_sha(self[0])
180+
181+
@property
182+
def binsha(self):
183+
""":return: our sha as binary, 20 bytes"""
184+
return to_bin_sha(self[0])
185+
186+
def _error(self):
187+
""":return: the error that occurred when processing the stream, or None"""
188+
return self[4]
189+
190+
def _set_error(self, exc):
191+
"""Set this input stream to the given exc, may be None to reset the error"""
192+
self[4] = exc
193+
194+
error = property(_error, _set_error)
195+
196+
#} END interface
197+
198+
#{ Stream Reader Interface
199+
200+
def read(self, size=-1):
201+
"""Implements a simple stream reader interface, passing the read call on
202+
to our internal stream"""
203+
return self[3].read(size)
204+
205+
#} END stream reader interface
206+
207+
#{ interface
208+
209+
def _set_sha(self, sha):
210+
self[0] = sha
211+
212+
def _sha(self):
213+
return self[0]
214+
215+
sha = property(_sha, _set_sha)
216+
217+
218+
def _type(self):
219+
return self[1]
220+
221+
def _set_type(self, type):
222+
self[1] = type
223+
224+
type = property(_type, _set_type)
225+
226+
def _size(self):
227+
return self[2]
228+
229+
def _set_size(self, size):
230+
self[2] = size
231+
232+
size = property(_size, _set_size)
233+
234+
def _stream(self):
235+
return self[3]
236+
237+
def _set_stream(self, stream):
238+
self[3] = stream
239+
240+
stream = property(_stream, _set_stream)
241+
242+
#} END odb info interface
243+
244+
245+
class InvalidOInfo(tuple):
246+
"""Carries information about a sha identifying an object which is invalid in
247+
the queried database. The exception attribute provides more information about
248+
the cause of the issue"""
249+
__slots__ = tuple()
250+
251+
def __new__(cls, sha, exc):
252+
return tuple.__new__(cls, (sha, exc))
253+
254+
def __init__(self, sha, exc):
255+
tuple.__init__(self, (sha, exc))
256+
257+
@property
258+
def sha(self):
259+
return self[0]
260+
261+
@property
262+
def error(self):
263+
""":return: exception instance explaining the failure"""
264+
return self[1]
265+
266+
267+
class InvalidOStream(InvalidOInfo):
268+
"""Carries information about an invalid ODB stream"""
269+
__slots__ = tuple()
270+
271+
#} END ODB Bases
272+

db/git.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
from gitdb.stream import (
2+
from gitdb.base import (
33
OInfo,
44
OStream
55
)

db/loose.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
from gitdb.stream import (
1414
DecompressMemMapReader,
1515
FDCompressedSha1Writer,
16-
Sha1Writer,
17-
OStream,
18-
OInfo
16+
Sha1Writer
1917
)
2018

19+
from gitdb.base import (
20+
OStream,
21+
OInfo
22+
)
23+
2124
from gitdb.util import (
2225
ENOENT,
2326
to_hex_sha,

0 commit comments

Comments
 (0)