Statistics
| Branch: | Tag: | Revision:

root / snf-pithos-backend / pithos / backends / lib / hashfiler / context_object.py @ 4a7b190f

History | View | Annotate | Download (5 kB)

1 c30635bf Filippos Giannakos
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 c30635bf Filippos Giannakos
#
3 c30635bf Filippos Giannakos
# Redistribution and use in source and binary forms, with or
4 c30635bf Filippos Giannakos
# without modification, are permitted provided that the following
5 c30635bf Filippos Giannakos
# conditions are met:
6 c30635bf Filippos Giannakos
#
7 c30635bf Filippos Giannakos
#   1. Redistributions of source code must retain the above
8 c30635bf Filippos Giannakos
#      copyright notice, this list of conditions and the following
9 c30635bf Filippos Giannakos
#      disclaimer.
10 c30635bf Filippos Giannakos
#
11 c30635bf Filippos Giannakos
#   2. Redistributions in binary form must reproduce the above
12 c30635bf Filippos Giannakos
#      copyright notice, this list of conditions and the following
13 c30635bf Filippos Giannakos
#      disclaimer in the documentation and/or other materials
14 c30635bf Filippos Giannakos
#      provided with the distribution.
15 c30635bf Filippos Giannakos
#
16 c30635bf Filippos Giannakos
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 c30635bf Filippos Giannakos
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 c30635bf Filippos Giannakos
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 c30635bf Filippos Giannakos
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 c30635bf Filippos Giannakos
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 c30635bf Filippos Giannakos
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 c30635bf Filippos Giannakos
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 c30635bf Filippos Giannakos
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 c30635bf Filippos Giannakos
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 c30635bf Filippos Giannakos
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 c30635bf Filippos Giannakos
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 c30635bf Filippos Giannakos
# POSSIBILITY OF SUCH DAMAGE.
28 c30635bf Filippos Giannakos
#
29 c30635bf Filippos Giannakos
# The views and conclusions contained in the software and
30 c30635bf Filippos Giannakos
# documentation are those of the authors and should not be
31 c30635bf Filippos Giannakos
# interpreted as representing official policies, either expressed
32 c30635bf Filippos Giannakos
# or implied, of GRNET S.A.
33 c30635bf Filippos Giannakos
34 c30635bf Filippos Giannakos
from os import SEEK_CUR, SEEK_SET
35 29148653 Sofia Papagiannaki
from rados import ObjectNotFound
36 c30635bf Filippos Giannakos
37 c30635bf Filippos Giannakos
_zeros = ''
38 c30635bf Filippos Giannakos
39 c30635bf Filippos Giannakos
40 c30635bf Filippos Giannakos
def zeros(nr):
41 c30635bf Filippos Giannakos
    global _zeros
42 c30635bf Filippos Giannakos
    size = len(_zeros)
43 c30635bf Filippos Giannakos
    if nr == size:
44 c30635bf Filippos Giannakos
        return _zeros
45 c30635bf Filippos Giannakos
46 c30635bf Filippos Giannakos
    if nr > size:
47 c30635bf Filippos Giannakos
        _zeros += '\0' * (nr - size)
48 c30635bf Filippos Giannakos
        return _zeros
49 c30635bf Filippos Giannakos
50 c30635bf Filippos Giannakos
    if nr < size:
51 c30635bf Filippos Giannakos
        _zeros = _zeros[:nr]
52 c30635bf Filippos Giannakos
        return _zeros
53 c30635bf Filippos Giannakos
54 c30635bf Filippos Giannakos
55 c30635bf Filippos Giannakos
def file_sync_write_chunks(radosobject, chunksize, offset, chunks, size=None):
56 c30635bf Filippos Giannakos
    """Write given chunks to the given buffered file object.
57 c30635bf Filippos Giannakos
       Writes never span across chunk boundaries.
58 c30635bf Filippos Giannakos
       If size is given stop after or pad until size bytes have been written.
59 c30635bf Filippos Giannakos
    """
60 c30635bf Filippos Giannakos
    padding = 0
61 c30635bf Filippos Giannakos
    cursize = chunksize * offset
62 c30635bf Filippos Giannakos
    radosobject.seek(cursize)
63 c30635bf Filippos Giannakos
    for chunk in chunks:
64 c30635bf Filippos Giannakos
        if padding:
65 c30635bf Filippos Giannakos
            radosobject.sync_write(buffer(zeros(chunksize), 0, padding))
66 c30635bf Filippos Giannakos
        if size is not None and cursize + chunksize >= size:
67 c30635bf Filippos Giannakos
            chunk = chunk[:chunksize - (cursize - size)]
68 c30635bf Filippos Giannakos
            radosobject.sync_write(chunk)
69 c30635bf Filippos Giannakos
            cursize += len(chunk)
70 c30635bf Filippos Giannakos
            break
71 c30635bf Filippos Giannakos
        radosobject.sync_write(chunk)
72 c30635bf Filippos Giannakos
        padding = chunksize - len(chunk)
73 c30635bf Filippos Giannakos
74 c30635bf Filippos Giannakos
    padding = size - cursize if size is not None else 0
75 c30635bf Filippos Giannakos
    if padding <= 0:
76 c30635bf Filippos Giannakos
        return
77 c30635bf Filippos Giannakos
78 c30635bf Filippos Giannakos
    q, r = divmod(padding, chunksize)
79 c30635bf Filippos Giannakos
    for x in xrange(q):
80 c30635bf Filippos Giannakos
        radosobject.sunc_write(zeros(chunksize))
