1 /* dag.h : DAG-like interface filesystem
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_X_DAG_H
24 #define SVN_LIBSVN_FS_X_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 /* Return the filesystem containing NODE. */
87 svn_fs_x__dag_get_fs(dag_node_t
*node
);
89 /* Changes the filesystem containing NODE to FS. (Used when pulling
90 nodes out of a shared cache, say.) */
92 svn_fs_x__dag_set_fs(dag_node_t
*node
,
96 /* Return NODE's revision number. If NODE has never been committed as
97 part of a revision, set *REV to SVN_INVALID_REVNUM. */
99 svn_fs_x__dag_get_revision(const dag_node_t
*node
);
102 /* Return the node revision ID of NODE. The value returned is shared
103 with NODE, and will be deallocated when NODE is. */
104 const svn_fs_x__id_t
*
105 svn_fs_x__dag_get_id(const dag_node_t
*node
);
107 /* Return the node ID of NODE. The value returned is shared with NODE,
108 and will be deallocated when NODE is. */
109 const svn_fs_x__id_t
*
110 svn_fs_x__dag_get_node_id(dag_node_t
*node
);
112 /* Return the copy ID of NODE. The value returned is shared with NODE,
113 and will be deallocated when NODE is. */
114 const svn_fs_x__id_t
*
115 svn_fs_x__dag_get_copy_id(dag_node_t
*node
);
117 /* Return TRUE, iff nodes LHS and RHS have the same node ID. */
119 svn_fs_x__dag_related_node(dag_node_t
*lhs
,
122 /* Return TRUE, iff nodes LHS and RHS have the same node and copy IDs.
125 svn_fs_x__dag_same_line_of_history(dag_node_t
*lhs
,
128 /* Return the created path of NODE. The value returned is shared
129 with NODE, and will be deallocated when NODE is. */
131 svn_fs_x__dag_get_created_path(dag_node_t
*node
);
134 /* Return the node revision ID of NODE's immediate predecessor.
136 const svn_fs_x__id_t
*
137 svn_fs_x__dag_get_predecessor_id(dag_node_t
*node
);
139 /* Return the number of predecessors NODE has (recursively).
142 svn_fs_x__dag_get_predecessor_count(dag_node_t
*node
);
144 /* Return the number of node under NODE (inclusive) with svn:mergeinfo
148 svn_fs_x__dag_get_mergeinfo_count(dag_node_t
*node
);
150 /* Return TRUE, iff NODE is a directory with at least one descendant (not
151 including itself) with svn:mergeinfo.
154 svn_fs_x__dag_has_descendants_with_mergeinfo(dag_node_t
*node
);
156 /* Return TRUE, iff NODE itself has svn:mergeinfo set on it. */
158 svn_fs_x__dag_has_mergeinfo(dag_node_t
*node
);
160 /* Return non-zero IFF NODE is currently mutable. */
162 svn_fs_x__dag_check_mutable(const dag_node_t
*node
);
164 /* Return the node kind of NODE. */
166 svn_fs_x__dag_node_kind(dag_node_t
*node
);
168 /* Set *PROPLIST_P to a PROPLIST hash representing the entire property
169 list of NODE, allocating from POOL. The hash has const char *
170 names (the property names) and svn_string_t * values (the property
173 If properties do not exist on NODE, *PROPLIST_P will be set to
176 Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries.
179 svn_fs_x__dag_get_proplist(apr_hash_t
**proplist_p
,
181 apr_pool_t
*result_pool
,
182 apr_pool_t
*scratch_pool
);
184 /* Set the property list of NODE to PROPLIST, allocating from POOL.
185 The node being changed must be mutable.
187 Use SCRATCH_POOL for temporary allocations.
190 svn_fs_x__dag_set_proplist(dag_node_t
*node
,
191 apr_hash_t
*proplist
,
192 apr_pool_t
*scratch_pool
);
194 /* Increment the mergeinfo_count field on NODE by INCREMENT. The node
195 being changed must be mutable.
197 Use SCRATCH_POOL for temporary allocations.
200 svn_fs_x__dag_increment_mergeinfo_count(dag_node_t
*node
,
201 apr_int64_t increment
,
202 apr_pool_t
*scratch_pool
);
204 /* Set the has-mergeinfo flag on NODE to HAS_MERGEINFO. The node
205 being changed must be mutable.
207 Use SCRATCH_POOL for temporary allocations.
210 svn_fs_x__dag_set_has_mergeinfo(dag_node_t
*node
,
211 svn_boolean_t has_mergeinfo
,
212 apr_pool_t
*scratch_pool
);
216 /* Revision and transaction roots. */
219 /* Open the root of change set CHANGE_SET of filesystem FS, allocating from
220 RESULT_POOL. Set *NODE_P to the new node. Use SCRATCH_POOL for
221 temporary allocations.*/
223 svn_fs_x__dag_root(dag_node_t
**node_p
,
225 svn_fs_x__change_set_t change_set
,
226 apr_pool_t
*result_pool
,
227 apr_pool_t
*scratch_pool
);
233 /* Open the node named NAME in the directory PARENT. Set *CHILD_P to
234 the new node, allocated in RESULT_POOL. NAME must be a single path
235 component; it cannot be a slash-separated directory path. If NAME does
236 not exist within PARENT, set *CHILD_P to NULL.
239 svn_fs_x__dag_open(dag_node_t
**child_p
,
242 apr_pool_t
*result_pool
,
243 apr_pool_t
*scratch_pool
);
246 /* Set *ID_P to the noderev-id for entry NAME in PARENT. If no such
247 entry exists, set *ID_P to "unused" but do not error. */
249 svn_fs_x__dir_entry_id(svn_fs_x__id_t
*id_p
,
252 apr_pool_t
*scratch_pool
);
254 /* Set *ENTRIES_P to an array of NODE's entries, sorted by entry names,
255 and the values are svn_fs_x__dirent_t. The returned table (and elements)
256 is allocated in RESULT_POOL, temporaries in SCRATCH_POOL. */
258 svn_fs_x__dag_dir_entries(apr_array_header_t
**entries_p
,
260 apr_pool_t
*result_pool
,
261 apr_pool_t
*scratch_pool
);
263 /* Set ENTRY_NAME in NODE to point to ID (with kind KIND), allocating
264 from POOL. NODE must be a mutable directory. ID can refer to a
265 mutable or immutable node. If ENTRY_NAME does not exist, it will
266 be created. TXN_ID is the Subversion transaction under which this
269 Use SCRATCH_POOL for temporary allocations.
272 svn_fs_x__dag_set_entry(dag_node_t
*node
,
273 const char *entry_name
,
274 const svn_fs_x__id_t
*id
,
275 svn_node_kind_t kind
,
276 svn_fs_x__txn_id_t txn_id
,
277 apr_pool_t
*scratch_pool
);
280 /* Make a new mutable clone of the node named NAME in PARENT, and
281 adjust PARENT's directory entry to point to it, unless NAME in
282 PARENT already refers to a mutable node. In either case, set
283 *CHILD_P to a reference to the new node, allocated in POOL. PARENT
284 must be mutable. NAME must be a single path component; it cannot
285 be a slash-separated directory path. PARENT_PATH must be the
286 canonicalized absolute path of the parent directory.
288 COPY_ID, if non-NULL, is a key into the `copies' table, and
289 indicates that this new node is being created as the result of a
290 copy operation, and specifically which operation that was.
292 PATH is the canonicalized absolute path at which this node is being
295 TXN_ID is the Subversion transaction under which this occurs.
297 Allocate *CHILD_P in RESULT_POOL and use SCRATCH_POOL for temporaries.
300 svn_fs_x__dag_clone_child(dag_node_t
**child_p
,
302 const char *parent_path
,
304 const svn_fs_x__id_t
*copy_id
,
305 svn_fs_x__txn_id_t txn_id
,
306 svn_boolean_t is_parent_copyroot
,
307 apr_pool_t
*result_pool
,
308 apr_pool_t
*scratch_pool
);
311 /* Delete the directory entry named NAME from PARENT, allocating from
312 POOL. PARENT must be mutable. NAME must be a single path
313 component; it cannot be a slash-separated directory path. If the
314 node being deleted is a mutable directory, remove all mutable nodes
315 reachable from it. TXN_ID is the Subversion transaction under
318 If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in
321 Use SCRATCH_POOL for temporary allocations.
324 svn_fs_x__dag_delete(dag_node_t
*parent
,
326 svn_fs_x__txn_id_t txn_id
,
327 apr_pool_t
*scratch_pool
);
330 /* Create a new mutable directory named NAME in PARENT. Set *CHILD_P
331 to a reference to the new node, allocated in RESULT_POOL. The new
332 directory has no contents, and no properties. PARENT must be
333 mutable. NAME must be a single path component; it cannot be a
334 slash-separated directory path. PARENT_PATH must be the
335 canonicalized absolute path of the parent directory. PARENT must
336 not currently have an entry named NAME. TXN_ID is the Subversion
337 transaction under which this occurs.
339 Use SCRATCH_POOL for temporary allocations.
342 svn_fs_x__dag_make_dir(dag_node_t
**child_p
,
344 const char *parent_path
,
346 svn_fs_x__txn_id_t txn_id
,
347 apr_pool_t
*result_pool
,
348 apr_pool_t
*scratch_pool
);
355 /* Set *CONTENTS to a readable generic stream which yields the
356 contents of FILE. Allocate the stream in RESULT_POOL.
358 If FILE is not a file, return SVN_ERR_FS_NOT_FILE.
361 svn_fs_x__dag_get_contents(svn_stream_t
**contents
,
363 apr_pool_t
*result_pool
);
365 /* Attempt to fetch the contents of NODE and pass it along with the BATON
366 to the PROCESSOR. Set *SUCCESS only of the data could be provided
367 and the processor had been called.
369 Use SCRATCH_POOL for temporary allocations.
372 svn_fs_x__dag_try_process_file_contents(svn_boolean_t
*success
,
374 svn_fs_process_contents_func_t processor
,
376 apr_pool_t
*scratch_pool
);
379 /* Set *STREAM_P to a delta stream that will turn the contents of SOURCE into
380 the contents of TARGET, allocated in RESULT_POOL. If SOURCE is null, the
381 empty string will be used is its stead.
383 Use SCRATCH_POOL for temporary allocations.
386 svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t
**stream_p
,
389 apr_pool_t
*result_pool
,
390 apr_pool_t
*scratch_pool
);
392 /* Return a generic writable stream in *CONTENTS with which to set the
393 contents of FILE. Allocate the stream in RESULT_POOL.
395 Any previous edits on the file will be deleted, and a new edit
396 stream will be constructed.
399 svn_fs_x__dag_get_edit_stream(svn_stream_t
**contents
,
401 apr_pool_t
*result_pool
);
404 /* Signify the completion of edits to FILE made using the stream
405 returned by svn_fs_x__dag_get_edit_stream.
407 If CHECKSUM is non-null, it must match the checksum for FILE's
408 contents (note: this is not recalculated, the recorded checksum is
409 used), else the error SVN_ERR_CHECKSUM_MISMATCH is returned.
411 This operation is a no-op if no edits are present.
413 Use SCRATCH_POOL for temporary allocations.
416 svn_fs_x__dag_finalize_edits(dag_node_t
*file
,
417 const svn_checksum_t
*checksum
,
418 apr_pool_t
*scratch_pool
);
421 /* Set *LENGTH to the length of the contents of FILE.
424 svn_fs_x__dag_file_length(svn_filesize_t
*length
,
427 /* Put the recorded checksum of type KIND for FILE into CHECKSUM, allocating
430 If no stored checksum is available, do not calculate the checksum,
431 just put NULL into CHECKSUM.
434 svn_fs_x__dag_file_checksum(svn_checksum_t
**checksum
,
436 svn_checksum_kind_t kind
,
437 apr_pool_t
*result_pool
);
439 /* Create a new mutable file named NAME in PARENT. Set *CHILD_P to a
440 reference to the new node, allocated in RESULT_POOL. The new file's
441 contents are the empty string, and it has no properties. PARENT
442 must be mutable. NAME must be a single path component; it cannot
443 be a slash-separated directory path. PARENT_PATH must be the
444 canonicalized absolute path of the parent directory. TXN_ID is the
445 Subversion transaction under which this occurs.
447 Use SCRATCH_POOL for temporary allocations.
450 svn_fs_x__dag_make_file(dag_node_t
**child_p
,
452 const char *parent_path
,
454 svn_fs_x__txn_id_t txn_id
,
455 apr_pool_t
*result_pool
,
456 apr_pool_t
*scratch_pool
);
462 /* Make ENTRY in TO_NODE be a copy of FROM_NODE. TO_NODE must be mutable.
463 TXN_ID is the Subversion transaction under which this occurs.
465 If PRESERVE_HISTORY is true, the new node will record that it was
466 copied from FROM_PATH in FROM_REV; therefore, FROM_NODE should be
467 the node found at FROM_PATH in FROM_REV, although this is not
468 checked. FROM_PATH should be canonicalized before being passed
471 If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored.
473 Use SCRATCH_POOL for temporary allocations.
476 svn_fs_x__dag_copy(dag_node_t
*to_node
,
478 dag_node_t
*from_node
,
479 svn_boolean_t preserve_history
,
480 svn_revnum_t from_rev
,
481 const char *from_path
,
482 svn_fs_x__txn_id_t txn_id
,
483 apr_pool_t
*scratch_pool
);
488 /* Find out what is the same between two nodes. If STRICT is FALSE,
489 this function may report false positives, i.e. report changes even
490 if the resulting contents / props are equal.
492 If PROPS_CHANGED is non-null, set *PROPS_CHANGED to 1 if the two
493 nodes have different property lists, or to 0 if same.
495 If CONTENTS_CHANGED is non-null, set *CONTENTS_CHANGED to 1 if the
496 two nodes have different contents, or to 0 if same. NODE1 and NODE2
497 must refer to files from the same filesystem.
499 Use SCRATCH_POOL for temporary allocations.
502 svn_fs_x__dag_things_different(svn_boolean_t
*props_changed
,
503 svn_boolean_t
*contents_changed
,
506 svn_boolean_t strict
,
507 apr_pool_t
*scratch_pool
);
510 /* Set *REV and *PATH to the copyroot revision and path of node NODE, or
511 to SVN_INVALID_REVNUM and NULL if no copyroot exists.
514 svn_fs_x__dag_get_copyroot(svn_revnum_t
*rev
,
518 /* Return the copyfrom revision associated with NODE.
521 svn_fs_x__dag_get_copyfrom_rev(dag_node_t
*node
);
523 /* Return the copyfrom path associated with NODE.
526 svn_fs_x__dag_get_copyfrom_path(dag_node_t
*node
);
528 /* Update *TARGET so that SOURCE is it's predecessor.
530 Use SCRATCH_POOL for temporary allocations.
533 svn_fs_x__dag_update_ancestry(dag_node_t
*target
,
535 apr_pool_t
*scratch_pool
);
538 #endif /* __cplusplus */
540 #endif /* SVN_LIBSVN_FS_X_DAG_H */