Welcome, guest | Sign In | My Account | Store | Cart

The following recipe provides a simple simulation of secondary memory and is primarily designed to provide a driver interface to a virtual hard drive. The interface is simple and allows the simulation of IO errors. Also provided are methods that allow efficient storage are retrieval of a disk object on the computer's file system.

Python, 121 lines
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from random import random

################################################################################

class DiskDriver:

    # CONSTANTS
    MAX_BLOCKS = (2 ** 16)
    MAX_SIZE = (2 ** 16)
    MAX_WORD = (2 ** 16) - 1

    # Disk With Driver
    def __init__(self, blocks, size):
        assert type(blocks) is int and 1 <= blocks <= self.MAX_BLOCKS
        assert type(size) is int and 1 <= size <= self.MAX_SIZE
        self.__blocks = blocks
        self.__size = size
        self.__fail = float()
        self.__disk = dict()

    # Read A Block
    def read(self, block):
        assert type(block) is int and 1 <= block <= self.__blocks
        assert self.__fail <= random()
        if self.__disk.has_key(block):
            return self.__disk[block]
        else:
            return chr(0) * self.__size

    # Write A Block
    def write(self, block, data):
        assert type(block) is int and 1 <= block <= self.__blocks
        assert type(data) is str and len(data) == self.__size
        assert self.__fail <= random()
        self.__disk[block] = data

    # Erase A Block
    def erase(self, block):
        assert type(block) is int and 1 <= block <= self.__blocks
        assert self.__fail <= random()
        if self.__disk.has_key(block):
            del self.__disk[block]

    # Probability Of Failure
    def fail(self, probability):
        assert type(probability) is float and 0 <= probability <= 1
        self.__fail = float(int(probability * self.MAX_WORD)) / self.MAX_WORD

    # Dump To File
    def dump(self, name):
        assert type(name) is str
        pickle = file(name, 'wb')
        temp = self.__blocks - 1
        pickle.write(chr(temp >> 8) + chr(temp & 0xFF))
        temp = self.__size - 1
        pickle.write(chr(temp >> 8) + chr(temp & 0xFF))
        temp = int(self.__fail * self.MAX_WORD)
        pickle.write(chr(temp >> 8) + chr(temp & 0xFF))
        for key in self.__disk:
            temp = key - 1
            pickle.write(chr(temp >> 8) + chr(temp & 0xFF))
            pickle.write(self.__disk[key])
        pickle.close()

    # Load From File
    def load(self, name):
        assert type(name) is str
        pickle = file(name, 'rb')
        temp = pickle.read(2)
        assert len(temp) == 2
        self.__blocks = (ord(temp[0]) << 8) + (ord(temp[1]) + 1)
        temp = pickle.read(2)
        assert len(temp) == 2
        self.__size = (ord(temp[0]) << 8) + (ord(temp[1]) + 1)
        temp = pickle.read(2)
        assert len(temp) == 2
        self.__fail = float((ord(temp[0]) << 8) + ord(temp[1])) / self.MAX_WORD
        self.__disk = dict()
        while True:
            temp = pickle.read(2)
            if not temp:
                break
            assert len(temp) == 2
            key = (ord(temp[0]) << 8) + (ord(temp[1]) + 1)
            assert 1 <= key <= self.__blocks
            temp = pickle.read(self.__size)
            assert len(temp) == self.__size
            self.__disk[key] = temp
        pickle.close()

    # Test If Equal
    def __eq__(self, other):
        try:
            assert self.__blocks == other.__blocks
            assert self.__size == other.__size
            assert self.__fail == other.__fail
            assert len(self.__disk) == len(other.__disk)
            for key in self.__disk:
                assert self.__disk[key] == other.__disk[key]
            return True
        except:
            return False

################################################################################

def test():
    from os import remove, urandom
    from random import randint
    test = DiskDriver(1024, 1024)
    for temp in range(512):
        test.write(randint(1, 1024), urandom(1024))
    test.dump('temp')
    other = DiskDriver(1, 1)
    other.load('temp')
    remove('temp')
    raw_input('Tested To ' + str(test == other))

################################################################################

if __name__ == '__main__':
    test()

This file is part of a series of files designed to implement a file system from scratch.