1 /* id.c : operations on node-revision IDs
3 * ====================================================================
4 * Copyright (c) 2000-2004 CollabNet. All rights reserved.
6 * This software is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at http://subversion.tigris.org/license-1.html.
9 * If newer versions of this license are posted there, you may use a
10 * newer version instead, at your option.
12 * This software consists of voluntary contributions made by many
13 * individuals. For exact contribution history, see the revision
14 * history and logs, available at http://subversion.tigris.org/.
15 * ====================================================================
22 #include "../libsvn_fs/fs-loader.h"
35 /* Accessing ID Pieces. */
38 svn_fs_fs__id_node_id(const svn_fs_id_t
*id
)
40 id_private_t
*pvt
= id
->fsap_data
;
47 svn_fs_fs__id_copy_id(const svn_fs_id_t
*id
)
49 id_private_t
*pvt
= id
->fsap_data
;
56 svn_fs_fs__id_txn_id(const svn_fs_id_t
*id
)
58 id_private_t
*pvt
= id
->fsap_data
;
65 svn_fs_fs__id_rev(const svn_fs_id_t
*id
)
67 id_private_t
*pvt
= id
->fsap_data
;
74 svn_fs_fs__id_offset(const svn_fs_id_t
*id
)
76 id_private_t
*pvt
= id
->fsap_data
;
83 svn_fs_fs__id_unparse(const svn_fs_id_t
*id
,
86 const char *txn_rev_id
;
87 id_private_t
*pvt
= id
->fsap_data
;
91 txn_rev_id
= apr_psprintf(pool
, "%ld/%"
92 APR_OFF_T_FMT
, pvt
->rev
, pvt
->offset
);
96 txn_rev_id
= pvt
->txn_id
;
98 return svn_string_createf(pool
, "%s.%s.%c%s",
99 pvt
->node_id
, pvt
->copy_id
,
100 (pvt
->txn_id
? 't' : 'r'),
105 /*** Comparing node IDs ***/
108 svn_fs_fs__id_eq(const svn_fs_id_t
*a
,
109 const svn_fs_id_t
*b
)
111 id_private_t
*pvta
= a
->fsap_data
, *pvtb
= b
->fsap_data
;
115 if (strcmp(pvta
->node_id
, pvtb
->node_id
) != 0)
117 if (strcmp(pvta
->copy_id
, pvtb
->copy_id
) != 0)
119 if ((pvta
->txn_id
== NULL
) != (pvtb
->txn_id
== NULL
))
121 if (pvta
->txn_id
&& pvtb
->txn_id
&& strcmp(pvta
->txn_id
, pvtb
->txn_id
) != 0)
123 if (pvta
->rev
!= pvtb
->rev
)
125 if (pvta
->offset
!= pvtb
->offset
)
132 svn_fs_fs__id_check_related(const svn_fs_id_t
*a
,
133 const svn_fs_id_t
*b
)
135 id_private_t
*pvta
= a
->fsap_data
, *pvtb
= b
->fsap_data
;
139 /* If both node_ids start with _ and they have differing transaction
140 IDs, then it is impossible for them to be related. */
141 if (pvta
->node_id
[0] == '_')
143 if (pvta
->txn_id
&& pvtb
->txn_id
&&
144 (strcmp(pvta
->txn_id
, pvtb
->txn_id
) != 0))
148 return (strcmp(pvta
->node_id
, pvtb
->node_id
) == 0) ? TRUE
: FALSE
;
153 svn_fs_fs__id_compare(const svn_fs_id_t
*a
,
154 const svn_fs_id_t
*b
)
156 if (svn_fs_fs__id_eq(a
, b
))
158 return (svn_fs_fs__id_check_related(a
, b
) ? 1 : -1);
165 static id_vtable_t id_vtable
= {
166 svn_fs_fs__id_unparse
,
167 svn_fs_fs__id_compare
172 svn_fs_fs__id_txn_create(const char *node_id
,
177 svn_fs_id_t
*id
= apr_palloc(pool
, sizeof(*id
));
178 id_private_t
*pvt
= apr_palloc(pool
, sizeof(*pvt
));
180 pvt
->node_id
= apr_pstrdup(pool
, node_id
);
181 pvt
->copy_id
= apr_pstrdup(pool
, copy_id
);
182 pvt
->txn_id
= apr_pstrdup(pool
, txn_id
);
183 pvt
->rev
= SVN_INVALID_REVNUM
;
185 id
->vtable
= &id_vtable
;
192 svn_fs_fs__id_rev_create(const char *node_id
,
198 svn_fs_id_t
*id
= apr_palloc(pool
, sizeof(*id
));
199 id_private_t
*pvt
= apr_palloc(pool
, sizeof(*pvt
));
201 pvt
->node_id
= apr_pstrdup(pool
, node_id
);
202 pvt
->copy_id
= apr_pstrdup(pool
, copy_id
);
205 pvt
->offset
= offset
;
206 id
->vtable
= &id_vtable
;
213 svn_fs_fs__id_copy(const svn_fs_id_t
*id
, apr_pool_t
*pool
)
215 svn_fs_id_t
*new_id
= apr_palloc(pool
, sizeof(*new_id
));
216 id_private_t
*new_pvt
= apr_palloc(pool
, sizeof(*new_pvt
));
217 id_private_t
*pvt
= id
->fsap_data
;
219 new_pvt
->node_id
= apr_pstrdup(pool
, pvt
->node_id
);
220 new_pvt
->copy_id
= apr_pstrdup(pool
, pvt
->copy_id
);
221 new_pvt
->txn_id
= pvt
->txn_id
? apr_pstrdup(pool
, pvt
->txn_id
) : NULL
;
222 new_pvt
->rev
= pvt
->rev
;
223 new_pvt
->offset
= pvt
->offset
;
224 new_id
->vtable
= &id_vtable
;
225 new_id
->fsap_data
= new_pvt
;
231 svn_fs_fs__id_parse(const char *data
,
237 char *data_copy
, *str
, *last_str
;
239 /* Dup the ID data into POOL. Our returned ID will have references
241 data_copy
= apr_pstrmemdup(pool
, data
, len
);
243 /* Alloc a new svn_fs_id_t structure. */
244 id
= apr_palloc(pool
, sizeof(*id
));
245 pvt
= apr_palloc(pool
, sizeof(*pvt
));
246 id
->vtable
= &id_vtable
;
249 /* Now, we basically just need to "split" this data on `.'
250 characters. We will use apr_strtok, which will put terminators
251 where each of the '.'s used to be. Then our new id field will
252 reference string locations inside our duplicate string.*/
255 str
= apr_strtok(data_copy
, ".", &last_str
);
261 str
= apr_strtok(NULL
, ".", &last_str
);
267 str
= apr_strtok(NULL
, ".", &last_str
);
273 /* This is a revision type ID */
276 str
= apr_strtok(str
+ 1, "/", &last_str
);
279 pvt
->rev
= SVN_STR_TO_REV(str
);
281 str
= apr_strtok(NULL
, "/", &last_str
);
284 pvt
->offset
= apr_atoi64(str
);
286 else if (str
[0] == 't')
288 /* This is a transaction type ID */
289 pvt
->txn_id
= str
+ 1;
290 pvt
->rev
= SVN_INVALID_REVNUM
;