Rev 1389: Implement get_record_stream() for files. in file:///data/jelmer/bzr-svn/stackable/

Jelmer Vernooij jelmer at samba.org
Sat Jun 28 02:53:02 BST 2008


At file:///data/jelmer/bzr-svn/stackable/

------------------------------------------------------------
revno: 1389
revision-id: jelmer at samba.org-20080628015301-6gd76dge9h4406fc
parent: jelmer at samba.org-20080627225252-el1byuv3mn5jkrfr
committer: Jelmer Vernooij <jelmer at samba.org>
branch nick: stackable
timestamp: Sat 2008-06-28 03:53:01 +0200
message:
  Implement get_record_stream() for files.
modified:
  fileids.py                     fileids.py-20060714013623-u5iiyqqnko11grcf-1
  ra.c                           ra.pyx-20080313140933-qybkqaxe3m4mcll7-1
  versionedfiles.py              versionedfiles.py-20080626134117-j8g0ntz1pj228iox-1
=== modified file 'fileids.py'
--- a/fileids.py	2008-06-26 15:38:43 +0000
+++ b/fileids.py	2008-06-28 01:53:01 +0000
@@ -61,15 +61,20 @@
 FILEIDMAP_VERSION = 1
 
 def simple_apply_changes(new_file_id, changes, find_children=None):
