[prev in list] [next in list] [prev in thread] [next in thread]
List: subversion-cvs
Subject:
From: cmpilato () tigris ! org
Date: 2007-09-28 21:42:23
Message-ID: 200709282142.l8SLgNuX031988 () svn2 ! sjc ! collab ! net
[Download RAW message or body]
Author: cmpilato
Date: Fri Sep 28 14:42:23 2007
New Revision: 26845
Log:
On the 'fs-successor-ids' branch: Commit what I've done so far to add
a `successors' table to the BDB backend.
* subversion/libsvn_fs_base/bdb/successors-table.h,
* subversion/libsvn_fs_base/bdb/successors-table.c
New files implementing a new `successors' table for BDB.
* subversion/libsvn_fs_base/fs.c
(cleanup_fs, open_databases): Handle the 'successors' database.
* subversion/libsvn_fs_base/fs.h
(base_fs_data_t): Add 'successors' database pointer.
* subversion/libsvn_fs_base/node-rev.c
(svn_fs_base__create_successor): Store a successor ID relationship, too.
(svn_fs_base__delete_node_revision): Add 'pred_id' parameter, and
remove the successor ID relationship, too.
(svn_fs_base__get_node_successors): New function.
* subversion/libsvn_fs_base/node-rev.h
(svn_fs_base__delete_node_revision): Add 'pred_id' parameter.
(svn_fs_base__get_node_successors): New function.
* subversion/libsvn_fs_base/dag.c
(svn_fs_base__dag_remove_node): Update call to
svn_fs_base__delete_node_revision().
Added:
branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.c \
(contents, props changed) \
branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.h \
(contents, props changed) Modified:
branches/fs-successor-ids/subversion/libsvn_fs_base/dag.c
branches/fs-successor-ids/subversion/libsvn_fs_base/fs.c
branches/fs-successor-ids/subversion/libsvn_fs_base/fs.h
branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.c
branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.h
Added: branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.c
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.c?pathrev=26845
==============================================================================
--- (empty file)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.c Fri \
Sep 28 14:42:23 2007 @@ -0,0 +1,254 @@
+/* successors-table.c : operations on the `successors' table
+ *
+ * ====================================================================
+ * Copyright (c) 2007 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+#include "bdb_compat.h"
+
+#include <apr_hash.h>
+#include <apr_tables.h>
+
+#include "svn_fs.h"
+#include "svn_pools.h"
+#include "svn_path.h"
+#include "../fs.h"
+#include "../err.h"
+#include "../trail.h"
+#include "../id.h"
+#include "../util/fs_skels.h"
+#include "../../libsvn_fs/fs-loader.h"
+#include "bdb-err.h"
+#include "dbt.h"
+#include "successors-table.h"
+
+
+#include "svn_private_config.h"
+
+
+/*** Creating and opening the successors table. ***/
+
+int
+svn_fs_bdb__open_successors_table(DB **successors_p,
+ DB_ENV *env,
+ svn_boolean_t create)
+{
+ const u_int32_t open_flags = (create ? (DB_CREATE | DB_EXCL) : 0);
+ DB *successors;
+ int error;
+
+ BDB_ERR(svn_fs_bdb__check_version());
+ BDB_ERR(db_create(&successors, env, 0));
+
+ /* Enable duplicate keys. This allows us to store the successors
+ one-per-row. Note: this must occur before ->open(). */
+ BDB_ERR(successors->set_flags(successors, DB_DUP));
+
+ error = successors->open(SVN_BDB_OPEN_PARAMS(successors, NULL),
+ "successors", 0, DB_BTREE,
+ open_flags, 0666);
+
+ /* Create the table if it doesn't yet exist. This is a form of
+ automagical repository upgrading. */
+ if (error == ENOENT && (! create))
+ {
+ BDB_ERR(successors->close(successors, 0));
+ return svn_fs_bdb__open_successors_table(successors_p, env, TRUE);
+ }
+ BDB_ERR(error);
+
+ *successors_p = successors;
+ return 0;
+}
+
+
+
+/*** Storing and retrieving successors. ***/
+
+svn_error_t *
+svn_fs_bdb__successors_add(svn_fs_t *fs,
+ const char *node_id,
+ const char *succ_id,
+ trail_t *trail,
+ apr_pool_t *pool)
+{
+ base_fs_data_t *bfd = fs->fsap_data;
+ DBT query, value;
+
+ /* Store a new record into the database. */
+ svn_fs_base__str_to_dbt(&query, node_id);
+ svn_fs_base__str_to_dbt(&value, succ_id);
+ svn_fs_base__trail_debug(trail, "successors", "put");
+ SVN_ERR(BDB_WRAP(fs, _("creating successor"),
+ bfd->successors->put(bfd->successors, trail->db_txn,
+ &query, &value, 0)));
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_fs_bdb__successors_delete(svn_fs_t *fs,
+ const char *node_id,
+ const char *succ_id,
+ trail_t *trail,
+ apr_pool_t *pool)
+{
+ base_fs_data_t *bfd = fs->fsap_data;
+ DBC *cursor;
+ DBT key, value;
+ int db_err = 0, db_c_err = 0;
+ svn_error_t *err = SVN_NO_ERROR;
+
+ /* Get a cursor on the first record matching NODE_ID, and then loop
+ over the records, adding them to the return array. */
+ svn_fs_base__trail_debug(trail, "successors", "cursor");
+ SVN_ERR(BDB_WRAP(fs, _("creating cursor for reading successors"),
+ bfd->successors->cursor(bfd->successors, trail->db_txn,
+ &cursor, 0)));
+
+ /* Advance the cursor to the key that we're looking for. */
+ svn_fs_base__str_to_dbt(&key, node_id);
+ svn_fs_base__result_dbt(&value);
+ db_err = svn_bdb_dbc_get(cursor, &key, &value, DB_SET);
+ if (! db_err)
+ svn_fs_base__track_dbt(&value, pool);
+
+ while (! db_err)
+ {
+ /* VALUE now contains a successor ID. Is it the one we're
+ looking to delete? */
+ if ((value.size == strlen(succ_id))
+ && (memcmp(succ_id, value.data, value.size) == 0))
+ {
+ db_err = svn_bdb_dbc_del(cursor, 0);
+ break;
+ }
+
+ /* Advance the cursor to the next record with this same KEY, and
+ fetch that record. */
+ svn_fs_base__result_dbt(&value);
+ db_err = svn_bdb_dbc_get(cursor, &key, &value, DB_NEXT_DUP);
+ if (! db_err)
+ svn_fs_base__track_dbt(&value, pool);
+ }
+
+ /* Record any errors we caught. We'll return them post-cleanup. */
+ if (db_err)
+ err = BDB_WRAP(fs, _("deleting successor"), db_err);
+
+ /* Close the cursor. */
+ db_c_err = svn_bdb_dbc_close(cursor);
+
+ /* If we had an error prior to closing the cursor, return the error. */
+ if (err)
+ return err;
+
+ /* If our only error thus far was when we closed the cursor, return
+ that error. */
+ if (db_c_err)
+ SVN_ERR(BDB_WRAP(fs, _("closing successors cursor"), db_c_err));
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_fs_bdb__successors_delete_all(svn_fs_t *fs,
+ const char *node_id,
+ trail_t *trail,
+ apr_pool_t *pool)
+{
+ int db_err;
+ DBT query;
+ base_fs_data_t *bfd = fs->fsap_data;
+
+ svn_fs_base__trail_debug(trail, "successors", "del");
+ db_err = bfd->successors->del(bfd->successors, trail->db_txn,
+ svn_fs_base__str_to_dbt(&query, node_id), 0);
+
+ /* If there're no successors for NODE_ID, that is acceptable. Any
+ other error should be propogated to the caller, though. */
+ if ((db_err) && (db_err != DB_NOTFOUND))
+ {
+ SVN_ERR(BDB_WRAP(fs, _("deleting successors"), db_err));
+ }
+
+ return SVN_NO_ERROR;
+}
+
+
+svn_error_t *
+svn_fs_bdb__successors_fetch(apr_array_header_t **successors_p,
+ svn_fs_t *fs,
+ const char *node_id,
+ trail_t *trail,
+ apr_pool_t *pool)
+{
+ base_fs_data_t *bfd = fs->fsap_data;
+ DBC *cursor;
+ DBT key, value;
+ int db_err = 0, db_c_err = 0;
+ svn_error_t *err = SVN_NO_ERROR;
+ apr_array_header_t *successors = apr_array_make(pool, 8, sizeof(const char *));
+
+ /* Get a cursor on the first record matching NODE_ID, and then loop
+ over the records, adding them to the return array. */
+ svn_fs_base__trail_debug(trail, "successors", "cursor");
+ SVN_ERR(BDB_WRAP(fs, _("creating cursor for reading successors"),
+ bfd->successors->cursor(bfd->successors, trail->db_txn,
+ &cursor, 0)));
+
+ /* Advance the cursor to the key that we're looking for. */
+ svn_fs_base__str_to_dbt(&key, node_id);
+ svn_fs_base__result_dbt(&value);
+ db_err = svn_bdb_dbc_get(cursor, &key, &value, DB_SET);
+ if (! db_err)
+ svn_fs_base__track_dbt(&value, pool);
+
+ while (! db_err)
+ {
+ APR_ARRAY_PUSH(successors, const char *) =
+ apr_pstrmemdup(pool, value.data, value.size);
+
+ /* Advance the cursor to the next record with this same NODE_ID,
+ and fetch that record. */
+ svn_fs_base__result_dbt(&value);
+ db_err = svn_bdb_dbc_get(cursor, &key, &value, DB_NEXT_DUP);
+ if (! db_err)
+ svn_fs_base__track_dbt(&value, pool);
+ }
+
+ /* If there are no (more) successor records for this KEY, we're
+ finished. Just return the (possibly empty) array. Any other
+ error, however, needs to get handled appropriately. */
+ if (db_err && (db_err != DB_NOTFOUND))
+ err = BDB_WRAP(fs, _("fetching successors"), db_err);
+
+ /* Close the cursor. */
+ db_c_err = svn_bdb_dbc_close(cursor);
+
+ /* If we had an error prior to closing the cursor, return the error. */
+ if (err)
+ return err;
+
+ /* If our only error thus far was when we closed the cursor, return
+ that error. */
+ if (db_c_err)
+ SVN_ERR(BDB_WRAP(fs, _("closing successors cursor"), db_c_err));
+
+ /* Finally, set our return variable and get outta here. */
+ *successors_p = successors;
+ return SVN_NO_ERROR;
+}
Added: branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.h
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.h?pathrev=26845
==============================================================================
--- (empty file)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/bdb/successors-table.h Fri \
Sep 28 14:42:23 2007 @@ -0,0 +1,93 @@
+/* successors-table.h : internal interface to `successors' table
+ *
+ * ====================================================================
+ * Copyright (c) 2000-2004 CollabNet. All rights reserved.
+ *
+ * This software is licensed as described in the file COPYING, which
+ * you should have received as part of this distribution. The terms
+ * are also available at http://subversion.tigris.org/license-1.html.
+ * If newer versions of this license are posted there, you may use a
+ * newer version instead, at your option.
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals. For exact contribution history, see the revision
+ * history and logs, available at http://subversion.tigris.org/.
+ * ====================================================================
+ */
+
+#ifndef SVN_LIBSVN_FS_SUCCESSORS_TABLE_H
+#define SVN_LIBSVN_FS_SUCCESSORS_TABLE_H
+
+#define APU_WANT_DB
+#include <apu_want.h>
+
+#include "svn_io.h"
+#include "svn_fs.h"
+#include "../fs.h"
+#include "../trail.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+/* Open a `successors' table in ENV. If CREATE is non-zero, create
+ one if it doesn't exist. Set *SUCCESSORS_P to the new table.
+ Return a Berkeley DB error code. */
+int svn_fs_bdb__open_successors_table(DB **successors_p,
+ DB_ENV *env,
+ svn_boolean_t create);
+
+
+/* Add SUCC_ID as a record to the `successors' table in FS as part of
+ TRAIL, keyed on NODE_ID.
+
+ NODE_ID and SUCC_ID are unparsed node-revision-ID strings.
+
+ Note that because the `successors' table uses duplicate keys, this
+ function will not overwrite prior additions that have the NODE_ID
+ key, but simply adds this new record alongside previous ones. */
+svn_error_t *svn_fs_bdb__successors_add(svn_fs_t *fs,
+ const char *node_id,
+ const char *succ_id,
+ trail_t *trail,
+ apr_pool_t *pool);
+
+
+/* Remove SUCC_ID as a successor for NODE_ID in the `successors' table
+ in FS, as part of TRAIL.
+
+ NODE_ID and SUCC_ID are unparsed node-revision-ID strings. */
+svn_error_t *svn_fs_bdb__successors_delete(svn_fs_t *fs,
+ const char *node_id,
+ const char *succ_id,
+ trail_t *trail,
+ apr_pool_t *pool);
+
+
+/* Remove all successors associated with unparsed node-revision-ID
+ NODE_ID from the `successors' table in FS, as part of TRAIL. */
+svn_error_t *svn_fs_bdb__successors_delete_all(svn_fs_t *fs,
+ const char *node_id,
+ trail_t *trail,
+ apr_pool_t *pool);
+
+/* Return an array *SUCCESSORS_P of const char * successor IDs
+ representing all the successors of NODE_ID in FS, as part of TRAIL.
+
+ NODE_ID and the returned successor IDs are all unparsed
+ node-revision-ID strings.
+
+ Allocate the array and its items in POOL. */
+svn_error_t *svn_fs_bdb__successors_fetch(apr_array_header_t **successors_p,
+ svn_fs_t *fs,
+ const char *key,
+ trail_t *trail,
+ apr_pool_t *pool);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* SVN_LIBSVN_FS_SUCCESSORS_TABLE_H */
Modified: branches/fs-successor-ids/subversion/libsvn_fs_base/dag.c
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/dag.c?pathrev=26845&r1=26844&r2=26845
==============================================================================
--- branches/fs-successor-ids/subversion/libsvn_fs_base/dag.c (original)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/dag.c Fri Sep 28 14:42:23 \
2007 @@ -962,7 +962,8 @@
txn_id, trail, pool));
/* Delete the node revision itself. */
- SVN_ERR(svn_fs_base__delete_node_revision(fs, id, trail, pool));
+ SVN_ERR(svn_fs_base__delete_node_revision(fs, id, noderev->predecessor_id,
+ trail, pool));
return SVN_NO_ERROR;
}
Modified: branches/fs-successor-ids/subversion/libsvn_fs_base/fs.c
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/fs.c?pathrev=26845&r1=26844&r2=26845
==============================================================================
--- branches/fs-successor-ids/subversion/libsvn_fs_base/fs.c (original)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/fs.c Fri Sep 28 14:42:23 2007
@@ -55,6 +55,7 @@
#include "bdb/uuids-table.h"
#include "bdb/locks-table.h"
#include "bdb/lock-tokens-table.h"
+#include "bdb/successors-table.h"
#include "../libsvn_fs/fs-loader.h"
#include "private/svn_fs_mergeinfo.h"
@@ -180,6 +181,7 @@
SVN_ERR(cleanup_fs_db(fs, &bfd->uuids, "uuids"));
SVN_ERR(cleanup_fs_db(fs, &bfd->locks, "locks"));
SVN_ERR(cleanup_fs_db(fs, &bfd->lock_tokens, "lock-tokens"));
+ SVN_ERR(cleanup_fs_db(fs, &bfd->successors, "successors"));
/* Finally, close the environment. */
bfd->bdb = 0;
@@ -617,6 +619,12 @@
svn_fs_bdb__open_lock_tokens_table(&bfd->lock_tokens,
bfd->bdb->env,
create)));
+ SVN_ERR(BDB_WRAP(fs, (create
+ ? "creating 'successors' table"
+ : "opening 'successors' table"),
+ svn_fs_bdb__open_successors_table(&bfd->successors,
+ bfd->bdb->env,
+ create)));
return SVN_NO_ERROR;
}
Modified: branches/fs-successor-ids/subversion/libsvn_fs_base/fs.h
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/fs.h?pathrev=26845&r1=26844&r2=26845
==============================================================================
--- branches/fs-successor-ids/subversion/libsvn_fs_base/fs.h (original)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/fs.h Fri Sep 28 14:42:23 2007
@@ -56,6 +56,7 @@
DB *representations;
DB *revisions;
DB *strings;
+ DB *successors;
DB *transactions;
DB *uuids;
DB *locks;
Modified: branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.c
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.c?pathrev=26845&r1=26844&r2=26845
==============================================================================
--- branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.c (original)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.c Fri Sep 28 \
14:42:23 2007 @@ -20,13 +20,17 @@
#define APU_WANT_DB
#include <apu_want.h>
+#include "svn_pools.h"
#include "svn_fs.h"
#include "fs.h"
+#include "id.h"
#include "err.h"
#include "node-rev.h"
#include "reps-strings.h"
+#include "revs-txns.h"
#include "bdb/nodes-table.h"
+#include "bdb/successors-table.h"
/* Creating completely new nodes. */
@@ -68,6 +72,7 @@
apr_pool_t *pool)
{
svn_fs_id_t *new_id;
+ svn_string_t *new_id_str, *old_id_str;
/* Choose an ID for the new node, and store it in the database. */
SVN_ERR(svn_fs_bdb__new_successor_id(&new_id, fs, old_id, copy_id,
@@ -77,6 +82,12 @@
SVN_ERR(svn_fs_bdb__put_node_revision(fs, new_id, new_noderev,
trail, pool));
+ /* Record the successor relationship. */
+ old_id_str = svn_fs_unparse_id(old_id, pool);
+ new_id_str = svn_fs_unparse_id(new_id, pool);
+ SVN_ERR(svn_fs_bdb__successors_add(fs, old_id_str->data, new_id_str->data,
+ trail, pool));
+
*new_id_p = new_id;
return SVN_NO_ERROR;
}
@@ -88,11 +99,75 @@
svn_error_t *
svn_fs_base__delete_node_revision(svn_fs_t *fs,
const svn_fs_id_t *id,
+ const svn_fs_id_t *pred_id,
trail_t *trail,
apr_pool_t *pool)
{
- /* ### todo: here, we should adjust other nodes to compensate for
+ svn_string_t *node_id_str, *succ_id_str;
+
+ /* ### TODO: here, we should adjust other nodes to compensate for
the missing node. */
+ /* Remove the successor association... */
+ if (pred_id)
+ {
+ node_id_str = svn_fs_unparse_id(pred_id, pool);
+ succ_id_str = svn_fs_unparse_id(id, pool);
+ SVN_ERR(svn_fs_bdb__successors_delete(fs, node_id_str->data,
+ succ_id_str->data, trail,
+ pool));
+ }
+
+ /* ...and then the node itself. */
return svn_fs_bdb__delete_nodes_entry(fs, id, trail, pool);
}
+
+
+
+/* Fetching node successors. */
+
+svn_error_t *
+svn_fs_base__get_node_successors(apr_array_header_t **successors_p,
+ svn_fs_t *fs,
+ const svn_fs_id_t *id,
+ svn_boolean_t committed_only,
+ trail_t *trail,
+ apr_pool_t *pool)
+{
+ apr_array_header_t *all_successors, *successors;
+ apr_pool_t *subpool = svn_pool_create(pool);
+ svn_string_t *node_id_str = svn_fs_unparse_id(id, pool);
+ int i;
+
+ SVN_ERR(svn_fs_bdb__successors_fetch(&all_successors, fs, node_id_str->data,
+ trail, pool));
+ successors = apr_array_make(pool, all_successors->nelts,
+ sizeof(const svn_fs_id_t *));
+ for (i = 0; i < all_successors->nelts; i++)
+ {
+ svn_revnum_t revision;
+ const char *succ_id_str = APR_ARRAY_IDX(all_successors, i, const char *);
+ const svn_fs_id_t *succ_id = svn_fs_parse_id(succ_id_str,
+ strlen(succ_id_str), pool);
+
+ svn_pool_clear(subpool);
+
+ /* If we only want stable, committed successor IDs, then we need
+ to check each ID's txn-id component to verify that's been
+ committed. */
+ if (committed_only)
+ {
+ SVN_ERR(svn_fs_base__txn_get_revision
+ (&revision, fs, svn_fs_base__id_txn_id(succ_id),
+ trail, subpool));
+ if (! SVN_IS_VALID_REVNUM(revision))
+ continue;
+ }
+
+ APR_ARRAY_PUSH(successors, const svn_fs_id_t *) = succ_id;
+ }
+ svn_pool_destroy(subpool);
+
+ *successors_p = successors;
+ return SVN_NO_ERROR;
+}
Modified: branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.h
URL: http://svn.collab.net/viewvc/svn/branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.h?pathrev=26845&r1=26844&r2=26845
==============================================================================
--- branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.h (original)
+++ branches/fs-successor-ids/subversion/libsvn_fs_base/node-rev.h Fri Sep 28 \
14:42:23 2007 @@ -74,14 +74,30 @@
apr_pool_t *pool);
-/* Delete node revision ID from FS's `nodes' table, as part of TRAIL.
+/* Delete node revision ID (with predecessor id PRED_ID, if any) from
+ FS's `nodes' table, as part of TRAIL.
+
WARNING: This does not check that the node revision is mutable!
Callers should do that check themselves. */
svn_error_t *svn_fs_base__delete_node_revision(svn_fs_t *fs,
const svn_fs_id_t *id,
+ const svn_fs_id_t *pred_id,
trail_t *trail,
apr_pool_t *pool);
+/* Set *SUCCESSORS to an array of svn_fs_id_t * node revision IDs of
+ nodes in FS which are successors of ID (that is, ID is their
+ immediate predecessor). If COMMITTED_ONLY is set, only include
+ successors which were created in transactions that have since been
+ committed.
+
+ Do this as part of TRAIL, and use POOL for any allocations. */
+svn_error_t *svn_fs_base__get_node_successors(apr_array_header_t **successors,
+ svn_fs_t *fs,
+ const svn_fs_id_t *id,
+ svn_boolean_t committed_only,
+ trail_t *trail,
+ apr_pool_t *pool);
#ifdef __cplusplus
}
---------------------------------------------------------------------
To unsubscribe, e-mail: svn-unsubscribe@subversion.tigris.org
For additional commands, e-mail: svn-help@subversion.tigris.org
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic