Remove no-longer-used svn_*_get_mergeinfo_for_tree APIs.
[svn.git] / subversion / libsvn_fs_fs / dag.h
blob8b50c93bc89e0cd417141359e400e5d1e6a597b5
1 /* dag.h : DAG-like interface filesystem, private to libsvn_fs
3 * ====================================================================
4 * Copyright (c) 2000-2006 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 * ====================================================================
18 #ifndef SVN_LIBSVN_FS_DAG_H
19 #define SVN_LIBSVN_FS_DAG_H
21 #include "svn_fs.h"
22 #include "svn_delta.h"
24 #include "fs.h"
26 #ifdef __cplusplus
27 extern "C" {
28 #endif /* __cplusplus */
31 /* The interface in this file provides all the essential filesystem
32 operations, but exposes the filesystem's DAG structure. This makes
33 it simpler to implement than the public interface, since a client
34 of this interface has to understand and cope with shared structure
35 directly as it appears in the database. However, it's still a
36 self-consistent set of invariants to maintain, making it
37 (hopefully) a useful interface boundary.
39 In other words:
41 - The dag_node_t interface exposes the internal DAG structure of
42 the filesystem, while the svn_fs.h interface does any cloning
43 necessary to make the filesystem look like a tree.
45 - The dag_node_t interface exposes the existence of copy nodes,
46 whereas the svn_fs.h handles them transparently.
48 - dag_node_t's must be explicitly cloned, whereas the svn_fs.h
49 operations make clones implicitly.
51 - Callers of the dag_node_t interface use Berkeley DB transactions
52 to ensure consistency between operations, while callers of the
53 svn_fs.h interface use Subversion transactions. */
56 /* Generic DAG node stuff. */
59 /* Fill *NODE with a dag_node_t representing node revision ID in FS,
60 allocating in POOL. */
61 svn_error_t *
62 svn_fs_fs__dag_get_node(dag_node_t **node,
63 svn_fs_t *fs,
64 const svn_fs_id_t *id,
65 apr_pool_t *pool);
68 /* Return a new dag_node_t object referring to the same node as NODE,
69 allocated in POOL. If you're trying to build a structure in a
70 pool that wants to refer to dag nodes that may have been allocated
71 elsewhere, you can call this function and avoid inter-pool pointers. */
72 dag_node_t *svn_fs_fs__dag_dup(dag_node_t *node,
73 apr_pool_t *pool);
76 /* Return the filesystem containing NODE. */
77 svn_fs_t *svn_fs_fs__dag_get_fs(dag_node_t *node);
80 /* Set *REV to NODE's revision number, allocating in POOL. If NODE
81 has never been committed as part of a revision, set *REV to
82 SVN_INVALID_REVNUM. */
83 svn_error_t *svn_fs_fs__dag_get_revision(svn_revnum_t *rev,
84 dag_node_t *node,
85 apr_pool_t *pool);
88 /* Return the node revision ID of NODE. The value returned is shared
89 with NODE, and will be deallocated when NODE is. */
90 const svn_fs_id_t *svn_fs_fs__dag_get_id(dag_node_t *node);
93 /* Return the created path of NODE. The value returned is shared
94 with NODE, and will be deallocated when NODE is. */
95 const char *svn_fs_fs__dag_get_created_path(dag_node_t *node);
98 /* Set *ID_P to the node revision ID of NODE's immediate predecessor,
99 or NULL if NODE has no predecessor, allocating from POOL. */
100 svn_error_t *svn_fs_fs__dag_get_predecessor_id(const svn_fs_id_t **id_p,
101 dag_node_t *node,
102 apr_pool_t *pool);
105 /* Set *COUNT to the number of predecessors NODE has (recursively), or
106 -1 if not known, allocating from POOL. */
107 svn_error_t *svn_fs_fs__dag_get_predecessor_count(int *count,
108 dag_node_t *node,
109 apr_pool_t *pool);
111 /* Set *COUNT to the number of node under NODE (inclusive) with
112 svn:mergeinfo properties, allocating from POOL. */
113 svn_error_t *svn_fs_fs__dag_get_mergeinfo_count(apr_int64_t *count,
114 dag_node_t *node,
115 apr_pool_t *pool);
117 /* Set *DO_THEY to a flag indicating whether or not NODE is a
118 directory with at least one descendant (not including itself) with
119 svn:mergeinfo. */
120 svn_error_t *
121 svn_fs_fs__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they,
122 dag_node_t *node,
123 apr_pool_t *pool);
125 /* Set *HAS_MERGEINFO to a flag indicating whether or not NODE itself
126 has svn:mergeinfo set on it. */
127 svn_error_t *
128 svn_fs_fs__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo,
129 dag_node_t *node,
130 apr_pool_t *pool);
132 /* Return non-zero IFF NODE is currently mutable. */
133 svn_boolean_t svn_fs_fs__dag_check_mutable(dag_node_t *node);
135 /* Return the node kind of NODE. */
136 svn_node_kind_t svn_fs_fs__dag_node_kind(dag_node_t *node);
138 /* Set *PROPLIST_P to a PROPLIST hash representing the entire property
139 list of NODE, allocating from POOL. The hash has const char *
140 names (the property names) and svn_string_t * values (the property
141 values).
143 If properties do not exist on NODE, *PROPLIST_P will be set to
144 NULL. */
145 svn_error_t *svn_fs_fs__dag_get_proplist(apr_hash_t **proplist_p,
146 dag_node_t *node,
147 apr_pool_t *pool);
149 /* Set the property list of NODE to PROPLIST, allocating from POOL.
150 The node being changed must be mutable. */
151 svn_error_t *svn_fs_fs__dag_set_proplist(dag_node_t *node,
152 apr_hash_t *proplist,
153 apr_pool_t *pool);
155 /* Increment the mergeinfo_count field on NODE by INCREMENT. The node
156 being changed must be mutable. */
157 svn_error_t *svn_fs_fs__dag_increment_mergeinfo_count(dag_node_t *node,
158 apr_int64_t increment,
159 apr_pool_t *pool);
161 /* Set the has-mergeinfo flag on NODE to HAS_MERGEINFO. The node
162 being changed must be mutable. */
163 svn_error_t *svn_fs_fs__dag_set_has_mergeinfo(dag_node_t *node,
164 svn_boolean_t has_mergeinfo,
165 apr_pool_t *pool);
169 /* Revision and transaction roots. */
172 /* Open the root of revision REV of filesystem FS, allocating from
173 POOL. Set *NODE_P to the new node. */
174 svn_error_t *svn_fs_fs__dag_revision_root(dag_node_t **node_p,
175 svn_fs_t *fs,
176 svn_revnum_t rev,
177 apr_pool_t *pool);
180 /* Set *NODE_P to the root of transaction TXN_ID in FS, allocating
181 from POOL.
183 Note that the root node of TXN_ID is not necessarily mutable. If
184 no changes have been made in the transaction, then it may share its
185 root directory with its base revision. To get a mutable root node
186 for a transaction, call svn_fs_fs__dag_clone_root. */
187 svn_error_t *svn_fs_fs__dag_txn_root(dag_node_t **node_p,
188 svn_fs_t *fs,
189 const char *txn_id,
190 apr_pool_t *pool);
193 /* Set *NODE_P to the base root of transaction TXN_ID in FS,
194 allocating from POOL. Allocate the node in TRAIL->pool. */
195 svn_error_t *svn_fs_fs__dag_txn_base_root(dag_node_t **node_p,
196 svn_fs_t *fs,
197 const char *txn_id,
198 apr_pool_t *pool);
201 /* Clone the root directory of TXN_ID in FS, and update the
202 `transactions' table entry to point to it, unless this has been
203 done already. In either case, set *ROOT_P to a reference to the
204 root directory clone. Allocate *ROOT_P in POOL. */
205 svn_error_t *svn_fs_fs__dag_clone_root(dag_node_t **root_p,
206 svn_fs_t *fs,
207 const char *txn_id,
208 apr_pool_t *pool);
212 /* Directories. */
215 /* Open the node named NAME in the directory PARENT. Set *CHILD_P to
216 the new node, allocated in POOL. NAME must be a single path
217 component; it cannot be a slash-separated directory path. */
218 svn_error_t *svn_fs_fs__dag_open(dag_node_t **child_p,
219 dag_node_t *parent,
220 const char *name,
221 apr_pool_t *pool);
224 /* Set *ENTRIES_P to a hash table of NODE's entries. The keys of the
225 table are entry names, and the values are svn_fs_dirent_t's. Use
226 POOL for temporary allocations.
228 The returned table is *not* allocated in POOL, and becomes invalid
229 on the next call to this function or svn_fs_fs__rep_contents_dir.
230 If the caller needs the table to live longer, it should copy the
231 hash using svn_fs_fs__copy_dir_entries. */
232 svn_error_t *svn_fs_fs__dag_dir_entries(apr_hash_t **entries_p,
233 dag_node_t *node,
234 apr_pool_t *pool);
237 /* Set ENTRY_NAME in NODE to point to ID (with kind KIND), allocating
238 from POOL. NODE must be a mutable directory. ID can refer to a
239 mutable or immutable node. If ENTRY_NAME does not exist, it will
240 be created. TXN_ID is the Subversion transaction under which this
241 occurs.*/
242 svn_error_t *svn_fs_fs__dag_set_entry(dag_node_t *node,
243 const char *entry_name,
244 const svn_fs_id_t *id,
245 svn_node_kind_t kind,
246 const char *txn_id,
247 apr_pool_t *pool);
250 /* Make a new mutable clone of the node named NAME in PARENT, and
251 adjust PARENT's directory entry to point to it, unless NAME in
252 PARENT already refers to a mutable node. In either case, set
253 *CHILD_P to a reference to the new node, allocated in POOL. PARENT
254 must be mutable. NAME must be a single path component; it cannot
255 be a slash-separated directory path. PARENT_PATH must be the
256 canonicalized absolute path of the parent directory.
258 COPY_ID, if non-NULL, is a key into the `copies' table, and
259 indicates that this new node is being created as the result of a
260 copy operation, and specifically which operation that was.
262 PATH is the canonicalized absolute path at which this node is being
263 created.
265 TXN_ID is the Subversion transaction under which this occurs. */
266 svn_error_t *svn_fs_fs__dag_clone_child(dag_node_t **child_p,
267 dag_node_t *parent,
268 const char *parent_path,
269 const char *name,
270 const char *copy_id,
271 const char *txn_id,
272 svn_boolean_t is_parent_copyroot,
273 apr_pool_t *pool);
276 /* Delete the directory entry named NAME from PARENT, allocating from
277 POOL. PARENT must be mutable. NAME must be a single path
278 component; it cannot be a slash-separated directory path. If the
279 node being deleted is a mutable directory, remove all mutable nodes
280 reachable from it. TXN_ID is the Subversion transaction under
281 which this occurs.
283 If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in
284 PARENT. */
285 svn_error_t *svn_fs_fs__dag_delete(dag_node_t *parent,
286 const char *name,
287 const char *txn_id,
288 apr_pool_t *pool);
291 /* Delete the node revision assigned to node ID from FS's `nodes'
292 table, allocating from POOL. Also delete any mutable
293 representations and strings associated with that node revision. ID
294 may refer to a file or directory, which must be mutable.
296 NOTE: If ID represents a directory, and that directory has mutable
297 children, you risk orphaning those children by leaving them
298 dangling, disconnected from all DAG trees. It is assumed that
299 callers of this interface know what in the world they are doing. */
300 svn_error_t *svn_fs_fs__dag_remove_node(svn_fs_t *fs,
301 const svn_fs_id_t *id,
302 apr_pool_t *pool);
305 /* Delete all mutable node revisions reachable from node ID, including
306 ID itself, from FS's `nodes' table, allocating from POOL. Also
307 delete any mutable representations and strings associated with that
308 node revision. ID may refer to a file or directory, which may be
309 mutable or immutable. */
310 svn_error_t *svn_fs_fs__dag_delete_if_mutable(svn_fs_t *fs,
311 const svn_fs_id_t *id,
312 apr_pool_t *pool);
315 /* Create a new mutable directory named NAME in PARENT. Set *CHILD_P
316 to a reference to the new node, allocated in POOL. The new
317 directory has no contents, and no properties. PARENT must be
318 mutable. NAME must be a single path component; it cannot be a
319 slash-separated directory path. PARENT_PATH must be the
320 canonicalized absolute path of the parent directory. PARENT must
321 not currently have an entry named NAME. Do any temporary
322 allocation in POOL. TXN_ID is the Subversion transaction under
323 which this occurs. */
324 svn_error_t *svn_fs_fs__dag_make_dir(dag_node_t **child_p,
325 dag_node_t *parent,
326 const char *parent_path,
327 const char *name,
328 const char *txn_id,
329 apr_pool_t *pool);
333 /* Files. */
336 /* Set *CONTENTS to a readable generic stream which yields the
337 contents of FILE. Allocate the stream in POOL.
339 If FILE is not a file, return SVN_ERR_FS_NOT_FILE. */
340 svn_error_t *svn_fs_fs__dag_get_contents(svn_stream_t **contents,
341 dag_node_t *file,
342 apr_pool_t *pool);
345 /* Set *STREAM_P to a delta stream that will turn the contents of SOURCE into
346 the contents of TARGET, allocated in POOL. If SOURCE is null, the empty
347 string will be used. */
348 svn_error_t *
349 svn_fs_fs__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p,
350 dag_node_t *source,
351 dag_node_t *target,
352 apr_pool_t *pool);
354 /* Return a generic writable stream in *CONTENTS with which to set the
355 contents of FILE. Allocate the stream in POOL.
357 Any previous edits on the file will be deleted, and a new edit
358 stream will be constructed. */
359 svn_error_t *svn_fs_fs__dag_get_edit_stream(svn_stream_t **contents,
360 dag_node_t *file,
361 apr_pool_t *pool);
364 /* Signify the completion of edits to FILE made using the stream
365 returned by svn_fs_fs__dag_get_edit_stream, allocating from POOL.
367 If CHECKSUM is non-null, it must match the checksum for FILE's
368 contents (note: this is not recalculated, the recorded checksum is
369 used), else the error SVN_ERR_CHECKSUM_MISMATCH is returned.
371 This operation is a no-op if no edits are present. */
372 svn_error_t *svn_fs_fs__dag_finalize_edits(dag_node_t *file,
373 const char *checksum,
374 apr_pool_t *pool);
377 /* Set *LENGTH to the length of the contents of FILE, allocating from
378 POOL. */
379 svn_error_t *svn_fs_fs__dag_file_length(svn_filesize_t *length,
380 dag_node_t *file,
381 apr_pool_t *pool);
383 /* Put the recorded MD5 checksum of FILE into DIGEST, allocating from
384 * POOL. DIGEST must point to APR_MD5_DIGESTSIZE bytes of storage.
386 * If no stored checksum is available, do not calculate the checksum,
387 * just put all 0's into DIGEST.
389 svn_error_t *
390 svn_fs_fs__dag_file_checksum(unsigned char digest[],
391 dag_node_t *file,
392 apr_pool_t *pool);
394 /* Create a new mutable file named NAME in PARENT. Set *CHILD_P to a
395 reference to the new node, allocated in POOL. The new file's
396 contents are the empty string, and it has no properties. PARENT
397 must be mutable. NAME must be a single path component; it cannot
398 be a slash-separated directory path. PARENT_PATH must be the
399 canonicalized absolute path of the parent directory. TXN_ID is the
400 Subversion transaction under which this occurs. */
401 svn_error_t *svn_fs_fs__dag_make_file(dag_node_t **child_p,
402 dag_node_t *parent,
403 const char *parent_path,
404 const char *name,
405 const char *txn_id,
406 apr_pool_t *pool);
410 /* Copies */
412 /* Make ENTRY in TO_NODE be a copy of FROM_NODE, allocating from POOL.
413 TO_NODE must be mutable. TXN_ID is the Subversion transaction
414 under which this occurs.
416 If PRESERVE_HISTORY is true, the new node will record that it was
417 copied from FROM_PATH in FROM_REV; therefore, FROM_NODE should be
418 the node found at FROM_PATH in FROM_REV, although this is not
419 checked. FROM_PATH should be canonicalized before being passed
420 here.
422 If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored. */
423 svn_error_t *svn_fs_fs__dag_copy(dag_node_t *to_node,
424 const char *entry,
425 dag_node_t *from_node,
426 svn_boolean_t preserve_history,
427 svn_revnum_t from_rev,
428 const char *from_path,
429 const char *txn_id,
430 apr_pool_t *pool);
433 /* Comparison */
435 /* Find out what is the same between two nodes.
437 If PROPS_CHANGED is non-null, set *PROPS_CHANGED to 1 if the two
438 nodes have different property lists, or to 0 if same.
440 If CONTENTS_CHANGED is non-null, set *CONTENTS_CHANGED to 1 if the
441 two nodes have different contents, or to 0 if same. For files,
442 file contents are compared; for directories, the entries lists are
443 compared. If one is a file and the other is a directory, the one's
444 contents will be compared to the other's entries list. (Not
445 terribly useful, I suppose, but that's the caller's business.)
447 ### todo: This function only compares rep keys at the moment. This
448 may leave us with a slight chance of a false positive, though I
449 don't really see how that would happen in practice. Nevertheless,
450 it should probably be fixed. */
451 svn_error_t *svn_fs_fs__dag_things_different(svn_boolean_t *props_changed,
452 svn_boolean_t *contents_changed,
453 dag_node_t *node1,
454 dag_node_t *node2,
455 apr_pool_t *pool);
458 /* Set *NODE_ID to the node-id of the coyproot of node NODE, or NULL
459 if no copyroot exists. Get any temporary allocations from POOL. */
460 svn_error_t *svn_fs_fs__dag_get_copyroot(svn_revnum_t *rev,
461 const char **path,
462 dag_node_t *node,
463 apr_pool_t *pool);
465 /* Set *REV to the copyfrom revision associated with NODE. Get any
466 temporary allocations from POOL. */
467 svn_error_t *svn_fs_fs__dag_get_copyfrom_rev(svn_revnum_t *rev,
468 dag_node_t *node,
469 apr_pool_t *pool);
471 /* Set *PATH to the copyfrom path associated with NODE. Get any
472 temporary allocations from POOL. */
473 svn_error_t *svn_fs_fs__dag_get_copyfrom_path(const char **path,
474 dag_node_t *node,
475 apr_pool_t *pool);
477 #ifdef __cplusplus
479 #endif /* __cplusplus */
481 #endif /* SVN_LIBSVN_FS_DAG_H */