summaryrefslogtreecommitdiff
path: root/lib/git/odb/db.py
diff options
context:
space:
mode:
authorSebastian Thiel <byronimo@gmail.com>2010-06-02 23:53:29 +0200
committerSebastian Thiel <byronimo@gmail.com>2010-06-02 23:53:29 +0200
commit6f8ce8901e21587cd2320562df412e05b5ab1731 (patch)
tree4376f34c327896f7951bc1af7c7d93896decf863 /lib/git/odb/db.py
parent8b86f9b399a8f5af792a04025fdeefc02883f3e5 (diff)
downloadgitpython-6f8ce8901e21587cd2320562df412e05b5ab1731.tar.gz
added frame for object reading, including simple test
Diffstat (limited to 'lib/git/odb/db.py')
-rw-r--r--lib/git/odb/db.py76
1 files changed, 62 insertions, 14 deletions
diff --git a/lib/git/odb/db.py b/lib/git/odb/db.py
index 204da9ad..1248a3f4 100644
--- a/lib/git/odb/db.py
+++ b/lib/git/odb/db.py
@@ -1,9 +1,13 @@
"""Contains implementations of database retrieveing objects"""
import os
-from git.errors import InvalidDBRoot
+from git.errors import (
+ InvalidDBRoot,
+ BadObject
+ )
from git.utils import IndexFileSHA1Writer
from utils import (
+ getsize,
to_hex_sha,
exists,
hex_to_bin,
@@ -16,6 +20,7 @@ from utils import (
)
import tempfile
+import mmap
class iObjectDBR(object):
@@ -136,27 +141,70 @@ class LooseObjectDB(FileDBBase, iObjectDBR, iObjectDBW):
self._hexsha_to_file = dict()
#{ Interface
- def hexsha_to_object_path(self, hexsha):
+ def object_path(self, hexsha):
"""
:return: path at which the object with the given hexsha would be stored,
relative to the database root"""
return join(hexsha[:2], hexsha[2:])
- #} END interface
-
- def has_object(self, sha):
- sha = to_hex_sha(sha)
- # try cache
- if sha in self._hexsha_to_file:
- return True
+ def readable_db_object_path(self, hexsha):
+ """
+ :return: readable object path to the object identified by hexsha
+ :raise BadObject: If the object file does not exist"""
+ try:
+ return self._hexsha_to_file[hexsha]
+ except KeyError:
+ pass
+ # END ignore cache misses
# try filesystem
- path = self.db_path(self.hexsha_to_object_path(sha))
+ path = self.db_path(self.object_path(hexsha))
if exists(path):
- self._hexsha_to_file[sha] = path
- return True
+ self._hexsha_to_file[hexsha] = path
+ return path
# END handle cache
- return False
+ raise BadObject(hexsha)
+
+ #} END interface
+
+ def _object_header_info(self, mmap):
+ """:return: tuple(type_string, uncompressed_size_in_bytes
+ :param mmap: newly mapped memory map at position 0. It will be
+ seeked to the actual start of the object contents, which can be used
+ to initialize a zlib decompress object."""
+ raise NotImplementedError("todo")
+
+ def _map_object(self, sha):
+ """
+ :return: tuple(file, mmap) tuple with an opened file for reading, and
+ a memory map of that file"""
+ db_path = self.readable_db_object_path(to_hex_sha(sha))
+ f = open(db_path, 'rb')
+ m = mmap.mmap(f.fileno(), getsize(db_path), access=mmap.ACCESS_READ)
+ return (f, m)
+
+ def object_info(self, sha):
+ f, m = self._map_object(sha)
+ try:
+ type, size = self._object_header_info(m)
+ finally:
+ f.close()
+ m.close()
+ # END assure release of system resources
+
+ def object(self, sha):
+ f, m = self._map_object(sha)
+ type, size = self._object_header_info(m)
+ # TODO: init a dynamic decompress stream from our memory map
+
+
+ def has_object(self, sha):
+ try:
+ self.readable_db_object_path(to_hex_sha(sha))
+ return True
+ except BadObject:
+ return False
+ # END check existance
def to_object(self, type, size, stream, dry_run=False, sha_as_hex=True):
# open a tmp file to write the data to
@@ -194,7 +242,7 @@ class LooseObjectDB(FileDBBase, iObjectDBR, iObjectDBW):
os.remove(tmp_path)
else:
# rename the file into place
- obj_path = self.db_path(self.hexsha_to_object_path(sha))
+ obj_path = self.db_path(self.object_path(sha))
obj_dir = dirname(obj_path)
if not isdir(obj_dir):
mkdir(obj_dir)