Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (4 kB)

1
# Copyright 2011-2012 GRNET S.A. All rights reserved.
2
#
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
#
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
#
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
#
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
#
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
from archipelagoblocker import ArchipelagoBlocker
35

    
36

    
37
class Blocker(object):
38
    """Blocker.
39
       Required constructor parameters: blocksize, blockpath, hashtype.
40
       Optional blockpool.
41
    """
42

    
43
    def __init__(self, **params):
44
        self.archip_blocker = ArchipelagoBlocker(**params)
45
        self.hashlen = self.archip_blocker.hashlen
46
        self.blocksize = params['blocksize']
47

    
48
    def block_hash(self, data):
49
        """Hash a block of data"""
50
        return self.archip_blocker.block_hash(data)
51

    
52
    def block_ping(self, hashes):
53
        """Check hashes for existence and
54
           return those missing from block storage.
55
        """
56
        return self.archip_blocker.block_ping(hashes)
57

    
58
    def block_retr(self, hashes):
59
        """Retrieve blocks from storage by their hashes."""
60
        return self.archip_blocker.block_retr(hashes)
61

    
62
    def block_retr_archipelago(self, hashes):
63
        """Retrieve blocks from storage by theri hashes."""
64
        return self.archip_blocker.block_retr_archipelago(hashes)
65

    
66
    def block_stor(self, blocklist):
67
        """Store a bunch of blocks and return (hashes, missing).
68
           Hashes is a list of the hashes of the blocks,
69
           missing is a list of indices in that list indicating
70
           which blocks were missing from the store.
71
        """
72
        (hashes, missing) = self.archip_blocker.block_stor(blocklist)
73
        return (hashes, missing)
74

    
75
    def block_delta(self, blkhash, offset, data):
76
        """Construct and store a new block from a given block
77
           and a data 'patch' applied at offset. Return:
78
           (the hash of the new block, if the block already existed)
79
        """
80
        blocksize = self.blocksize
81
        archip_hash = None
82
        archip_existed = True
83
        (archip_hash, archip_existed) = \
84
                self.archip_blocker.block_delta(blkhash, offset, data)
85

    
86
        if not archip_hash:
87
            return None, None
88

    
89
        if self.archip_blocker and not archip_hash:
90
            block = self.archip_blocker.block_retr((blkhash,))
91
            if not block:
92
                return None, None
93
            block = block[0]
94
            newblock = block[:offset] + data
95
            if len(newblock) > blocksize:
96
                newblock = newblock[:blocksize]
97
            elif len(newblock) < blocksize:
98
                newblock += block[len(newblock):]
99
            archip_hash, archip_existed = self.rblocker.block_stor((newblock,))
100

    
101
        return archip_hash, 1 if archip_existed else 0