33__all__ = ["MappedMemoryManager" ]
44
55import os
6+ import sys
67import mmap
78
89from mmap import PAGESIZE
@@ -64,16 +65,22 @@ def extend_right_to(self, window, max_size):
6465 self .size = min (self .size + (window .ofs - self .ofs_end ()), max_size )
6566
6667
67- class Region (object ):
68+ class MappedRegion (object ):
6869 """Defines a mapped region of memory, aligned to pagesizes
6970 :note: deallocates used region automatically on destruction"""
70- __slots__ = (
71+ __slots__ = [
7172 '_b' , # beginning of mapping
7273 '_mf' , # mapped memory chunk (as returned by mmap)
7374 '_nc' , # number of clients using this region
74- '_uc' # total amount of usages
75- )
75+ '_uc' , # total amount of usages
76+ '_ms' # actual size of the mapping
77+ ]
78+ _need_compat_layer = sys .version_info [1 ] < 6
7679
80+ if _need_compat_layer :
81+ __slots__ .append ('_mfb' ) # mapped memory buffer to provide offset
82+ #END handle additional slot
83+
7784
7885 def __init__ (self , path , ofs , size ):
7986 """Initialize a region, allocate the memory map
@@ -88,10 +95,66 @@ def __init__(self, path, ofs, size):
8895
8996 fd = os .open (path , os .O_RDONLY | getattr (os , 'O_BINARY' , 0 ))
9097 try :
91- self ._mf = mmap .mmap (fd , size , access = mmap .ACCESS_READ , offset = ofs )
98+ kwargs = dict (access = mmap .ACCESS_READ , offset = ofs )
99+ corrected_size = size
100+ if self ._need_compat_layer :
101+ del (kwargs ['offset' ])
102+ corrected_size += ofs
103+ # END handle python not supporting offset ! Arg
104+
105+ # have to correct size, otherwise (instead of the c version) it will
106+ # bark that the size is too large ... many extra file accesses because
107+ # if this ... argh !
108+ self ._mf = mmap .mmap (fd , min (os .fstat (fd ).st_size , corrected_size ), ** kwargs )
109+
110+ print len (self ._mf )
111+ if self ._need_compat_layer :
112+ self ._mfb = buffer (self ._mf , ofs , size )
113+ #END handle buffer wrapping
92114 finally :
93115 os .close (fd )
94116 #END close file handle
117+
118+ def ofs_begin (self ):
119+ """:return: absolute byte offset to the first byte of the mapping"""
120+ return self ._b
121+
122+ def size (self ):
123+ """:return: total size of the mapped region in bytes"""
124+ return len (self ._mf )
125+
126+ def ofs_end (self ):
127+ """:return: Absolute offset to one byte beyond the mapping into the file"""
128+ return self ._b + self .size ()
129+
130+ def includes_ofs (self , ofs ):
131+ """:return: True if the given offset can be read in our mapped region"""
132+ return (ofs >= self .ofs_begin ()) and (ofs <= self .ofs_end ())
133+
134+ def client_count (self ):
135+ """:return: number of clients currently using this region"""
136+ return self ._nc
137+
138+ def adjust_client_count (self , ofs ):
139+ """Adjust the client count by the given positive or negative offset"""
140+ self ._nc += ofs
141+
142+ def usage_count (self ):
143+ """:return: amount of usages so far"""
144+ return self ._uc
145+
146+ def adjust_usage_count (self , ofs ):
147+ """Adjust the usage count by the given positive or negative offset"""
148+ self ._uc += ofs
149+
150+ # re-define all methods which need offset adjustments in compatibility mode
151+ if _need_compat_layer :
152+ def size (self ):
153+ return len (self ._mf ) - self ._b
154+
155+ def ofs_end (self ):
156+ return len (self ._mf )
157+ #END handle compat layer
95158
96159
97160class MappedMemoryManager (object ):
0 commit comments