81 c30635bf Filippos Giannakos
    radosobject.sync_write(buffer(zeros(chunksize), 0, r))
82 c30635bf Filippos Giannakos
83 29148653 Sofia Papagiannaki
84 c30635bf Filippos Giannakos
def file_sync_read_chunks(radosobject, chunksize, nr, offset=0):
85 c30635bf Filippos Giannakos
    """Read and yield groups of chunks from a buffered file object at offset.
86 c30635bf Filippos Giannakos
       Reads never span accros chunksize boundaries.
87 c30635bf Filippos Giannakos
    """
88 c30635bf Filippos Giannakos
    radosobject.seek(offset * chunksize)
89 c30635bf Filippos Giannakos
    while nr:
90 c30635bf Filippos Giannakos
        remains = chunksize
91 c30635bf Filippos Giannakos
        chunk = ''
92 c30635bf Filippos Giannakos
        while 1:
93 c30635bf Filippos Giannakos
            s = radosobject.sync_read(remains)
94 c30635bf Filippos Giannakos
            if not s:
95 c30635bf Filippos Giannakos
                if chunk:
96 c30635bf Filippos Giannakos
                    yield chunk
97 c30635bf Filippos Giannakos
                return
98 c30635bf Filippos Giannakos
            chunk += s
99 c30635bf Filippos Giannakos
            remains -= len(s)
100 c30635bf Filippos Giannakos
            if remains <= 0:
101 c30635bf Filippos Giannakos
                break
102 c30635bf Filippos Giannakos
        yield chunk
103 c30635bf Filippos Giannakos
        nr -= 1
104 c30635bf Filippos Giannakos
105 29148653 Sofia Papagiannaki
106 c30635bf Filippos Giannakos
class RadosObject(object):
107 c30635bf Filippos Giannakos
    __slots__ = ("name", "ioctx", "create", "offset")
108 c30635bf Filippos Giannakos
109 c30635bf Filippos Giannakos
    def __init__(self, name, ioctx, create=0):
110 c30635bf Filippos Giannakos
        self.name = name
111 c30635bf Filippos Giannakos
        self.ioctx = ioctx
112 c30635bf Filippos Giannakos
        self.create = create
113 c30635bf Filippos Giannakos
        self.offset = 0
114 c30635bf Filippos Giannakos
        #self.dirty = 0
115 c30635bf Filippos Giannakos
116 c30635bf Filippos Giannakos
    def __enter__(self):
117 c30635bf Filippos Giannakos
        return self
118 c30635bf Filippos Giannakos
119 c30635bf Filippos Giannakos
    def __exit__(self, exc, arg, trace):
120 c30635bf Filippos Giannakos
        return False
121 c30635bf Filippos Giannakos
122 c30635bf Filippos Giannakos
    def seek(self, offset, whence=SEEK_SET):
123 c30635bf Filippos Giannakos
        if whence == SEEK_CUR:
124 c30635bf Filippos Giannakos
            offset += self.offset
125 c30635bf Filippos Giannakos
        self.offset = offset
126 c30635bf Filippos Giannakos
        return offset
127 c30635bf Filippos Giannakos
128 c30635bf Filippos Giannakos
    def tell(self):
129 c30635bf Filippos Giannakos
        return self.offset
130 c30635bf Filippos Giannakos
131 c30635bf Filippos Giannakos
    def truncate(self, size):
132 c30635bf Filippos Giannakos
        self.ioctx.trunc(self.name, size)
133 c30635bf Filippos Giannakos
134 c30635bf Filippos Giannakos
    def sync_write(self, data):
135 c30635bf Filippos Giannakos
        #self.dirty = 1
136 c30635bf Filippos Giannakos
        self.ioctx.write(self.name, data, self.offset)
137 c30635bf Filippos Giannakos
        self.offset += len(data)
138 c30635bf Filippos Giannakos
139 c30635bf Filippos Giannakos
    def sync_write_chunks(self, chunksize, offset, chunks, size=None):
140 c30635bf Filippos Giannakos
        #self.dirty = 1
141 c30635bf Filippos Giannakos
        return file_sync_write_chunks(self, chunksize, offset, chunks, size)
142 c30635bf Filippos Giannakos
143 c30635bf Filippos Giannakos
    def sync_read(self, size):
144 c30635bf Filippos Giannakos
        read = self.ioctx.read
145 c30635bf Filippos Giannakos
        data = ''
146 c30635bf Filippos Giannakos
        datalen = 0
147 c30635bf Filippos Giannakos
        while 1:
148 c30635bf Filippos Giannakos
            try:
149 29148653 Sofia Papagiannaki
                s = read(self.name, size - datalen, self.offset)
150 c30635bf Filippos Giannakos
            except ObjectNotFound:
151 c30635bf Filippos Giannakos
                s = None
152 c30635bf Filippos Giannakos
            if not s:
153 c30635bf Filippos Giannakos
                break
154 c30635bf Filippos Giannakos
            data += s
155 c30635bf Filippos Giannakos
            datalen += len(s)
156 c30635bf Filippos Giannakos
            self.offset += len(s)
157 c30635bf Filippos Giannakos
            if datalen >= size:
158 c30635bf Filippos Giannakos
                break
159 c30635bf Filippos Giannakos
        return data
160 c30635bf Filippos Giannakos
161 c30635bf Filippos Giannakos
    def sync_read_chunks(self, chunksize, nr, offset=0):
162 c30635bf Filippos Giannakos
        return file_sync_read_chunks(self, chunksize, nr, offset)