You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by hw...@apache.org on 2011/08/30 23:00:57 UTC
svn commit: r1163379 - in /subversion/branches/fs-py/subversion:
libsvn_fs_py/fs_fs.c libsvn_fs_py/py_util.c libsvn_fs_py/py_util.h
python/svn/fs/__init__.py python/svn/hash.py
Author: hwright
Date: Tue Aug 30 21:00:57 2011
New Revision: 1163379
URL: http://svn.apache.org/viewvc?rev=1163379&view=rev
Log:
On the fs-py branch:
Fetch revprops using Python, not C.
* subversion/python/svn/fs/__init__.py
(FS.revision_proplist): New.
* subversion/python/svn/hash.py
(read): New.
* subversion/libsvn_fs_py/fs_fs.c
(revision_proplist): Remove implementation in favor of Python one.
* subversion/libsvn_fs_py/py_util.c
(make_string_from_ob, make_svn_string_from_ob, svn_fs_py__prophash_from_dict):
New.
* subversion/libsvn_fs_py/py_util.h
(svn_fs_py__prophash_from_dict): New.
Modified:
subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c
subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c
subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h
subversion/branches/fs-py/subversion/python/svn/fs/__init__.py
subversion/branches/fs-py/subversion/python/svn/hash.py
Modified: subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c?rev=1163379&r1=1163378&r2=1163379&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_py/fs_fs.c Tue Aug 30 21:00:57 2011
@@ -2875,65 +2875,15 @@ revision_proplist(apr_hash_t **proplist_
svn_revnum_t rev,
apr_pool_t *pool)
{
- apr_hash_t *proplist;
-
- SVN_ERR(ensure_revision_exists(fs, rev, pool));
-
- if (1)
- {
- apr_file_t *revprop_file = NULL;
- svn_error_t *err = SVN_NO_ERROR;
- int i;
- apr_pool_t *iterpool;
-
- proplist = apr_hash_make(pool);
- iterpool = svn_pool_create(pool);
- for (i = 0; i < RECOVERABLE_RETRY_COUNT; i++)
- {
- svn_pool_clear(iterpool);
-
- /* Clear err here rather than after finding a recoverable error so
- * we can return that error on the last iteration of the loop. */
- svn_error_clear(err);
- err = svn_io_file_open(&revprop_file, path_revprops(fs, rev,
- iterpool),
- APR_READ | APR_BUFFERED, APR_OS_DEFAULT,
- iterpool);
- if (err)
- {
- if (APR_STATUS_IS_ENOENT(err->apr_err))
- {
- svn_error_clear(err);
- return svn_error_createf(SVN_ERR_FS_NO_SUCH_REVISION, NULL,
- _("No such revision %ld"), rev);
- }
-#ifdef ESTALE
- else if (APR_TO_OS_ERROR(err->apr_err) == ESTALE
- || APR_TO_OS_ERROR(err->apr_err) == EIO
- || APR_TO_OS_ERROR(err->apr_err) == ENOENT)
- continue;
-#endif
- return svn_error_trace(err);
- }
-
- SVN_ERR(svn_hash__clear(proplist, iterpool));
- RETRY_RECOVERABLE(err, revprop_file,
- svn_hash_read2(proplist,
- svn_stream_from_aprfile2(
- revprop_file, TRUE, iterpool),
- SVN_HASH_TERMINATOR, pool));
+ fs_fs_data_t *ffd = fs->fsap_data;
+ PyObject *p_proplist;
- IGNORE_RECOVERABLE(err, svn_io_file_close(revprop_file, iterpool));
+ SVN_ERR(svn_fs_py__call_method(&p_proplist, ffd->p_fs, "revision_proplist",
+ "(l)", rev));
- break;
- }
+ *proplist_p = svn_fs_py__prophash_from_dict(p_proplist, pool);
- if (err)
- return svn_error_trace(err);
- svn_pool_destroy(iterpool);
- }
-
- *proplist_p = proplist;
+ Py_DECREF(p_proplist);
return SVN_NO_ERROR;
}
Modified: subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c?rev=1163379&r1=1163378&r2=1163379&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.c Tue Aug 30 21:00:57 2011
@@ -620,6 +620,80 @@ svn_fs_py__load_module(fs_fs_data_t *ffd
return svn_error_trace(load_module(&ffd->p_module, FS_MODULE_NAME));
}
+/* Conversion from Python single objects (not hashes/lists/etc.) to
+ Subversion types. */
+static const char *
+make_string_from_ob(PyObject *ob, apr_pool_t *pool)
+{
+ if (ob == Py_None)
+ return NULL;
+ if (! PyString_Check(ob))
+ {
+ PyErr_SetString(PyExc_TypeError, "not a string");
+ return NULL;
+ }
+ return apr_pstrdup(pool, PyString_AS_STRING(ob));
+}
+
+static svn_string_t *
+make_svn_string_from_ob(PyObject *ob, apr_pool_t *pool)
+{
+ if (ob == Py_None)
+ return NULL;
+ if (! PyString_Check(ob))
+ {
+ PyErr_SetString(PyExc_TypeError, "not a string");
+ return NULL;
+ }
+ return svn_string_create(PyString_AS_STRING(ob), pool);
+}
+
+/* ### We may need to wrap this in something to catch any Python errors which
+ * ### are generated. */
+apr_hash_t *
+svn_fs_py__prophash_from_dict(PyObject *dict, apr_pool_t *pool)
+{
+ apr_hash_t *hash;
+ PyObject *keys;
+ long num_keys;
+ long i;
+
+ if (dict == Py_None)
+ return NULL;
+
+ if (!PyDict_Check(dict))
+ {
+ PyErr_SetString(PyExc_TypeError, "not a dictionary");
+ return NULL;
+ }
+
+ hash = apr_hash_make(pool);
+ keys = PyDict_Keys(dict);
+ num_keys = PyList_Size(keys);
+ for (i = 0; i < num_keys; i++)
+ {
+ PyObject *key = PyList_GetItem(keys, i);
+ PyObject *value = PyDict_GetItem(dict, key);
+ const char *propname = make_string_from_ob(key, pool);
+ svn_string_t *propval = make_svn_string_from_ob(value, pool);
+
+ if (! (propname && propval))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "dictionary keys/values aren't strings");
+ Py_DECREF(keys);
+ return NULL;
+ }
+ apr_hash_set(hash, propname, APR_HASH_KEY_STRING, propval);
+ }
+ Py_DECREF(keys);
+ return hash;
+}
+
+
+/**********************
+ * Wrapping C callback functions
+ */
static PyObject *
notify_func_wrapper(PyObject *p_tuple, PyObject *args)
{
Modified: subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h?rev=1163379&r1=1163378&r2=1163379&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h (original)
+++ subversion/branches/fs-py/subversion/libsvn_fs_py/py_util.h Tue Aug 30 21:00:57 2011
@@ -46,6 +46,9 @@ svn_fs_py__convert_cstring_hash(void *ob
PyObject *
svn_fs_py__convert_proplist(void *object);
+apr_hash_t *
+svn_fs_py__prophash_from_dict(PyObject *dict, apr_pool_t *pool);
+
/* Load a reference to the FS Python module into the shared data. */
svn_error_t *
svn_fs_py__load_module(fs_fs_data_t *ffd);
Modified: subversion/branches/fs-py/subversion/python/svn/fs/__init__.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/python/svn/fs/__init__.py?rev=1163379&r1=1163378&r2=1163379&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/python/svn/fs/__init__.py (original)
+++ subversion/branches/fs-py/subversion/python/svn/fs/__init__.py Tue Aug 30 21:00:57 2011
@@ -553,6 +553,14 @@ class FS(object):
self._pack_shard(shard, notify)
+ def revision_proplist(self, rev):
+ 'Return a dictionary of revprops'
+
+ self._ensure_revision_exists(rev)
+ with open(self.__path_revprops(rev), 'rb') as f:
+ return svn.hash.read(f, svn.hash.TERMINATOR)
+
+
# A few helper functions for C callers
def _create_fs(path, config=None):
Modified: subversion/branches/fs-py/subversion/python/svn/hash.py
URL: http://svn.apache.org/viewvc/subversion/branches/fs-py/subversion/python/svn/hash.py?rev=1163379&r1=1163378&r2=1163379&view=diff
==============================================================================
--- subversion/branches/fs-py/subversion/python/svn/hash.py (original)
+++ subversion/branches/fs-py/subversion/python/svn/hash.py Tue Aug 30 21:00:57 2011
@@ -20,6 +20,8 @@
TERMINATOR = "END"
+import svn
+
def encode(h, terminator):
output = []
for k in sorted(h.keys()):
@@ -29,3 +31,49 @@ def encode(h, terminator):
output.append('%s\n' % terminator)
return ''.join(output)
+
+
+def read(f, terminator):
+ 'Return a hash as read from the file-like object F.'
+
+ h = {}
+ while True:
+ line = f.readline().rstrip()
+
+ if line == terminator:
+ break
+
+ if line[0:2] == 'K ':
+ # Read length and data into a buffer.
+ keylen = int(line[2:])
+ keybuf = f.read(keylen)
+
+ # Suck up extra newline after key data
+ c = f.read(1)
+ if c != '\n':
+ raise svn.SubversionException(svn.err.MALFORMED_FILE,
+ "Serialized hash malformed")
+
+ # Read a val length line
+ line = f.readline().rstrip()
+ if line[0:2] == 'V ':
+ vallen = int(line[2:])
+ valbuf = f.read(vallen)
+
+ # Suck up extra newline after val data
+ c = f.read(1)
+ if c != '\n':
+ raise svn.SubversionException(svn.err.MALFORMED_FILE,
+ "Serialized hash malformed")
+
+ h[keybuf] = valbuf
+ else:
+ raise svn.SubversionException(svn.err.MALFORMED_FILE,
+ "Serialized hash malformed")
+
+ else:
+ print line
+ raise svn.SubversionException(svn.err.MALFORMED_FILE,
+ "Serialized hash malformed")
+
+ return h