1 /* dag.h : DAG-like interface filesystem, private to libsvn_fs
3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
20 * ====================================================================
23 #ifndef SVN_LIBSVN_FS_DAG_H
24 #define SVN_LIBSVN_FS_DAG_H
27 #include "svn_delta.h"
28 #include "private/svn_cache.h"
35 #endif /* __cplusplus */
38 /* The interface in this file provides all the essential filesystem
39 operations, but exposes the filesystem's DAG structure. This makes
40 it simpler to implement than the public interface, since a client
41 of this interface has to understand and cope with shared structure
42 directly as it appears in the database. However, it's still a
43 self-consistent set of invariants to maintain, making it
44 (hopefully) a useful interface boundary.
48 - The dag_node_t interface exposes the internal DAG structure of
49 the filesystem, while the svn_fs.h interface does any cloning
50 necessary to make the filesystem look like a tree.
52 - The dag_node_t interface exposes the existence of copy nodes,
53 whereas the svn_fs.h handles them transparently.
55 - dag_node_t's must be explicitly cloned, whereas the svn_fs.h
56 operations make clones implicitly.
58 - Callers of the dag_node_t interface use Berkeley DB transactions
59 to ensure consistency between operations, while callers of the
60 svn_fs.h interface use Subversion transactions. */
63 /* Generic DAG node stuff. */
65 typedef struct dag_node_t dag_node_t;
67 /* Fill *NODE with a dag_node_t representing node revision ID in FS,
68 allocating in RESULT_POOL. Use SCRATCH_POOL for temporaries. */
70 svn_fs_x__dag_get_node(dag_node_t **node,
72 const svn_fs_x__id_t *id,
73 apr_pool_t *result_pool,
74 apr_pool_t *scratch_pool);
77 /* Return a new dag_node_t object referring to the same node as NODE,
78 allocated in RESULT_POOL. If you're trying to build a structure in a
79 pool that wants to refer to dag nodes that may have been allocated
80 elsewhere, you can call this function and avoid inter-pool pointers. */
82 svn_fs_x__dag_dup(const dag_node_t *node,
83 apr_pool_t *result_pool);
85 /* If NODE has been allocated in POOL, return NODE. Otherwise, return
86 a copy created in RESULT_POOL with svn_fs_fs__dag_dup. */
88 svn_fs_x__dag_copy_into_pool(dag_node_t *node,
89 apr_pool_t *result_pool);
91 /* Serialize a DAG node, except don't try to preserve the 'fs' member.
92 Implements svn_cache__serialize_func_t */
94 svn_fs_x__dag_serialize(void **data,
99 /* Deserialize a DAG node, leaving the 'fs' member as NULL.
100 Implements svn_cache__deserialize_func_t */
102 svn_fs_x__dag_deserialize(void **out,
107 /* Return the filesystem containing NODE. */
109 svn_fs_x__dag_get_fs(dag_node_t *node);
111 /* Changes the filesystem containing NODE to FS. (Used when pulling
112 nodes out of a shared cache, say.) */
114 svn_fs_x__dag_set_fs(dag_node_t *node,
118 /* Return NODE's revision number. If NODE has never been committed as
119 part of a revision, set *REV to SVN_INVALID_REVNUM. */
121 svn_fs_x__dag_get_revision(const dag_node_t *node);
124 /* Return the node revision ID of NODE. The value returned is shared
125 with NODE, and will be deallocated when NODE is. */
126 const svn_fs_x__id_t *
127 svn_fs_x__dag_get_id(const dag_node_t *node);
129 /* Return the node ID of NODE. The value returned is shared with NODE,
130 and will be deallocated when NODE is. */
132 svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id,
135 /* Return the copy ID of NODE. The value returned is shared with NODE,
136 and will be deallocated when NODE is. */
138 svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id,
141 /* Set *SAME to TRUE, if nodes LHS and RHS have the same node ID. */
143 svn_fs_x__dag_related_node(svn_boolean_t *same,
147 /* Set *SAME to TRUE, if nodes LHS and RHS have the same node and copy IDs.
150 svn_fs_x__dag_same_line_of_history(svn_boolean_t *same,
154 /* Return the created path of NODE. The value returned is shared
155 with NODE, and will be deallocated when NODE is. */
157 svn_fs_x__dag_get_created_path(dag_node_t *node);
160 /* Set *ID_P to the node revision ID of NODE's immediate predecessor.
163 svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p,
167 /* Set *COUNT to the number of predecessors NODE has (recursively).
169 /* ### This function is currently only used by 'verify'. */
171 svn_fs_x__dag_get_predecessor_count(int *count,
174 /* Set *COUNT to the number of node under NODE (inclusive) with
175 svn:mergeinfo properties.
178 svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count,
181 /* Set *DO_THEY to a flag indicating whether or not NODE is a
182 directory with at least one descendant (not including itself) with
186 svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they,
189 /* Set *HAS_MERGEINFO to a flag indicating whether or not NODE itself
190 has svn:mergeinfo set on it.
193 svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo,
196 /* Return non-zero IFF NODE is currently mutable. */
198 svn_fs_x__dag_check_mutable(const dag_node_t *node);
200 /* Return the node kind of NODE. */
202 svn_fs_x__dag_node_kind(dag_node_t *node);
204 /* Set *PROPLIST_P to a PROPLIST hash representing the entire property
205 list of NODE, allocating from POOL. The hash has const char *
206 names (the property names) and svn_string_t * values (the property
209 If properties do not exist on NODE, *PROPLIST_P will be set to
212 Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries.
215 svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p,
217 apr_pool_t *result_pool,
218 apr_pool_t *scratch_pool);
220 /* Set the property list of NODE to PROPLIST, allocating from POOL.
221 The node being changed must be mutable.
223 Use SCRATCH_POOL for temporary allocations.
226 svn_fs_x__dag_set_proplist(dag_node_t *node,
227 apr_hash_t *proplist,
228 apr_pool_t *scratch_pool);
230 /* Increment the mergeinfo_count field on NODE by INCREMENT. The node
231 being changed must be mutable.
233 Use SCRATCH_POOL for temporary allocations.
236 svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node,
237 apr_int64_t increment,
238 apr_pool_t *scratch_pool);
240 /* Set the has-mergeinfo flag on NODE to HAS_MERGEINFO. The node
241 being changed must be mutable.
243 Use SCRATCH_POOL for temporary allocations.
246 svn_fs_x__dag_set_has_mergeinfo(dag_node_t *node,
247 svn_boolean_t has_mergeinfo,
248 apr_pool_t *scratch_pool);
252 /* Revision and transaction roots. */
255 /* Open the root of revision REV of filesystem FS, allocating from
256 RESULT_POOL. Set *NODE_P to the new node. Use SCRATCH_POOL for
257 temporary allocations.*/
259 svn_fs_x__dag_revision_root(dag_node_t **node_p,
262 apr_pool_t *result_pool,
263 apr_pool_t *scratch_pool);
266 /* Set *NODE_P to the root of transaction TXN_ID in FS, allocating
267 from RESULT_POOL. Use SCRATCH_POOL for temporary allocations. */
269 svn_fs_x__dag_txn_root(dag_node_t **node_p,
271 svn_fs_x__txn_id_t txn_id,
272 apr_pool_t *result_pool,
273 apr_pool_t *scratch_pool);
279 /* Open the node named NAME in the directory PARENT. Set *CHILD_P to
280 the new node, allocated in RESULT_POOL. NAME must be a single path
281 component; it cannot be a slash-separated directory path. If NAME does
282 not exist within PARENT, set *CHILD_P to NULL.
285 svn_fs_x__dag_open(dag_node_t **child_p,
288 apr_pool_t *result_pool,
289 apr_pool_t *scratch_pool);
292 /* Set *ENTRIES_P to an array of NODE's entries, sorted by entry names,
293 and the values are svn_fs_x__dirent_t. The returned table (and elements)
294 is allocated in RESULT_POOL, temporaries in SCRATCH_POOL. */
296 svn_fs_x__dag_dir_entries(apr_array_header_t **entries_p,
298 apr_pool_t *result_pool,
299 apr_pool_t *scratch_pool);
301 /* Set ENTRY_NAME in NODE to point to ID (with kind KIND), allocating
302 from POOL. NODE must be a mutable directory. ID can refer to a
303 mutable or immutable node. If ENTRY_NAME does not exist, it will
304 be created. TXN_ID is the Subversion transaction under which this
307 Use SCRATCH_POOL for temporary allocations.
310 svn_fs_x__dag_set_entry(dag_node_t *node,
311 const char *entry_name,
312 const svn_fs_x__id_t *id,
313 svn_node_kind_t kind,
314 svn_fs_x__txn_id_t txn_id,
315 apr_pool_t *scratch_pool);
318 /* Make a new mutable clone of the node named NAME in PARENT, and
319 adjust PARENT's directory entry to point to it, unless NAME in
320 PARENT already refers to a mutable node. In either case, set
321 *CHILD_P to a reference to the new node, allocated in POOL. PARENT
322 must be mutable. NAME must be a single path component; it cannot
323 be a slash-separated directory path. PARENT_PATH must be the
324 canonicalized absolute path of the parent directory.
326 COPY_ID, if non-NULL, is a key into the `copies' table, and
327 indicates that this new node is being created as the result of a
328 copy operation, and specifically which operation that was.
330 PATH is the canonicalized absolute path at which this node is being
333 TXN_ID is the Subversion transaction under which this occurs.
335 Allocate *CHILD_P in RESULT_POOL and use SCRATCH_POOL for temporaries.
338 svn_fs_x__dag_clone_child(dag_node_t **child_p,
340 const char *parent_path,
342 const svn_fs_x__id_t *copy_id,
343 svn_fs_x__txn_id_t txn_id,
344 svn_boolean_t is_parent_copyroot,
345 apr_pool_t *result_pool,
346 apr_pool_t *scratch_pool);
349 /* Delete the directory entry named NAME from PARENT, allocating from
350 POOL. PARENT must be mutable. NAME must be a single path
351 component; it cannot be a slash-separated directory path. If the
352 node being deleted is a mutable directory, remove all mutable nodes
353 reachable from it. TXN_ID is the Subversion transaction under
356 If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in
359 Use SCRATCH_POOL for temporary allocations.
362 svn_fs_x__dag_delete(dag_node_t *parent,
364 svn_fs_x__txn_id_t txn_id,
365 apr_pool_t *scratch_pool);
368 /* Create a new mutable directory named NAME in PARENT. Set *CHILD_P
369 to a reference to the new node, allocated in RESULT_POOL. The new
370 directory has no contents, and no properties. PARENT must be
371 mutable. NAME must be a single path component; it cannot be a
372 slash-separated directory path. PARENT_PATH must be the
373 canonicalized absolute path of the parent directory. PARENT must
374 not currently have an entry named NAME. TXN_ID is the Subversion
375 transaction under which this occurs.
377 Use SCRATCH_POOL for temporary allocations.
380 svn_fs_x__dag_make_dir(dag_node_t **child_p,
382 const char *parent_path,
384 svn_fs_x__txn_id_t txn_id,
385 apr_pool_t *result_pool,
386 apr_pool_t *scratch_pool);
393 /* Set *CONTENTS to a readable generic stream which yields the
394 contents of FILE. Allocate the stream in RESULT_POOL.
396 If FILE is not a file, return SVN_ERR_FS_NOT_FILE.
399 svn_fs_x__dag_get_contents(svn_stream_t **contents,
401 apr_pool_t *result_pool);
403 /* Attempt to fetch the contents of NODE and pass it along with the BATON
404 to the PROCESSOR. Set *SUCCESS only of the data could be provided
405 and the processor had been called.
407 Use SCRATCH_POOL for temporary allocations.
410 svn_fs_x__dag_try_process_file_contents(svn_boolean_t *success,
412 svn_fs_process_contents_func_t processor,
414 apr_pool_t *scratch_pool);
417 /* Set *STREAM_P to a delta stream that will turn the contents of SOURCE into
418 the contents of TARGET, allocated in RESULT_POOL. If SOURCE is null, the
419 empty string will be used is its stead.
421 Use SCRATCH_POOL for temporary allocations.
424 svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p,
427 apr_pool_t *result_pool,
428 apr_pool_t *scratch_pool);
430 /* Return a generic writable stream in *CONTENTS with which to set the
431 contents of FILE. Allocate the stream in RESULT_POOL.
433 Any previous edits on the file will be deleted, and a new edit
434 stream will be constructed.
437 svn_fs_x__dag_get_edit_stream(svn_stream_t **contents,
439 apr_pool_t *result_pool);
442 /* Signify the completion of edits to FILE made using the stream
443 returned by svn_fs_x__dag_get_edit_stream.
445 If CHECKSUM is non-null, it must match the checksum for FILE's
446 contents (note: this is not recalculated, the recorded checksum is
447 used), else the error SVN_ERR_CHECKSUM_MISMATCH is returned.
449 This operation is a no-op if no edits are present.
451 Use SCRATCH_POOL for temporary allocations.
454 svn_fs_x__dag_finalize_edits(dag_node_t *file,
455 const svn_checksum_t *checksum,
456 apr_pool_t *scratch_pool);
459 /* Set *LENGTH to the length of the contents of FILE.
462 svn_fs_x__dag_file_length(svn_filesize_t *length,
465 /* Put the recorded checksum of type KIND for FILE into CHECKSUM, allocating
468 If no stored checksum is available, do not calculate the checksum,
469 just put NULL into CHECKSUM.
472 svn_fs_x__dag_file_checksum(svn_checksum_t **checksum,
474 svn_checksum_kind_t kind,
475 apr_pool_t *result_pool);
477 /* Create a new mutable file named NAME in PARENT. Set *CHILD_P to a
478 reference to the new node, allocated in RESULT_POOL. The new file's
479 contents are the empty string, and it has no properties. PARENT
480 must be mutable. NAME must be a single path component; it cannot
481 be a slash-separated directory path. PARENT_PATH must be the
482 canonicalized absolute path of the parent directory. TXN_ID is the
483 Subversion transaction under which this occurs.
485 Use SCRATCH_POOL for temporary allocations.
488 svn_fs_x__dag_make_file(dag_node_t **child_p,
490 const char *parent_path,
492 svn_fs_x__txn_id_t txn_id,
493 apr_pool_t *result_pool,
494 apr_pool_t *scratch_pool);
500 /* Make ENTRY in TO_NODE be a copy of FROM_NODE. TO_NODE must be mutable.
501 TXN_ID is the Subversion transaction under which this occurs.
503 If PRESERVE_HISTORY is true, the new node will record that it was
504 copied from FROM_PATH in FROM_REV; therefore, FROM_NODE should be
505 the node found at FROM_PATH in FROM_REV, although this is not
506 checked. FROM_PATH should be canonicalized before being passed
509 If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored.
511 Use SCRATCH_POOL for temporary allocations.
514 svn_fs_x__dag_copy(dag_node_t *to_node,
516 dag_node_t *from_node,
517 svn_boolean_t preserve_history,
518 svn_revnum_t from_rev,
519 const char *from_path,
520 svn_fs_x__txn_id_t txn_id,
521 apr_pool_t *scratch_pool);
526 /* Find out what is the same between two nodes. If STRICT is FALSE,
527 this function may report false positives, i.e. report changes even
528 if the resulting contents / props are equal.
530 If PROPS_CHANGED is non-null, set *PROPS_CHANGED to 1 if the two
531 nodes have different property lists, or to 0 if same.
533 If CONTENTS_CHANGED is non-null, set *CONTENTS_CHANGED to 1 if the
534 two nodes have different contents, or to 0 if same. NODE1 and NODE2
535 must refer to files from the same filesystem.
537 Use SCRATCH_POOL for temporary allocations.
540 svn_fs_x__dag_things_different(svn_boolean_t *props_changed,
541 svn_boolean_t *contents_changed,
544 svn_boolean_t strict,
545 apr_pool_t *scratch_pool);
548 /* Set *REV and *PATH to the copyroot revision and path of node NODE, or
549 to SVN_INVALID_REVNUM and NULL if no copyroot exists.
552 svn_fs_x__dag_get_copyroot(svn_revnum_t *rev,
556 /* Set *REV to the copyfrom revision associated with NODE.
559 svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev,
562 /* Set *PATH to the copyfrom path associated with NODE.
565 svn_fs_x__dag_get_copyfrom_path(const char **path,
568 /* Update *TARGET so that SOURCE is it's predecessor.
570 Use SCRATCH_POOL for temporary allocations.
573 svn_fs_x__dag_update_ancestry(dag_node_t *target,
575 apr_pool_t *scratch_pool);
578 #endif /* __cplusplus */
580 #endif /* SVN_LIBSVN_FS_DAG_H */