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.
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.
Tags: files