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

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

Към профила на Станислав Гатев

Резултати

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

Код

class FileSystemError(Exception):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class DestinationNodeExistsError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class NotAMountpointError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class DirectoryHardLinkError(FileSystemError):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
pass
class DestinationNotADirectoryError(FileSystemError):
pass
class LinkPathError(FileSystemError):
pass
class Node(object):
def __init__(self, parent, name, item, mounted=False):
self.parent = parent
self._name = name
self._item = item
self._mounted = mounted
@property
def size(self):
return 1 + self.item.size
@property
def available_size(self):
return -self.size
@property
def name(self):
return self._name
@property
def item(self):
return self._item
@property
def mounted(self):
return self._mounted
def remove(self, directory, force):
if self.item.is_directory and not directory:
raise NonExplicitDirectoryDeletionError
if self.item.is_directory and len(self.item.nodes) > 0 and not force:
raise NonEmptyDirectoryDeletionError
self.parent.item.remove_child(self.name)
class File(object):
def __init__(self, content):
self._content = content
@property
def is_directory(self):
return False
@property
def size(self):
return len(self.content)
@property
def content(self):
return self._content
@property
def is_file_system(self):
return False
def append(self, text):
self._content += text
def truncate(self, text):
self._content = text
class Directory(object):
def __init__(self):
self.children = {}
@property
def is_directory(self):
return True
@property
def size(self):
return sum(map(lambda child: child.size, self.children.values()))
@property
def directories(self):
return [child.item for child in self.children.values()
if child.item.is_directory]
@property
def files(self):
return [child.item for child in self.children.values()
if not child.item.is_directory]
@property
def nodes(self):
return [child.item for child in self.children.values()]
@property
def is_file_system(self):
return False
def get_child(self, components):
if len(components) == 0:
raise NodeDoesNotExistError
child = self.children.get(components[0], None)
if child is None:
raise NodeDoesNotExistError
if len(components) == 1:
return child
else:
return child.item.get_child(components[1:])
def add_child(self, name, node):
if name in self.children:
raise DestinationNodeExistsError
self.children[name] = node
def remove_child(self, name):
del self.children[name]
class SymbolicLink(object):
def __init__(self, link):
self._link = link
@property
def link_path(self):
return self._link
@property
def size(self):
return 0
@property
def is_file_system(self):
return False
def __getattr__(self, name):
try:
return getattr(self._link, name)
except Exception:
raise LinkPathError
class FileSystem(object):
def __init__(self, size):
self.total_size = size
self._root = Node(None, None, Directory())
@property
def root(self):
return self._root.item
@property
def is_file_system(self):
return True
@property
def size(self):
return self.total_size
@property
def available_size(self):
return self.total_size + self._root.available_size
def get_node(self, path):
return self._get_node_internal(path).item
def get_child(self, components):
if len(components) == 0:
return self._root
return self._root.item.get_child(components)
def create(self, path, directory=False, content=''):
_, *components, name = path.split('/')
try:
parent = self.get_child(components)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if directory:
self._create(parent, name, Directory())
else:
self._create(parent, name, File(content))
def remove(self, path, directory=False, force=True):
node = self._get_node_internal(path)
node.remove(directory, force)
def mount(self, file_system, path):
try:
dir = self._get_node_internal(path)
except NodeDoesNotExistError:
raise MountPointDoesNotExistError
if not dir.item.is_directory:
raise MountPointNotADirectoryError
if len(dir.item.nodes) > 0:
raise MountPointNotEmptyError
self.remove(path, True, True)
mounted_node = Node(dir.parent, dir.name,
file_system.get_node('/'), mounted=True)
dir.parent.item.add_child(dir.name, mounted_node)
def unmount(self, path):
node = self._get_node_internal(path)
if not node.mounted:
raise NotAMountpointError
node.parent.item.remove_child(node.name)
empty_dir = Node(node.parent, node.name, Directory())
node.parent.item.add_child(node.name, empty_dir)
def link(self, source, destination, symbolic=True):
try:
node = self.get_node(source)
except NodeDoesNotExistError:
if symbolic:
raise NodeDoesNotExistError
else:
raise SourceNodeDoesNotExistError
if node.is_directory and not symbolic:
raise DirectoryHardLinkError
_, *components, name = destination.split('/')
parent = self.get_child(components)
self._create(parent, name, SymbolicLink(node))
def move(self, source, destination):
try:
node = self._get_node_internal(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError
try:
dest = self.get_node(destination)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if not dest.is_directory:
raise DestinationNotADirectoryError
self.remove(source, node.item.is_directory, True)
dest.add_child(node.name, Node(dest, node.name, node.item))
def _create(self, parent, name, entry):
node = Node(parent, name, entry)
if self.available_size < node.size:
raise NotEnoughSpaceError
parent.item.add_child(name, node)
def _get_node_internal(self, path):
if not path:
raise NodeDoesNotExistError
if path == '/':
return self._root
components = path.split('/')
return self.get_child(components[1:])

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

.E......E.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_mounting (test.TestFileSystem)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "lib/language/python/runner.py", line 65, in thread
    raise TimeoutError
TimeoutError

======================================================================
ERROR: test_move_overwrite (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.243s

FAILED (errors=6)

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

Станислав обнови решението на 29.04.2015 16:53 (преди над 9 години)

+class FileSystemError(Exception):
+ pass
+
+
+class NotEnoughSpaceError(FileSystemError):
+ pass
+
+
+class NodeDoesNotExistError(FileSystemError):
+ pass
+
+
+class DestinationNodeExistsError(FileSystemError):
+ pass
+
+
+class NonExplicitDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class SourceNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
+ pass
+
+
+class FileSystemMountError(FileSystemError):
+ pass
+
+
+class MountPointDoesNotExistError(FileSystemMountError):
+ pass
+
+
+class MountPointNotADirectoryError(FileSystemMountError):
+ pass
+
+
+class NotAMountpointError(FileSystemMountError):
+ pass
+
+
+class MountPointNotEmptyError(FileSystemMountError):
+ pass
+
+
+class DirectoryHardLinkError(FileSystemError):
+ pass
+
+
+class NonEmptyDirectoryDeletionError(FileSystemError):
+ pass
+
+
+class DestinationNotADirectoryError(FileSystemError):
+ pass
+
+
+class LinkPathError(FileSystemError):
+ pass
+
+
+class Node(object):
+
+ def __init__(self, parent, name, item, mounted=False):
+ self.parent = parent
+ self._name = name
+ self._item = item
+ self._mounted = mounted
+
+ @property
+ def name(self):
+ return self._name
+
+ @property
+ def item(self):
+ return self._item
+
+ @property
+ def mounted(self):
+ return self._mounted
+
+ def remove(self, directory, force):
+ if self.item.is_directory and not directory:
+ raise NonExplicitDirectoryDeletionError
+ if self.item.is_directory and len(self.item.nodes) > 0 and not force:
+ raise NonEmptyDirectoryDeletionError
+ self.parent.item.remove_child(self.name)
+
+
+class File(object):
+
+ def __init__(self, content):
+ self._content = content
+
+ @property
+ def is_directory(self):
+ return False
+
+ @property
+ def size(self):
+ return 1 + len(self.content)
+
+ @property
+ def content(self):
+ return self._content
+
+ @property
+ def is_file_system(self):
+ return False
+
+ def append(self, text):
+ self._content += text
+
+ def truncate(self, text):
+ self._content = text
+
+
+class Directory(object):
+
+ def __init__(self):
+ self.children = {}
+
+ @property
+ def is_directory(self):
+ return True
+
+ @property
+ def size(self):
+ return 1 + sum(map(lambda child: child.item.size,
+ self.children.values()))
+
+ @property
+ def directories(self):
+ return [child.item for child in self.children.values()
+ if child.item.is_directory]
+
+ @property
+ def files(self):
+ return [child.item for child in self.children.values()
+ if not child.item.is_directory]
+
+ @property
+ def nodes(self):
+ return [child.item for child in self.children.values()]
+
+ @property
+ def is_file_system(self):
+ return False
+
+ def get_child(self, components):
+ if len(components) == 0:
+ raise NodeDoesNotExistError
+
+ child = self.children.get(components[0], None)
+ if child is None:
+ raise NodeDoesNotExistError
+
+ if len(components) == 1:
+ return child
+ else:
+ return child.item.get_child(components[1:])
+
+ def add_child(self, name, node):
+ if name in self.children:
+ raise DestinationNodeExistsError
+ self.children[name] = node
+
+ def remove_child(self, name):
+ del self.children[name]
+
+
+class SymbolicLink(object):
+
+ def __init__(self, link):
+ self._link = link
+
+ @property
+ def link_path(self):
+ return self._link
+
+ @property
+ def size(self):
+ return 1
+
+ @property
+ def is_file_system(self):
+ return False
+
+ def __getattr__(self, name):
+ try:
+ return getattr(self._link, name)
+ except Exception:
+ raise LinkPathError
+
+
+class FileSystem(object):
+
+ def __init__(self, size):
+ self.total_size = size
+ self._root = Node(None, None, Directory())
+
+ @property
+ def root(self):
+ return self._root.item
+
+ @property
+ def is_file_system(self):
+ return True
+
+ @property
+ def size(self):
+ return self.total_size
+
+ @property
+ def available_size(self):
+ return self.total_size - self._root.item.size
+
+ def get_node(self, path):
+ return self._get_node_internal(path).item
+
+ def get_child(self, components):
+ if len(components) == 0:
+ return self._root
+ return self._root.item.get_child(components)
+
+ def create(self, path, directory=False, content=''):
+ _, *components, name = path.split('/')
+ try:
+ parent = self.get_child(components)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if directory:
+ self._create(parent, name, Directory())
+ else:
+ self._create(parent, name, File(content))
+
+ def remove(self, path, directory=False, force=True):
+ node = self._get_node_internal(path)
+ node.remove(directory, force)
+
+ def mount(self, file_system, path):
+ try:
+ dir = self._get_node_internal(path)
+ except NodeDoesNotExistError:
+ raise MountPointDoesNotExistError
+ if not dir.item.is_directory:
+ raise MountPointNotADirectoryError
+ if len(dir.item.nodes) > 0:
+ raise MountPointNotEmptyError
+ self.remove(path, True, True)
+ mounted_node = Node(dir.parent, dir.name,
+ file_system.get_node('/'), mounted=True)
+ dir.parent.item.add_child(dir.name, mounted_node)
+
+ def unmount(self, path):
+ node = self._get_node_internal(path)
+ if not node.mounted:
+ raise NotAMountpointError
+ node.parent.item.remove_child(node.name)
+ empty_dir = Node(node.parent, node.name, Directory())
+ node.parent.item.add_child(node.name, empty_dir)
+
+ def link(self, source, destination, symbolic=True):
+ try:
+ node = self.get_node(source)
+ except NodeDoesNotExistError:
+ if symbolic:
+ raise NodeDoesNotExistError
+ else:
+ raise SourceNodeDoesNotExistError
+ if node.is_directory and not symbolic:
+ raise DirectoryHardLinkError
+ _, *components, name = destination.split('/')
+ parent = self.get_child(components)
+ self._create(parent, name, SymbolicLink(node))
+
+ def move(self, source, destination):
+ try:
+ node = self._get_node_internal(source)
+ except NodeDoesNotExistError:
+ raise SourceNodeDoesNotExistError
+ try:
+ dest = self.get_node(destination)
+ except NodeDoesNotExistError:
+ raise DestinationNodeDoesNotExistError
+ if not dest.is_directory:
+ raise DestinationNotADirectoryError
+ self.remove(source, node.item.is_directory, True)
+ dest.add_child(node.name, Node(dest, node.name, node.item))
+
+ def _create(self, parent, name, entry):
+ if self.available_size < entry.size:
+ raise NotEnoughSpaceError
+ parent.item.add_child(name, Node(parent, name, entry))
+
+ def _get_node_internal(self, path):
+ if not path:
+ raise NodeDoesNotExistError
+ if path == '/':
+ return self._root
+ components = path.split('/')
+ return self.get_child(components[1:])

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

class FileSystemError(Exception):
pass
class NotEnoughSpaceError(FileSystemError):
pass
class NodeDoesNotExistError(FileSystemError):
pass
class DestinationNodeExistsError(FileSystemError):
pass
class NonExplicitDirectoryDeletionError(FileSystemError):
pass
class SourceNodeDoesNotExistError(NodeDoesNotExistError):
pass
class DestinationNodeDoesNotExistError(NodeDoesNotExistError):
pass
class FileSystemMountError(FileSystemError):
pass
class MountPointDoesNotExistError(FileSystemMountError):
pass
class MountPointNotADirectoryError(FileSystemMountError):
pass
class NotAMountpointError(FileSystemMountError):
pass
class MountPointNotEmptyError(FileSystemMountError):
pass
class DirectoryHardLinkError(FileSystemError):
pass
class NonEmptyDirectoryDeletionError(FileSystemError):
pass
class DestinationNotADirectoryError(FileSystemError):
pass
class LinkPathError(FileSystemError):
pass
class Node(object):
def __init__(self, parent, name, item, mounted=False):
self.parent = parent
self._name = name
self._item = item
self._mounted = mounted
@property
+ def size(self):
+ return 1 + self.item.size
+
+ @property
+ def available_size(self):
+ return -self.size
+
+ @property
def name(self):
return self._name
@property
def item(self):
return self._item
@property
def mounted(self):
return self._mounted
def remove(self, directory, force):
if self.item.is_directory and not directory:
raise NonExplicitDirectoryDeletionError
if self.item.is_directory and len(self.item.nodes) > 0 and not force:
raise NonEmptyDirectoryDeletionError
self.parent.item.remove_child(self.name)
class File(object):
def __init__(self, content):
self._content = content
@property
def is_directory(self):
return False
@property
def size(self):
- return 1 + len(self.content)
+ return len(self.content)
@property
def content(self):
return self._content
@property
def is_file_system(self):
return False
def append(self, text):
self._content += text
def truncate(self, text):
self._content = text
class Directory(object):
def __init__(self):
self.children = {}
@property
def is_directory(self):
return True
@property
def size(self):
- return 1 + sum(map(lambda child: child.item.size,
- self.children.values()))
+ return sum(map(lambda child: child.size, self.children.values()))
@property
def directories(self):
return [child.item for child in self.children.values()
if child.item.is_directory]
@property
def files(self):
return [child.item for child in self.children.values()
if not child.item.is_directory]
@property
def nodes(self):
return [child.item for child in self.children.values()]
@property
def is_file_system(self):
return False
def get_child(self, components):
if len(components) == 0:
raise NodeDoesNotExistError
child = self.children.get(components[0], None)
if child is None:
raise NodeDoesNotExistError
if len(components) == 1:
return child
else:
return child.item.get_child(components[1:])
def add_child(self, name, node):
if name in self.children:
raise DestinationNodeExistsError
self.children[name] = node
def remove_child(self, name):
del self.children[name]
class SymbolicLink(object):
def __init__(self, link):
self._link = link
@property
def link_path(self):
return self._link
@property
def size(self):
- return 1
+ return 0
@property
def is_file_system(self):
return False
def __getattr__(self, name):
try:
return getattr(self._link, name)
except Exception:
raise LinkPathError
class FileSystem(object):
def __init__(self, size):
self.total_size = size
self._root = Node(None, None, Directory())
@property
def root(self):
return self._root.item
@property
def is_file_system(self):
return True
@property
def size(self):
return self.total_size
@property
def available_size(self):
- return self.total_size - self._root.item.size
+ return self.total_size + self._root.available_size
def get_node(self, path):
return self._get_node_internal(path).item
def get_child(self, components):
if len(components) == 0:
return self._root
return self._root.item.get_child(components)
def create(self, path, directory=False, content=''):
_, *components, name = path.split('/')
try:
parent = self.get_child(components)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if directory:
self._create(parent, name, Directory())
else:
self._create(parent, name, File(content))
def remove(self, path, directory=False, force=True):
node = self._get_node_internal(path)
node.remove(directory, force)
def mount(self, file_system, path):
try:
dir = self._get_node_internal(path)
except NodeDoesNotExistError:
raise MountPointDoesNotExistError
if not dir.item.is_directory:
raise MountPointNotADirectoryError
if len(dir.item.nodes) > 0:
raise MountPointNotEmptyError
self.remove(path, True, True)
mounted_node = Node(dir.parent, dir.name,
file_system.get_node('/'), mounted=True)
dir.parent.item.add_child(dir.name, mounted_node)
def unmount(self, path):
node = self._get_node_internal(path)
if not node.mounted:
raise NotAMountpointError
node.parent.item.remove_child(node.name)
empty_dir = Node(node.parent, node.name, Directory())
node.parent.item.add_child(node.name, empty_dir)
def link(self, source, destination, symbolic=True):
try:
node = self.get_node(source)
except NodeDoesNotExistError:
if symbolic:
raise NodeDoesNotExistError
else:
raise SourceNodeDoesNotExistError
if node.is_directory and not symbolic:
raise DirectoryHardLinkError
_, *components, name = destination.split('/')
parent = self.get_child(components)
self._create(parent, name, SymbolicLink(node))
def move(self, source, destination):
try:
node = self._get_node_internal(source)
except NodeDoesNotExistError:
raise SourceNodeDoesNotExistError
try:
dest = self.get_node(destination)
except NodeDoesNotExistError:
raise DestinationNodeDoesNotExistError
if not dest.is_directory:
raise DestinationNotADirectoryError
self.remove(source, node.item.is_directory, True)
dest.add_child(node.name, Node(dest, node.name, node.item))
def _create(self, parent, name, entry):
- if self.available_size < entry.size:
+ node = Node(parent, name, entry)
+ if self.available_size < node.size:
raise NotEnoughSpaceError
- parent.item.add_child(name, Node(parent, name, entry))
+ parent.item.add_child(name, node)
def _get_node_internal(self, path):
if not path:
raise NodeDoesNotExistError
if path == '/':
return self._root
components = path.split('/')
return self.get_child(components[1:])