Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4.5 kB)

1 2e662088 Antony Chazapis
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2 2715ade4 Sofia Papagiannaki
#
3 a9b3f29d Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 a9b3f29d Antony Chazapis
# without modification, are permitted provided that the following
5 a9b3f29d Antony Chazapis
# conditions are met:
6 2715ade4 Sofia Papagiannaki
#
7 a9b3f29d Antony Chazapis
#   1. Redistributions of source code must retain the above
8 a9b3f29d Antony Chazapis
#      copyright notice, this list of conditions and the following
9 a9b3f29d Antony Chazapis
#      disclaimer.
10 2715ade4 Sofia Papagiannaki
#
11 a9b3f29d Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 a9b3f29d Antony Chazapis
#      copyright notice, this list of conditions and the following
13 a9b3f29d Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 a9b3f29d Antony Chazapis
#      provided with the distribution.
15 2715ade4 Sofia Papagiannaki
#
16 a9b3f29d Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 a9b3f29d Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 a9b3f29d Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 a9b3f29d Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 a9b3f29d Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 a9b3f29d Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 a9b3f29d Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 a9b3f29d Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 a9b3f29d Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 a9b3f29d Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 a9b3f29d Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 a9b3f29d Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 2715ade4 Sofia Papagiannaki
#
29 a9b3f29d Antony Chazapis
# The views and conclusions contained in the software and
30 a9b3f29d Antony Chazapis
# documentation are those of the authors and should not be
31 a9b3f29d Antony Chazapis
# interpreted as representing official policies, either expressed
32 a9b3f29d Antony Chazapis
# or implied, of GRNET S.A.
33 a9b3f29d Antony Chazapis
34 c30635bf Filippos Giannakos
from fileblocker import FileBlocker
35 c30635bf Filippos Giannakos
36 29148653 Sofia Papagiannaki
37 c30635bf Filippos Giannakos
def intersect(a, b):
38 c30635bf Filippos Giannakos
    """ return the intersection of two lists """
39 c30635bf Filippos Giannakos
    return list(set(a) & set(b))
40 c30635bf Filippos Giannakos
41 29148653 Sofia Papagiannaki
42 c30635bf Filippos Giannakos
def union(a, b):
43 c30635bf Filippos Giannakos
    """ return the union of two lists """
44 c30635bf Filippos Giannakos
    return list(set(a) | set(b))
45 a9b3f29d Antony Chazapis
46 a9b3f29d Antony Chazapis
47 a9b3f29d Antony Chazapis
class Blocker(object):
48 a9b3f29d Antony Chazapis
    """Blocker.
49 47462eda Filippos Giannakos
       Required constructor parameters: blocksize, blockpath, hashtype.
50 47462eda Filippos Giannakos
       Optional blockpool.
51 a9b3f29d Antony Chazapis
    """
52 a9b3f29d Antony Chazapis
53 a9b3f29d Antony Chazapis
    def __init__(self, **params):
54 47462eda Filippos Giannakos
        self.rblocker = None
55 47462eda Filippos Giannakos
        try:
56 47462eda Filippos Giannakos
            if params['blockpool']:
57 43411855 Sofia Papagiannaki
                from radosblocker import RadosBlocker
58 47462eda Filippos Giannakos
                self.rblocker = RadosBlocker(**params)
59 29148653 Sofia Papagiannaki
        except KeyError:
60 47462eda Filippos Giannakos
            pass
61 c30635bf Filippos Giannakos
62 47462eda Filippos Giannakos
        self.fblocker = FileBlocker(**params)
63 47462eda Filippos Giannakos
        self.hashlen = self.fblocker.hashlen
64 57ccbdbf Filippos Giannakos
        self.blocksize = params['blocksize']
65 a9b3f29d Antony Chazapis
66 a9b3f29d Antony Chazapis
    def block_hash(self, data):
67 a9b3f29d Antony Chazapis
        """Hash a block of data"""
68 47462eda Filippos Giannakos
        return self.fblocker.block_hash(data)
69 a9b3f29d Antony Chazapis
70 a9b3f29d Antony Chazapis
    def block_ping(self, hashes):
