Win32: fix an incorrect error status being propagated to the caller in case
[svn/apache.git] / subversion / libsvn_fs_x / dag.h
blobdd951edcd6f413a2267f8b75555a46c4eaf01513
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
19 * under the License.
20 * ====================================================================
23 #ifndef SVN_LIBSVN_FS_X_DAG_H
24 #define SVN_LIBSVN_FS_X_DAG_H
26 #include "svn_fs.h"
27 #include "svn_delta.h"
28 #include "private/svn_cache.h"
30 #include "fs.h"
31 #include "id.h"
33 #ifdef __cplusplus
34 extern "C" {
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.
46 In other words:
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. */
69 svn_error_t *
70 svn_fs_x__dag_get_node(dag_node_t **node,
71 svn_fs_t *fs,
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. */
81 dag_node_t *
82 svn_fs_x__dag_dup(const dag_node_t *node,
83 apr_pool_t *result_pool);
85 /* Return the filesystem containing NODE. */
86 svn_fs_t *
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.) */
91 void
92 svn_fs_x__dag_set_fs(dag_node_t *node,
93 svn_fs_t *fs);
96 /* Return NODE's revision number. If NODE has never been committed as
97 part of a revision, set *REV to SVN_INVALID_REVNUM. */
98 svn_revnum_t
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. */
118 svn_boolean_t
119 svn_fs_x__dag_related_node(dag_node_t *lhs,
120 dag_node_t *rhs);
122 /* Return TRUE, iff nodes LHS and RHS have the same node and copy IDs.
124 svn_boolean_t
125 svn_fs_x__dag_same_line_of_history(dag_node_t *lhs,
126 dag_node_t *rhs);
128 /* Return the created path of NODE. The value returned is shared
129 with NODE, and will be deallocated when NODE is. */
130 const char *
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
145 properties.
147 apr_int64_t
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.
153 svn_boolean_t
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. */
157 svn_boolean_t
158 svn_fs_x__dag_has_mergeinfo(dag_node_t *node);
160 /* Return non-zero IFF NODE is currently mutable. */
161 svn_boolean_t
162 svn_fs_x__dag_check_mutable(const dag_node_t *node);
164 /* Return the node kind of NODE. */
165 svn_node_kind_t
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
171 values).
173 If properties do not exist on NODE, *PROPLIST_P will be set to
174 NULL.
176 Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries.
178 svn_error_t *
179 svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p,
180 dag_node_t *node,
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.
189 svn_error_t *
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.
199 svn_error_t *
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.
209 svn_error_t *
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.*/
222 svn_error_t *
223 svn_fs_x__dag_root(dag_node_t **node_p,
224 svn_fs_t *fs,
225 svn_fs_x__change_set_t change_set,
226 apr_pool_t *result_pool,
227 apr_pool_t *scratch_pool);
230 /* Directories. */
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.
238 svn_error_t *
239 svn_fs_x__dag_open(dag_node_t **child_p,
240 dag_node_t *parent,
241 const char *name,
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. */
248 svn_error_t *
249 svn_fs_x__dir_entry_id(svn_fs_x__id_t *id_p,
250 dag_node_t *parent,
251 const char *name,
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. */
257 svn_error_t *
258 svn_fs_x__dag_dir_entries(apr_array_header_t **entries_p,
259 dag_node_t *node,
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
267 occurs.
269 Use SCRATCH_POOL for temporary allocations.
271 svn_error_t *
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
293 created.
295 TXN_ID is the Subversion transaction under which this occurs.
297 Allocate *CHILD_P in RESULT_POOL and use SCRATCH_POOL for temporaries.
299 svn_error_t *
300 svn_fs_x__dag_clone_child(dag_node_t **child_p,
301 dag_node_t *parent,
302 const char *parent_path,
303 const char *name,
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
316 which this occurs.
318 If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in
319 PARENT.
321 Use SCRATCH_POOL for temporary allocations.
323 svn_error_t *
324 svn_fs_x__dag_delete(dag_node_t *parent,
325 const char *name,
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.
341 svn_error_t *
342 svn_fs_x__dag_make_dir(dag_node_t **child_p,
343 dag_node_t *parent,
344 const char *parent_path,
345 const char *name,
346 svn_fs_x__txn_id_t txn_id,
347 apr_pool_t *result_pool,
348 apr_pool_t *scratch_pool);
352 /* Files. */
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.
360 svn_error_t *
361 svn_fs_x__dag_get_contents(svn_stream_t **contents,
362 dag_node_t *file,
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.
371 svn_error_t *
372 svn_fs_x__dag_try_process_file_contents(svn_boolean_t *success,
373 dag_node_t *node,
374 svn_fs_process_contents_func_t processor,
375 void* baton,
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.
385 svn_error_t *
386 svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p,
387 dag_node_t *source,
388 dag_node_t *target,
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.
398 svn_error_t *
399 svn_fs_x__dag_get_edit_stream(svn_stream_t **contents,
400 dag_node_t *file,
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.
415 svn_error_t *
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.
423 svn_error_t *
424 svn_fs_x__dag_file_length(svn_filesize_t *length,
425 dag_node_t *file);
427 /* Put the recorded checksum of type KIND for FILE into CHECKSUM, allocating
428 from RESULT_POOL.
430 If no stored checksum is available, do not calculate the checksum,
431 just put NULL into CHECKSUM.
433 svn_error_t *
434 svn_fs_x__dag_file_checksum(svn_checksum_t **checksum,
435 dag_node_t *file,
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.
449 svn_error_t *
450 svn_fs_x__dag_make_file(dag_node_t **child_p,
451 dag_node_t *parent,
452 const char *parent_path,
453 const char *name,
454 svn_fs_x__txn_id_t txn_id,
455 apr_pool_t *result_pool,
456 apr_pool_t *scratch_pool);
460 /* Copies */
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
469 here.
471 If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored.
473 Use SCRATCH_POOL for temporary allocations.
475 svn_error_t *
476 svn_fs_x__dag_copy(dag_node_t *to_node,
477 const char *entry,
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);
486 /* Comparison */
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.
501 svn_error_t *
502 svn_fs_x__dag_things_different(svn_boolean_t *props_changed,
503 svn_boolean_t *contents_changed,
504 dag_node_t *node1,
505 dag_node_t *node2,
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.
513 void
514 svn_fs_x__dag_get_copyroot(svn_revnum_t *rev,
515 const char **path,
516 dag_node_t *node);
518 /* Return the copyfrom revision associated with NODE.
520 svn_revnum_t
521 svn_fs_x__dag_get_copyfrom_rev(dag_node_t *node);
523 /* Return the copyfrom path associated with NODE.
525 const char *
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.
532 svn_error_t *
533 svn_fs_x__dag_update_ancestry(dag_node_t *target,
534 dag_node_t *source,
535 apr_pool_t *scratch_pool);
536 #ifdef __cplusplus
538 #endif /* __cplusplus */
540 #endif /* SVN_LIBSVN_FS_X_DAG_H */