[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

[PATCH] svn_fs_revision_prop and friends

From: Yoshiki Hayashi <yoshiki_at_xemacs.org>
Date: 2001-03-01 08:56:21 CET

* rev-table.c (svn_fs__get_rev): Take trail as argument.
  All callers are changed.
* rev-table.c (svn_fs__put_rev): Ditto.
* rev-table.h (svn_fs__get_rev): Ditto.
* rev-table.h (svn_fs__put_rev): Ditto.

* rev-table.c (txn_body_revision_prop): New helper function
  for svn_fs_revision_prop.
* rev-table.c (svn_fs_revision_prop): New function
* rev-table.c (txn_body_revision_proplist): New helper
  function for svn_fs_revision_prop.
* rev-table.c (svn_fs_revision_proplist): New function.
* rev-table.c (txn_body_change_rev_prop): New helper
  function for svn_fs_change_rev_prop.
* rev-table.c (svn_fs_change_rev_prop): New function.

* skel.c (svn_fs__atom_matches_string): New function.
* skel.h (svn_fs__atom_matches_string): New function declaration.

Index: dag.c
===================================================================
RCS file: /cvs/subversion/subversion/libsvn_fs/dag.c,v
retrieving revision 1.62
diff -u -r1.62 dag.c
--- dag.c 2001/02/28 23:22:34 1.62
+++ dag.c 2001/03/01 07:48:22
@@ -301,8 +301,7 @@
                               svn_fs__parse_skel (rev_skel,
                                                   sizeof (rev_skel) - 1,
                                                   trail->pool),
- trail->db_txn,
- trail->pool));
+ trail));
 
     if (rev != 0)
       return svn_error_createf (SVN_ERR_FS_CORRUPT, 0, 0, fs->pool,
Index: rev-table.c
===================================================================
RCS file: /cvs/subversion/subversion/libsvn_fs/rev-table.c,v
retrieving revision 1.6
diff -u -r1.6 rev-table.c
--- rev-table.c 2001/02/28 15:46:15 1.6
+++ rev-table.c 2001/03/01 07:48:23
@@ -69,8 +69,7 @@
 svn_fs__get_rev (skel_t **skel_p,
                  svn_fs_t *fs,
                  svn_revnum_t rev,
- DB_TXN *db_txn,
- apr_pool_t *pool)
+ trail_t *trail)
 {
   int db_err;
   DBT key, value;
@@ -81,11 +80,11 @@
      numbers begin with one. */
   db_recno_t recno = rev + 1;
 
- db_err = fs->revisions->get (fs->revisions, db_txn,
+ db_err = fs->revisions->get (fs->revisions, trail->db_txn,
                                svn_fs__set_dbt (&key, &recno, sizeof (recno)),
                                svn_fs__result_dbt (&value),
                                0);
- svn_fs__track_dbt (&value, pool);
+ svn_fs__track_dbt (&value, trail->pool);
 
   /* If there's no such revision, return an appropriately specific error. */
   if (db_err == DB_NOTFOUND)
@@ -95,7 +94,7 @@
   SVN_ERR (DB_WRAP (fs, "reading filesystem revision", db_err));
 
   /* Parse and check the REVISION skel. */
- skel = svn_fs__parse_skel (value.data, value.size, pool);
+ skel = svn_fs__parse_skel (value.data, value.size, trail->pool);
   if (! skel
       || ! is_valid_filesystem_revision (skel))
     return svn_fs__err_corrupt_fs_revision (fs, rev);
@@ -109,8 +108,7 @@
 svn_fs__put_rev (svn_revnum_t *rev,
                  svn_fs_t *fs,
                  skel_t *skel,
- DB_TXN *db_txn,
- apr_pool_t *pool)
+ trail_t *trail)
 {
   int db_err;
   DBT key, value;
@@ -120,9 +118,9 @@
   if (! is_valid_filesystem_revision (skel))
     return svn_fs__err_corrupt_fs_revision (fs, -1);
 
- db_err = fs->revisions->put (fs->revisions, db_txn,
+ db_err = fs->revisions->put (fs->revisions, trail->db_txn,
                                svn_fs__recno_dbt(&key, &recno),
- svn_fs__skel_to_dbt (&value, skel, pool),
+ svn_fs__skel_to_dbt (&value, skel, trail->pool),
                                DB_APPEND);
   SVN_ERR (DB_WRAP (fs, "storing filesystem revision", db_err));
 
@@ -143,8 +141,7 @@
   skel_t *skel;
   svn_fs_id_t *id;
 
- SVN_ERR (svn_fs__get_rev (&skel, fs, rev,
- trail->db_txn, trail->pool));
+ SVN_ERR (svn_fs__get_rev (&skel, fs, rev, trail));
 
   id = svn_fs_parse_id (skel->children->next->data,
                         skel->children->next->len,
@@ -233,6 +230,235 @@
   SVN_ERR (svn_fs__retry_txn (fs, txn_body_youngest_rev, &args, pool));
 
   *youngest_p = youngest;
+ return SVN_NO_ERROR;
+}
+
+
+
+/* Generic revision operations. */
+
+
+struct revision_prop_args {
+ svn_string_t **value_p;
+ svn_fs_t *fs;
+ svn_revnum_t rev;
+ svn_string_t *propname;
+};
+
+
+static svn_error_t *
+txn_body_revision_prop (void *baton,
+ trail_t *trail)
+{
+ struct revision_prop_args *args = baton;
+
+ skel_t *skel;
+ skel_t *proplist, *prop;
+
+ SVN_ERR (svn_fs__get_rev (&skel, args->fs, args->rev, trail));
+ /* PROPLIST is the third element of revision skel. */
+ proplist = skel->children->next->next;
+
+ /* Search the proplist for a property with the right name. */
+ for (prop = proplist->children; prop; prop = prop->next->next)
+ {
+ skel_t *name = prop;
+ skel_t *value = prop->next;
+
+ if (svn_fs__atom_matches_string (name, args->propname))
+ {
+ *(args->value_p) = svn_string_ncreate (value->data, value->len,
+ trail->pool);
+ return SVN_NO_ERROR;
+ }
+ }
+
+ *(args->value_p) = 0;
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_fs_revision_prop (svn_string_t **value_p,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ svn_string_t *propname,
+ apr_pool_t *pool)
+{
+ struct revision_prop_args args;
+ svn_string_t *value;
+
+ args.value_p = &value;
+ args.fs = fs;
+ args.rev = rev;
+ args.propname = propname;
+ SVN_ERR (svn_fs__retry_txn (fs, txn_body_revision_prop, &args, pool));
+
+ *value_p = value;
+ return SVN_NO_ERROR;
+}
+
+
+struct revision_proplist_args {
+ apr_hash_t **table_p;
+ svn_fs_t *fs;
+ svn_revnum_t rev;
+};
+
+
+static svn_error_t *
+txn_body_revision_proplist (void *baton, trail_t *trail)
+{
+ struct revision_proplist_args *args = baton;
+
+ skel_t *skel;
+ skel_t *proplist, *prop;
+ apr_hash_t *table;
+
+ SVN_ERR (svn_fs__get_rev (&skel, args->fs, args->rev, trail));
+ /* PROPLIST is the third element of revision skel. */
+ proplist = skel->children->next->next;
+
+ /* Build a hash table from the property list. */
+ table = apr_hash_make (trail->pool);
+ for (prop = proplist->children; prop; prop = prop->next->next)
+ {
+ skel_t *name = prop;
+ skel_t *value = prop->next;
+
+ apr_hash_set (table, name->data, name->len,
+ svn_string_ncreate (value->data, value->len,
+ trail->pool));
+ }
+ *args->table_p = table;
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_fs_revision_proplist (apr_hash_t **table_p,
+ svn_fs_t *fs,
+ svn_revnum_t rev,
+ apr_pool_t *pool)
+{
+ struct revision_proplist_args args;
+ apr_hash_t *table;
+
+ args.table_p = &table;
+ args.fs = fs;
+ args.rev = rev;
+ SVN_ERR (svn_fs__retry_txn (fs, txn_body_revision_proplist, &args, pool));
+
+ *table_p = table;
+ return SVN_NO_ERROR;
+}
+
+
+struct change_rev_prop_args {
+ svn_fs_t *fs;
+ svn_revnum_t rev;
+ svn_string_t *name;
+ svn_string_t *value;
+};
+
+
+static svn_error_t *
+txn_body_change_rev_prop (void *baton, trail_t *trail)
+{
+ struct change_rev_prop_args *args = baton;
+
+ svn_fs_t *fs = args->fs;
+ skel_t *skel;
+ skel_t *proplist, *prop;
+ skel_t *prev = NULL;
+
+ SVN_ERR (svn_fs__get_rev (&skel, fs, args->rev, trail));
+ /* PROPLIST is the third element of revision skel. */
+ proplist = skel->children->next->next;
+
+ /* Delete the skel, either replacing or adding the given property. */
+ for (prop = proplist->children; prop; prop = prop->next->next)
+ {
+ skel_t *name = prop;
+ skel_t *value = prop->next;
+
+ if (svn_fs__atom_matches_string (name, args->name))
+ {
+
+ /* If VALUE is zero, remove this property altogether. */
+ if (! args->value)
+ {
+ if (prev)
+ {
+ if (prop->next)
+ prev->next->next = prop->next->next;
+ else
+ prev->next->next = 0;
+ }
+ else
+ {
+ if (prop->next)
+ proplist->children = prop->next->next;
+ else
+ proplist->children = 0;
+ }
+ }
+ else
+ {
+ value->data = args->value->data;
+ value->len = args->value->len;
+ }
+
+ break;
+ }
+
+ prev = prop;
+ }
+
+ /* This property doesn't appear in the property list; add it to the
+ beginning. */
+ if (! prop)
+ {
+ svn_fs__prepend (svn_fs__mem_atom (args->value->data,
+ args->value->len,
+ trail->pool),
+ proplist);
+ svn_fs__prepend (svn_fs__mem_atom (args->name->data,
+ args->name->len,
+ trail->pool),
+ proplist);
+ }
+
+ {
+ int db_err;
+ DBT key, value;
+ db_recno_t recno = args->rev + 1;
+ db_err = fs->revisions->put (fs->revisions, trail->db_txn,
+ svn_fs__set_dbt (&key, &recno, sizeof (recno)),
+ svn_fs__skel_to_dbt (&value, skel, trail->pool),
+ 0);
+ SVN_ERR (DB_WRAP (fs, "updating filesystem revision", db_err));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_fs_change_rev_prop (svn_fs_t *fs,
+ svn_revnum_t rev,
+ svn_string_t *name,
+ svn_string_t *value,
+ apr_pool_t *pool)
+{
+ struct change_rev_prop_args args;
+
+ args.fs = fs;
+ args.rev = rev;
+ args.name = name;
+ args.value = value;
+ SVN_ERR (svn_fs__retry_txn (fs, txn_body_change_rev_prop, &args, pool));
+
   return SVN_NO_ERROR;
 }
 
Index: rev-table.h
===================================================================
RCS file: /cvs/subversion/subversion/libsvn_fs/rev-table.h,v
retrieving revision 1.4
diff -u -r1.4 rev-table.h
--- rev-table.h 2001/02/19 20:27:01 1.4
+++ rev-table.h 2001/03/01 07:48:23
@@ -35,26 +35,24 @@
 
 
 /* Set *SKEL_P to point to the REVISION skel for the filesystem
- revision REV in FS, as part of the Berkeley DB transaction DB_TXN.
- Allocate the skel and the data it points into in POOL.
+ revision REV in FS, as part of TRAIL.
+ Allocate the skel and the data it points into in TAIL->pool.
 
    This verifies that *SKEL_P is a well-formed REVISION skel. */
 svn_error_t *svn_fs__get_rev (skel_t **skel_p,
                               svn_fs_t *fs,
                               svn_revnum_t rev,
- DB_TXN *db_txn,
- apr_pool_t *pool);
+ trail_t *trail);
 
-/* Store SKEL as the REVISION skel in FS as part of the Berkeley DB
- transaction DB_TXN, and return the new filesystem revision number
- in *REV. Do any necessary temporary allocation in POOL.
+/* Store SKEL as the REVISION skel in FS as part of TRAIL, and return
+ the new filesystem revision number in *REV. Do any necessary
+ temporary allocation in TRAIL->pool.
 
    This verifies that SKEL is a well-formed REVISION skel. */
 svn_error_t *svn_fs__put_rev (svn_revnum_t *rev,
                               svn_fs_t *fs,
                               skel_t *skel,
- DB_TXN *db_txn,
- apr_pool_t *pool);
+ trail_t *trail);
 
 
 /* Set *ROOT_ID_P to the ID of the root directory of revision REV in FS,
Index: skel.c
===================================================================
RCS file: /cvs/subversion/subversion/libsvn_fs/skel.c,v
retrieving revision 1.20
diff -u -r1.20 skel.c
--- skel.c 2001/02/22 19:00:27 1.20
+++ skel.c 2001/03/01 07:48:23
@@ -524,6 +524,20 @@
 
 
 int
+svn_fs__atom_matches_string (skel_t *skel, svn_string_t *str)
+{
+ if (skel
+ && skel->is_atom)
+ {
+ return (skel->len == str->len
+ && ! memcmp (skel->data, str->data, skel->len));
+ }
+ else
+ return 0;
+}
+
+
+int
 svn_fs__list_length (skel_t *skel)
 {
   if (! skel
Index: skel.h
===================================================================
RCS file: /cvs/subversion/subversion/libsvn_fs/skel.h,v
retrieving revision 1.15
diff -u -r1.15 skel.h
--- skel.h 2001/02/21 23:26:20 1.15
+++ skel.h 2001/03/01 07:48:23
@@ -143,6 +143,10 @@
 int svn_fs__matches_atom (skel_t *skel, const char *str);
 
 
+/* Return true iff SKEL is an atom whose data is the same as STR. */
+int svn_fs__atom_matches_string (skel_t *skel, svn_string_t *str);
+
+
 /* Return the length of the list skel SKEL. Atoms have a length of -1. */
 int svn_fs__list_length (skel_t *skel);
 

-- 
Yoshiki Hayashi
Received on Sat Oct 21 14:36:23 2006

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.