71 a9b3f29d Antony Chazapis
        """Check hashes for existence and
72 a9b3f29d Antony Chazapis
           return those missing from block storage.
73 a9b3f29d Antony Chazapis
        """
74 47462eda Filippos Giannakos
        r = []
75 47462eda Filippos Giannakos
        if self.rblocker:
76 47462eda Filippos Giannakos
            r = self.rblocker.block_ping(hashes)
77 c30635bf Filippos Giannakos
        f = self.fblocker.block_ping(hashes)
78 c30635bf Filippos Giannakos
        return union(r, f)
79 a9b3f29d Antony Chazapis
80 a9b3f29d Antony Chazapis
    def block_retr(self, hashes):
81 a9b3f29d Antony Chazapis
        """Retrieve blocks from storage by their hashes."""
82 c30635bf Filippos Giannakos
        return self.fblocker.block_retr(hashes)
83 a9b3f29d Antony Chazapis
84 a9b3f29d Antony Chazapis
    def block_stor(self, blocklist):
85 a9b3f29d Antony Chazapis
        """Store a bunch of blocks and return (hashes, missing).
86 a9b3f29d Antony Chazapis
           Hashes is a list of the hashes of the blocks,
87 a9b3f29d Antony Chazapis
           missing is a list of indices in that list indicating
88 a9b3f29d Antony Chazapis
           which blocks were missing from the store.
89 a9b3f29d Antony Chazapis
        """
90 47462eda Filippos Giannakos
        r_missing = []
91 47462eda Filippos Giannakos
        (hashes, f_missing) = self.fblocker.block_stor(blocklist)
92 47462eda Filippos Giannakos
        if self.rblocker:
93 47462eda Filippos Giannakos
            (_, r_missing) = self.rblocker.block_stor(blocklist)
94 c30635bf Filippos Giannakos
        return (hashes, union(r_missing, f_missing))
95 a9b3f29d Antony Chazapis
96 c9865fe1 Antony Chazapis
    def block_delta(self, blkhash, offset, data):
97 a9b3f29d Antony Chazapis
        """Construct and store a new block from a given block
98 c9865fe1 Antony Chazapis
           and a data 'patch' applied at offset. Return:
99 a9b3f29d Antony Chazapis
           (the hash of the new block, if the block already existed)
100 a9b3f29d Antony Chazapis
        """
101 57ccbdbf Filippos Giannakos
        blocksize = self.blocksize
102 47462eda Filippos Giannakos
        r_hash = None
103 47462eda Filippos Giannakos
        r_existed = True
104 c30635bf Filippos Giannakos
        (f_hash, f_existed) = self.fblocker.block_delta(blkhash, offset, data)
105 47462eda Filippos Giannakos
        if self.rblocker:
106 29148653 Sofia Papagiannaki
            (r_hash, r_existed) = self.rblocker.block_delta(blkhash, offset,
107 29148653 Sofia Papagiannaki
                                                            data)
108 c30635bf Filippos Giannakos
        if not r_hash and not f_hash:
109 c9865fe1 Antony Chazapis
            return None, None
110 47462eda Filippos Giannakos
        if self.rblocker and not r_hash:
111 c30635bf Filippos Giannakos
            block = self.fblocker.block_retr((blkhash,))
112 c30635bf Filippos Giannakos
            if not block:
113 c30635bf Filippos Giannakos
                return None, None
114 c30635bf Filippos Giannakos
            block = block[0]
115 c30635bf Filippos Giannakos
            newblock = block[:offset] + data
116 c30635bf Filippos Giannakos
            if len(newblock) > blocksize:
117 c30635bf Filippos Giannakos
                newblock = newblock[:blocksize]
118 c30635bf Filippos Giannakos
            elif len(newblock) < blocksize:
119 c30635bf Filippos Giannakos
                newblock += block[len(newblock):]
120 c30635bf Filippos Giannakos
            r_hash, r_existed = self.rblocker.block_stor((newblock,))
121 c30635bf Filippos Giannakos
122 c30635bf Filippos Giannakos
        return f_hash, 1 if r_existed and f_existed else 0