Решение на In-memory файлова система от Валентин Латунов

Обратно към всички решения

Към профила на Валентин Латунов

Резултати

  • 8 точки от тестове
  • 0 бонус точки
  • 8 точки общо
  • 12 успешни тест(а)
  • 6 неуспешни тест(а)

Код

class FileSystemError(Exception):
pass
class LinkPathError(FileSystemError):
pass
class DirectoryHardLinkError(FileSystemError):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeExistsError(FileSystemError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNotADirectoryError(FileSystemError):
pass
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class SystemNode:
def __init__(self, is_directory):
self.__is_directory = is_directory
@property
def is_directory(self):
return self.__is_directory
class SystemFile(SystemNode):
def __init__(self, data, file_sys):
super().__init__(False)
self.__data = data
self.__file_sys = file_sys
def __repr__(self):
return self.__data
@property
def content(self):
return self.__data
@property
def size(self):
return len(self.__data)
def append(self, text):
FS = self.__file_sys
if FS.available_size - len(text) < 0:
raise NotEnoughSpaceError
self.__data += text
def truncate(self, text):
FS = self.__file_sys
if FS.available_size - len(text) + len(self.__data) < 0:
raise NotEnoughSpaceError
self.__data = text
def taken_space(self):
return len(self.__data) + 1
def get_node(self, *args, **kwarg):
raise NodeDoesNotExistError
class SystemDirectory(SystemNode):
def __init__(self, file_sys):
super().__init__(True)
self.__dir = {}
self.__file_sys = file_sys
def __getitem__(self, index):
return self.__dir[sorted(list(self.__dir))[index]]
def __repr__(self):
return str(self.__dir)
@property
def directories(self):
return [val for key, val in self.__dir.items() if val.is_directory]
@property
def files(self):
return [val for key, val in self.__dir.items() if not val.is_directory]
@property
def nodes(self):
return [val for key, val in self.__dir.items()]
def get_node(self, name):
if name == '':
return self
elif name in self.__dir:
return self.__dir[name]
else:
raise NodeDoesNotExistError
def add_node(self, name, node):
if name == '':
raise SourceNodeDoesNotExistError
elif name in self.__dir:
raise DestinationNodeExistsError
else:
self.__dir[name] = node
def add_directory(self, name, file_sys):
if name == '' or name in self.__dir:
raise DestinationNodeExistsError
else:
self.__dir[name] = SystemDirectory(file_sys)
def add_file(self, name, data, file_sys):
if name == '':
raise DestinationNodeDoesNotExistError
elif name in self.__dir:
raise DestinationNodeExistsError
else:
self.__dir[name] = SystemFile(data, file_sys)
def add_link(self, name, node, symbolic, file_sys):
if name == '':
raise DestinationNodeDoesNotExistError
elif name in self.__dir:
raise DestinationNodeExistsError
else:
self.__dir[name] = SystemLink(node, symbolic, file_sys)
def remove_node(self, name):
if name == '' or name not in self.__dir:
raise NodeDoesNotExistError
else:
del self.__dir[name]
def taken_space(self):
to_return = 1
for node in self.__dir:
to_return += self.__dir[node].taken_space()
return to_return
class SystemLink(SystemNode):
def __init__(self, link_path, symbolic, file_sys):
super().__init__(False)
self.__link_path = link_path
self.__symbolic = symbolic
self.__file_sys = file_sys
@property
def link_path(self):
return self.__file_sys.get_node(self.__link_path)
@property
def content(self):
if self.__symbolic:
try:
return self.__file_sys.get_node(self.__link_path).content
except:
raise LinkPathError
else:
pass
@property
def files(self):
if self.__symbolic:
try:
return self.__file_sys.get_node(self.__link_path).files
except:
raise LinkPathError
else:
pass
@property
def nodes(self):
if self.__symbolic:
try:
return self.__file_sys.get_node(self.__link_path).nodes
except:
raise LinkPathError
else:
pass
@property
def directories(self):
if self.__symbolic:
try:
return self.__file_sys.get_node(self.__link_path).directories
except:
raise LinkPathError
else:
pass
def taken_space(self):
return 1
class FileSystem:
def __init__(self, size):
self.__size = size
self.__root = SystemDirectory(None)
def _set_root(self, directory):
self.__root = directory
@property
def size(self):
return self.__size
@property
def available_size(self):
return self.__size - self.__root.taken_space()
def get_node(self, path):
if len(path) == 0:
raise NodeDoesNotExistError
path_list = path.split('/')
to_return = self.__root
for name in path_list:
to_return = to_return.get_node(name)
return to_return
def create(self, path, *, directory=False, content=''):
path_list = path.split('/')
if len(path_list) < 2:
raise DestinationNodeDoesNotExistError
node = self.__root
try:
for name in path_list[:-1]:
node = node.get_node(name)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if node.is_directory:
Aval_space = self.available_size
if directory:
if Aval_space - 1 < 0:
raise NotEnoughSpaceError
else:
node.add_directory(path_list[-1], self)
else:
if Aval_space - len(content) - 1 < 0:
raise NotEnoughSpaceError
else:
node.add_file(path_list[-1], content, self)
else:
raise DestinationNodeDoesNotExistError
def remove(self, path, *, directory=False, force=True):
path_list = path.split('/')
if len(path_list) < 2:
raise NodeDoesNotExistError
node = self.__root
for name in path_list[:-1]:
node = node.get_node(name)
temp = node.get_node(path_list[-1])
if temp.is_directory:
if not directory:
raise NonExplicitDirectoryDeletionError
if len(temp.nodes) and not force:
raise NonEmptyDirectoryDeletionError
node.remove_node(path_list[-1])
def move(self, source, destination):
try:
source_node = self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError
try:
destination_node = self.get_node(destination)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if not destination_node.is_directory:
raise DestinationNotADirectoryError
destination_node.add_node(source.split('/')[-1], source_node)
self.remove(source, directory=source_node.is_directory)
def link(self, source, destination, *, symbolic=True):
try:
node = self.get_node(source)
except NodeDoesNotExistError:
if symbolic:
raise
else:
raise SourceNodeDoesNotExistError
if node.is_directory and not symbolic:
raise DirectoryHardLinkError
path_list = destination.split('/')
destination_node = self.__root
for name in path_list[:-1]:
destination_node = destination_node.get_node(name)
if destination_node.is_directory:
destination_node.add_link(path_list[-1], node, symbolic, self)
else:
raise DestinationNotADirectoryError
def mount(self, file_system, path):
try:
node = self.get_node(path)
except NodeDoesNotExistError:
raise MountPointDoesNotExistError
if node.is_directory:
if node.nodes:
raise MountPointNotEmptyError
else:
file_system._set_root(node)
else:
raise MountPointNotADirectoryError
def unmount(self, path):
pass

Лог от изпълнението

.EE...E......E.EE.
======================================================================
ERROR: test_create_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_hard_link_create (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_link_create (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_empty_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_remove_nonempty_directory (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_symlink_to_missing_file (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

----------------------------------------------------------------------
Ran 18 tests in 12.189s

FAILED (errors=6)

История (1 версия и 0 коментара)

Валентин обнови решението на 30.04.2015 16:13 (преди над 9 години)

+class FileSystemError(Exception):
+ pass
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class SystemNode:
+ def __init__(self, is_directory):
+ self.__is_directory = is_directory
+
+ @property
+ def is_directory(self):
+ return self.__is_directory
+
+
+class SystemFile(SystemNode):
+ def __init__(self, data, file_sys):
+ super().__init__(False)
+ self.__data = data
+ self.__file_sys = file_sys
+
+ def __repr__(self):
+ return self.__data
+
+ @property
+ def content(self):
+ return self.__data
+
+ @property
+ def size(self):
+ return len(self.__data)
+
+ def append(self, text):
+ FS = self.__file_sys
+ if FS.available_size - len(text) < 0:
+ raise NotEnoughSpaceError
+ self.__data += text
+
+ def truncate(self, text):
+ FS = self.__file_sys
+ if FS.available_size - len(text) + len(self.__data) < 0:
+ raise NotEnoughSpaceError
+ self.__data = text
+
+ def taken_space(self):
+ return len(self.__data) + 1
+
+ def get_node(self, *args, **kwarg):
+ raise NodeDoesNotExistError
+
+
+class SystemDirectory(SystemNode):
+ def __init__(self, file_sys):
+ super().__init__(True)
+ self.__dir = {}
+ self.__file_sys = file_sys
+
+ def __getitem__(self, index):
+ return self.__dir[sorted(list(self.__dir))[index]]
+
+ def __repr__(self):
+ return str(self.__dir)
+
+ @property
+ def directories(self):
+ return [val for key, val in self.__dir.items() if val.is_directory]
+
+ @property
+ def files(self):
+ return [val for key, val in self.__dir.items() if not val.is_directory]
+
+ @property
+ def nodes(self):
+ return [val for key, val in self.__dir.items()]
+
+ def get_node(self, name):
+ if name == '':
+ return self
+ elif name in self.__dir:
+ return self.__dir[name]
+ else:
+ raise NodeDoesNotExistError
+
+ def add_node(self, name, node):
+ if name == '':
+ raise SourceNodeDoesNotExistError
+ elif name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = node
+
+ def add_directory(self, name, file_sys):
+ if name == '' or name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = SystemDirectory(file_sys)
+
+ def add_file(self, name, data, file_sys):
+ if name == '':
+ raise DestinationNodeDoesNotExistError
+ elif name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = SystemFile(data, file_sys)
+
+ def add_link(self, name, node, symbolic, file_sys):
+ if name == '':
+ raise DestinationNodeDoesNotExistError
+ elif name in self.__dir:
+ raise DestinationNodeExistsError
+ else:
+ self.__dir[name] = SystemLink(node, symbolic, file_sys)
+
+ def remove_node(self, name):
+ if name == '' or name not in self.__dir:
+ raise NodeDoesNotExistError
+ else:
+ del self.__dir[name]
+
+ def taken_space(self):
+ to_return = 1
+ for node in self.__dir:
+ to_return += self.__dir[node].taken_space()
+ return to_return
+
+
+class SystemLink(SystemNode):
+ def __init__(self, link_path, symbolic, file_sys):
+ super().__init__(False)
+ self.__link_path = link_path
+ self.__symbolic = symbolic
+ self.__file_sys = file_sys
+
+ @property
+ def link_path(self):
+ return self.__file_sys.get_node(self.__link_path)
+
+ @property
+ def content(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).content
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ @property
+ def files(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).files
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ @property
+ def nodes(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).nodes
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ @property
+ def directories(self):
+ if self.__symbolic:
+ try:
+ return self.__file_sys.get_node(self.__link_path).directories
+ except:
+ raise LinkPathError
+ else:
+ pass
+
+ def taken_space(self):
+ return 1
+
+
+class FileSystem:
+ def __init__(self, size):
+ self.__size = size
+ self.__root = SystemDirectory(None)
+
+ def _set_root(self, directory):
+ self.__root = directory
+
+ @property
+ def size(self):
+ return self.__size
+
+ @property
+ def available_size(self):
+ return self.__size - self.__root.taken_space()
+
+ def get_node(self, path):
+ if len(path) == 0:
+ raise NodeDoesNotExistError
+ path_list = path.split('/')
+ to_return = self.__root
+ for name in path_list:
+ to_return = to_return.get_node(name)
+ return to_return
+
+ def create(self, path, *, directory=False, content=''):
+ path_list = path.split('/')
+ if len(path_list) < 2:
+ raise DestinationNodeDoesNotExistError
+ node = self.__root
+ try:
+ for name in path_list[:-1]:
+ node = node.get_node(name)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if node.is_directory:
+ Aval_space = self.available_size
+ if directory:
+ if Aval_space - 1 < 0:
+ raise NotEnoughSpaceError
+ else:
+ node.add_directory(path_list[-1], self)
+ else:
+ if Aval_space - len(content) - 1 < 0:
+ raise NotEnoughSpaceError
+ else:
+ node.add_file(path_list[-1], content, self)
+ else:
+ raise DestinationNodeDoesNotExistError
+
+ def remove(self, path, *, directory=False, force=True):
+ path_list = path.split('/')
+ if len(path_list) < 2:
+ raise NodeDoesNotExistError
+ node = self.__root
+ for name in path_list[:-1]:
+ node = node.get_node(name)
+ temp = node.get_node(path_list[-1])
+ if temp.is_directory:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+ if len(temp.nodes) and not force:
+ raise NonEmptyDirectoryDeletionError
+ node.remove_node(path_list[-1])
+
+ def move(self, source, destination):
+ try:
+ source_node = self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+ try:
+ destination_node = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if not destination_node.is_directory:
+ raise DestinationNotADirectoryError
+ destination_node.add_node(source.split('/')[-1], source_node)
+ self.remove(source, directory=source_node.is_directory)
+
+ def link(self, source, destination, *, symbolic=True):
+ try:
+ node = self.get_node(source)
+ except NodeDoesNotExistError:
+ if symbolic:
+ raise
+ else:
+ raise SourceNodeDoesNotExistError
+ if node.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+ path_list = destination.split('/')
+ destination_node = self.__root
+ for name in path_list[:-1]:
+ destination_node = destination_node.get_node(name)
+ if destination_node.is_directory:
+ destination_node.add_link(path_list[-1], node, symbolic, self)
+ else:
+ raise DestinationNotADirectoryError
+
+ def mount(self, file_system, path):
+ try:
+ node = self.get_node(path)
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+ if node.is_directory:
+ if node.nodes:
+ raise MountPointNotEmptyError
+ else:
+ file_system._set_root(node)
+ else:
+ raise MountPointNotADirectoryError
+
+ def unmount(self, path):
+ pass