Решение на In-memory файлова система от Георги Димов

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

Към профила на Георги Димов

Резултати

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

Код

class FileSystemError(Exception):
def __init__(self, message=''):
self.message = message
class DestinationNodeExistsError(FileSystemError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class NotAMountPointError:
pass
class NotEnoughSpaceError(FileSystemError):
pass
class FileSystemDirectoryError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemDirectoryError):
pass
class NonEmptyDirectoryDeletionError(FileSystemDirectoryError):
pass
class DestinationNotADirectoryError(FileSystemDirectoryError):
pass
class DestinationNodeExistError(FileSystemDirectoryError):
pass
class FileSystemLinkError(FileSystemError):
pass
class DirectoryHardLinkError(FileSystemLinkError):
pass
class BaseFile:
def __init__(self, is_directory):
self.is_directory = is_directory
class File(BaseFile):
def __init__(self, content):
BaseFile.__init__(self, False)
self.content = content
def __getattr__(self, name):
if name == 'size':
return len(self.content) + 1
def append(self, text):
self.content += text
def truncate(self, text):
self.content = text
class Directory(BaseFile):
def __init__(self):
BaseFile.__init__(self, True)
self.files_pool = {}
self.dirs_pool = {}
def __getattribute__(self, name):
def get_objects(name):
return list(object.__getattribute__(self, name).values())
def get_pool(name):
return object.__getattribute__(self, name)
attributes = {
'files': get_objects('files_pool'),
'directories': get_objects('dirs_pool'),
'nodes': get_objects('files_pool') + get_objects('dirs_pool'),
'nodes_pool': dict(get_pool('files_pool'), **get_pool('dirs_pool'))
}
if name in attributes:
return attributes[name]
else:
return BaseFile.__getattribute__(self, name)
def __getattr__(self, name):
def get_size():
size = 1
for current_file in self.files:
size += current_file.size
for current_directory in self.directories:
size += current_directory.size
return size
attributes = {
'size': get_size()
}
return attributes['size']
def __getitem__(self, current_object):
if current_object in self.nodes_pool:
return self.nodes_pool[current_object]
else:
raise NodeDoesNotExistError
def add_file(self, file_name, file_object):
self.files_pool.update({file_name: file_object})
def add_directory(self, directory_name, directory_object):
self.dirs_pool.update({directory_name: directory_object})
def remove(self, object_to_remove, directory=False, force=True):
if object_to_remove not in self.nodes_pool:
raise NodeDoesNotExistError
if object_to_remove in self.dirs_pool:
if not directory:
raise NonExplicitDirectoryDeletionError
if not self.dirs_pool[object_to_remove].nodes == [] and not force:
raise NonEmptyDirectoryDeletionError
del self.dirs_pool[object_to_remove]
else:
del self.files_pool[object_to_remove]
class BaseLink:
def __init__(self, link_path, symbolic=True):
self.link_path = link_path
self.symbolic = symbolic
class SymbolicLink(BaseLink):
def __init__(self, link_path):
BaseLink.__init__(self, link_path)
class HardLink(BaseLink):
def __init__(self, link_path, symbolic):
BaseLink.__init__(self, link_path, symbolic)
class FileSystem:
def __init__(self, size):
if not size > 0:
raise NotEnoughSpaceError
self.home = Directory()
self.size = size
self.available_size = self.size - self.home.size
def __find_object(self, current_directory, path):
if path.count('/') < 2:
if len(path) > 1:
current_object = path.split('/')[-1]
return current_directory[current_object]
else:
return current_directory
else:
current_path, rest_path = path.lstrip('/').split('/', 1)
current_directory = current_directory[current_path.lstrip('/')]
return self.__find_object(current_directory, '/' + rest_path)
def get_node(self, path):
if path == '':
raise NodeDoesNotExistError
else:
return self.__find_object(self.home, path)
def create(self, path, directory=False, content=''):
current_path, object_name = path.rsplit('/', 1)
try:
parent_directory = self.__find_object(self.home, current_path)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
try:
self.get_node(path)
except NodeDoesNotExistError:
pass
else:
raise DestinationNodeExistsError
if not directory:
new_file = File(content)
new_object_size = new_file.size
if not self.available_size - new_object_size >= 0:
raise NotEnoughSpaceError
parent_directory.add_file(object_name, new_file)
else:
new_directory = Directory()
new_object_size = new_directory.size
if not self.available_size - new_object_size >= 0:
raise NotEnoughSpaceError
parent_directory.add_directory(object_name, new_directory)
self.available_size -= new_object_size
def remove(self, path, directory=False, force=True):
parent_directory_path, object_name = path.rsplit('/', 1)
parent_directory = self.get_node(parent_directory_path + '/')
object_size = self.get_node(path).size
parent_directory.remove(object_name, directory=directory, force=force)
self.available_size += object_size
def move(self, source, destination):
try:
self.get_node(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError
try:
self.get_node(destination)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if not self.get_node(destination).is_directory:
raise DestinationNotADirectoryError
destination_directory = self.get_node(destination)
source_parent_path, source_name = source.rsplit('/', 1)
source_parent_directory = self.get_node(source_parent_path + '/')
object_to_move = source_parent_directory[source_name]
try:
self.get_node(destination.rstrip('/') + '/' + source_name)
except NodeDoesNotExistError:
pass
else:
raise DestinationNodeExistsError
if object_to_move.is_directory:
destination_directory.add_directory(source_name, object_to_move)
source_parent_directory.remove(source_name, True, True)
else:
destination_directory.add_file(source_name, object_to_move)
source_parent_directory.remove(source_name)
def link(self, source, destination, symbolic=True):
if symbolic:
self.get_node(source)
parent_path, link_name = destination.rsplit('/', 1)
else:
source_object = self.get_node(source)
if source_object.is_directory:
raise DirectoryHardLinkError
def mount(self, file_system, path):
try:
mount_point = self.get_node(path)
except NodeDoesNotExistError:
raise MountPointDoesNotExistError
if not mount_point.is_directory:
raise MountPointNotADirectoryError
if not mount_point.nodes == []:
raise MountPointNotEmptyError
parent_directory_path, mount_point_name = path.rsplit('/', 1)
parent_directory = self.get_node(parent_directory_path + '/')
file_system_root = file_system.get_node('/')
parent_directory.add_directory(mount_point_name, file_system_root)
def unmount(self, path):
mount_point = self.get_node(path)
if not mount_point.is_directory:
raise NotAMountPointError
parent_path, mount_name = path.rsplit('/', 1)
mount_point_parent_directory = self.get_node(parent_path + '/')
mount_point_parent_directory.remove(mount_name, True, True)
mount_point_parent_directory.add_directory(mount_name, Directory())

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

..EE..E......E.EE.
======================================================================
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_hard_link_space_consumption (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.202s

FAILED (errors=6)

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

Георги обнови решението на 30.04.2015 02:56 (преди над 9 години)

+class FileSystemError(Exception):
+ def __init__(self, message=''):
+ self.message = message
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class NotAMountPointError:
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class FileSystemDirectoryError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemDirectoryError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemDirectoryError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemDirectoryError):
+ pass
+
+
+class DestinationNodeExistError(FileSystemDirectoryError):
+ pass
+
+
+class FileSystemLinkError(FileSystemError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemLinkError):
+ pass
+
+
+class BaseFile:
+ def __init__(self, is_directory):
+ self.is_directory = is_directory
+
+
+class File(BaseFile):
+ def __init__(self, content):
+ BaseFile.__init__(self, False)
+ self.content = content
+
+ def __getattr__(self, name):
+ if name == 'size':
+ return len(self.content) + 1
+
+ def append(self, text):
+ self.content += text
+
+ def truncate(self, text):
+ self.content = text
+
+
+class Directory(BaseFile):
+ def __init__(self):
+ BaseFile.__init__(self, True)
+ self.files_pool = {}
+ self.dirs_pool = {}
+
+ def __getattribute__(self, name):
+ def get_objects(name):
+ return list(object.__getattribute__(self, name).values())
+
+ def get_pool(name):
+ return object.__getattribute__(self, name)
+
+ attributes = {
+ 'files': get_objects('files_pool'),
+ 'directories': get_objects('dirs_pool'),
+ 'nodes': get_objects('files_pool') + get_objects('dirs_pool'),
+ 'nodes_pool': dict(get_pool('files_pool'), **get_pool('dirs_pool'))
+ }
+
+ if name in attributes:
+ return attributes[name]
+ else:
+ return BaseFile.__getattribute__(self, name)
+
+ def __getattr__(self, name):
+ def get_size():
+ size = 1
+
+ for current_file in self.files:
+ size += current_file.size
+
+ for current_directory in self.directories:
+ size += current_directory.size
+
+ return size
+
+ attributes = {
+ 'size': get_size()
+ }
+
+ return attributes['size']
+
+ def __getitem__(self, current_object):
+ if current_object in self.nodes_pool:
+ return self.nodes_pool[current_object]
+ else:
+ raise NodeDoesNotExistError
+
+ def add_file(self, file_name, file_object):
+ self.files_pool.update({file_name: file_object})
+
+ def add_directory(self, directory_name, directory_object):
+ self.dirs_pool.update({directory_name: directory_object})
+
+ def remove(self, object_to_remove, directory=False, force=True):
+ if object_to_remove not in self.nodes_pool:
+ raise NodeDoesNotExistError
+
+ if object_to_remove in self.dirs_pool:
+ if not directory:
+ raise NonExplicitDirectoryDeletionError
+
+ if not self.dirs_pool[object_to_remove].nodes == [] and not force:
+ raise NonEmptyDirectoryDeletionError
+
+ del self.dirs_pool[object_to_remove]
+ else:
+ del self.files_pool[object_to_remove]
+
+
+class BaseLink:
+ def __init__(self, link_path, symbolic=True):
+ self.link_path = link_path
+ self.symbolic = symbolic
+
+
+class SymbolicLink(BaseLink):
+ def __init__(self, link_path):
+ BaseLink.__init__(self, link_path)
+
+
+class HardLink(BaseLink):
+ def __init__(self, link_path, symbolic):
+ BaseLink.__init__(self, link_path, symbolic)
+
+
+class FileSystem:
+ def __init__(self, size):
+ if not size > 0:
+ raise NotEnoughSpaceError
+
+ self.home = Directory()
+ self.size = size
+ self.available_size = self.size - self.home.size
+
+ def __find_object(self, current_directory, path):
+ if path.count('/') < 2:
+ if len(path) > 1:
+ current_object = path.split('/')[-1]
+ return current_directory[current_object]
+ else:
+ return current_directory
+ else:
+ current_path, rest_path = path.lstrip('/').split('/', 1)
+ current_directory = current_directory[current_path.lstrip('/')]
+ return self.__find_object(current_directory, '/' + rest_path)
+
+ def get_node(self, path):
+ if path == '':
+ raise NodeDoesNotExistError
+ else:
+ return self.__find_object(self.home, path)
+
+ def create(self, path, directory=False, content=''):
+ current_path, object_name = path.rsplit('/', 1)
+
+ try:
+ parent_directory = self.__find_object(self.home, current_path)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+
+ try:
+ self.get_node(path)
+ except NodeDoesNotExistError:
+ pass
+ else:
+ raise DestinationNodeExistsError
+
+ if not directory:
+ new_file = File(content)
+ new_object_size = new_file.size
+
+ if not self.available_size - new_object_size >= 0:
+ raise NotEnoughSpaceError
+
+ parent_directory.add_file(object_name, new_file)
+ else:
+ new_directory = Directory()
+ new_object_size = new_directory.size
+
+ if not self.available_size - new_object_size >= 0:
+ raise NotEnoughSpaceError
+ parent_directory.add_directory(object_name, new_directory)
+
+ self.available_size -= new_object_size
+
+ def remove(self, path, directory=False, force=True):
+ parent_directory_path, object_name = path.rsplit('/', 1)
+ parent_directory = self.get_node(parent_directory_path + '/')
+
+ object_size = self.get_node(path).size
+
+ parent_directory.remove(object_name, directory=directory, force=force)
+
+ self.available_size += object_size
+
+ def move(self, source, destination):
+ try:
+ self.get_node(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+
+ try:
+ self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+
+ if not self.get_node(destination).is_directory:
+ raise DestinationNotADirectoryError
+
+ destination_directory = self.get_node(destination)
+
+ source_parent_path, source_name = source.rsplit('/', 1)
+ source_parent_directory = self.get_node(source_parent_path + '/')
+
+ object_to_move = source_parent_directory[source_name]
+
+ try:
+ self.get_node(destination.rstrip('/') + '/' + source_name)
+ except NodeDoesNotExistError:
+ pass
+ else:
+ raise DestinationNodeExistsError
+
+ if object_to_move.is_directory:
+ destination_directory.add_directory(source_name, object_to_move)
+ source_parent_directory.remove(source_name, True, True)
+ else:
+ destination_directory.add_file(source_name, object_to_move)
+ source_parent_directory.remove(source_name)
+
+ def link(self, source, destination, symbolic=True):
+ if symbolic:
+ self.get_node(source)
+ parent_path, link_name = destination.rsplit('/', 1)
+ else:
+ source_object = self.get_node(source)
+ if source_object.is_directory:
+ raise DirectoryHardLinkError
+
+ def mount(self, file_system, path):
+ try:
+ mount_point = self.get_node(path)
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+
+ if not mount_point.is_directory:
+ raise MountPointNotADirectoryError
+
+ if not mount_point.nodes == []:
+ raise MountPointNotEmptyError
+
+ parent_directory_path, mount_point_name = path.rsplit('/', 1)
+ parent_directory = self.get_node(parent_directory_path + '/')
+ file_system_root = file_system.get_node('/')
+
+ parent_directory.add_directory(mount_point_name, file_system_root)
+
+ def unmount(self, path):
+ mount_point = self.get_node(path)
+
+ if not mount_point.is_directory:
+ raise NotAMountPointError
+
+ parent_path, mount_name = path.rsplit('/', 1)
+
+ mount_point_parent_directory = self.get_node(parent_path + '/')
+ mount_point_parent_directory.remove(mount_name, True, True)
+
+ mount_point_parent_directory.add_directory(mount_name, Directory())