-    """Simple function that can apply file id changes.
+    """Simple function that generates a dictionary with file id changes.
     
     Does not track renames. """
     map = {}
     for p in sorted(changes.keys()):
         data = changes[p]
 
+        inv_p = p.decode("utf-8")
+        if data[0] in ('D', 'R'):
+            map[inv_p] = None
+            for p in map:
+                if p.startswith("%s/" % inv_p):
+                    map[p] = None
         if data[0] in ('A', 'R'):
-            inv_p = p.decode("utf-8")
             map[inv_p] = new_file_id(inv_p)
 
             if data[1] is not None:
@@ -174,7 +179,14 @@
             if changes[p][0] == 'M' and not idmap.has_key(p):
                 idmap[p] = map[p][0]
 
-        map.update(dict([(x, (str(idmap[x]), revid)) for x in idmap]))
+        for x in sorted(idmap.keys()):
+            if idmap[x] is None:
+                del map[x]
+                for p in map.keys():
+                    if p.startswith("%s/" % x):
+                        del map[p]
+            else:
+                map[x] = (str(idmap[x]), revid)
 
         # Mark all parent paths as changed
         for p in idmap:

=== modified file 'ra.c'
--- a/ra.c	2008-06-27 16:28:04 +0000
+++ b/ra.c	2008-06-28 01:53:01 +0000
@@ -1212,10 +1212,52 @@
 	}
 
 	py_props = prop_hash_to_dict(props);
+	if (py_props == NULL) {
+		apr_pool_destroy(temp_pool);
+		return NULL;
+	}
 	apr_pool_destroy(temp_pool);
 	return Py_BuildValue("(NlN)", py_dirents, fetch_rev, py_props);
 }
 
+static PyObject *ra_get_file(PyObject *self, PyObject *args)
+{
+	char *path;
+	svn_revnum_t revision = -1;
+	RemoteAccessObject *ra = (RemoteAccessObject *)self;
+    apr_hash_t *props;
+    svn_revnum_t fetch_rev;
+	PyObject *py_stream, *py_props;
+	apr_pool_t *temp_pool;
+
+	if (!PyArg_ParseTuple(args, "sO|l", &path, &py_stream, &revision))
+		return NULL;
+
+	if (ra_check_busy(ra))
+		return NULL;
+
+	temp_pool = Pool(NULL);
+	if (temp_pool == NULL)
+		return NULL;
+
+	if (revision != SVN_INVALID_REVNUM)
+		fetch_rev = revision;
+
+	RUN_RA_WITH_POOL(temp_pool, ra, svn_ra_get_file(ra->ra, path, revision, 
+													new_py_stream(temp_pool, py_stream), 
+													&fetch_rev, &props, temp_pool));
+
+	py_props = prop_hash_to_dict(props);
+	if (py_props == NULL) {
+		apr_pool_destroy(temp_pool);
+		return NULL;
+	}
+
+	apr_pool_destroy(temp_pool);
+		 
+	return Py_BuildValue("(lN)", fetch_rev, py_props);
+}
+
 static PyObject *ra_get_lock(PyObject *self, PyObject *args)
 {
 	char *path;
@@ -1495,6 +1537,7 @@
 	{ "check_path", ra_check_path, METH_VARARGS, NULL },
 	{ "get_lock", ra_get_lock, METH_VARARGS, NULL },
 	{ "get_dir", ra_get_dir, METH_VARARGS, NULL },
+	{ "get_file", ra_get_file, METH_VARARGS, NULL },
 	{ "change_rev_prop", ra_change_rev_prop, METH_VARARGS, NULL },
 	{ "get_commit_editor", (PyCFunction)get_commit_editor, METH_VARARGS|METH_KEYWORDS, NULL },
 	{ "rev_proplist", ra_rev_proplist, METH_VARARGS, NULL },

=== modified file 'versionedfiles.py'
--- a/versionedfiles.py	2008-06-27 22:52:52 +0000
+++ b/versionedfiles.py	2008-06-28 01:53:01 +0000
@@ -13,23 +13,64 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-from bzrlib import osutils
+from bzrlib import debug, osutils, urlutils
+from bzrlib.trace import mutter
 from bzrlib.versionedfile import FulltextContentFactory, VersionedFiles
 
+from cStringIO import StringIO
+
 class SvnTexts(VersionedFiles):
     """Subversion texts backend."""
 
+    def __init__(self, repository):
+        self.repository = repository
+
     def check(self, progressbar=None):
         return True
 
     def add_mpdiffs(self, records):
         raise NotImplementedError(self.add_mpdiffs)
 
-    # TODO: annotate, get_parent_map, get_record_stream, get_sha1s, 
+    def get_record_stream(self, keys, ordering, include_delta_closure):
+        for (fileid, revid) in list(keys):
+            (branch, revnum, mapping) = self.repository.lookup_revision_id(revid)
+            map = self.repository.get_fileid_map(revnum, branch, mapping)
+            # Unfortunately, the map is the other way around
+            lines = None
+            mutter('map %r', map)
+            for k,(v,ck) in map.items():
+                if v == fileid:
+                    stream = StringIO()
+                    self.repository.transport.get_file(urlutils.join(branch, k), stream, revnum)
+                    lines = stream.readlines()
+                    break
+            if lines is None:
+                raise Exception("Inconsistent key specified: (%r,%r)" % (fileid, revid))
+            yield FulltextContentFactory((fileid,revid), None, 
+                        sha1=osutils.sha_strings(lines),
+                        text=''.join(lines))
+
+    def get_parent_map(self, keys):
+        mutter("get_parent_map(%r)" % keys)
+
+        invs = {}
+
+        # First, figure out the revision number/path
+        ret = {}
+        for (fileid, revid) in keys:
+            # FIXME: Evil hack
+            ret[(fileid, revid)] = None
+        return ret
+
+    # TODO: annotate, , get_sha1s, 
     # iter_lines_added_or_present_in_keys, keys
 
 
 class FakeVersionedFiles(VersionedFiles):
+    def mutter(self, text, *args):
+        if "fakevf" in debug.debug_flags:
+            mutter(text, *args)
+
     def __init__(self, get_parent_map, get_lines):
         self._get_parent_map = get_parent_map
         self._get_lines = get_lines
@@ -41,9 +82,11 @@
         raise NotImplementedError(self.add_mpdiffs)
 
     def get_parent_map(self, keys):
+        self.mutter("get_parent_map(%r)" % keys)
         return dict([((k,), tuple([(p,) for p in v])) for k,v in self._get_parent_map([k for (k,) in keys]).iteritems()])
 
     def get_sha1s(self, keys):
+        self.mutter("get_sha1s(%r)" % keys)
         ret = {}
         for (k,) in keys:
             lines = self._get_lines(k)
@@ -53,6 +96,7 @@
         return ret
 
     def get_record_stream(self, keys, ordering, include_delta_closure):
+        self.mutter("get_record_stream(%r)" % keys)
         for (k,) in list(keys):
             lines = self._get_lines(k)
             if lines is not None:




More information about the bazaar-commits mailing list