]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - subversion/libsvn_fs_x/dag.h
Import Subversion-1.10.0
[FreeBSD/FreeBSD.git] / subversion / libsvn_fs_x / dag.h
1 /* dag.h : DAG-like interface filesystem
2  *
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
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
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  * ====================================================================
21  */
22
23 #ifndef SVN_LIBSVN_FS_X_DAG_H
24 #define SVN_LIBSVN_FS_X_DAG_H
25
26 #include "svn_fs.h"
27 #include "svn_delta.h"
28 #include "private/svn_cache.h"
29
30 #include "fs.h"
31 #include "id.h"
32
33 #ifdef __cplusplus
34 extern "C" {
35 #endif /* __cplusplus */
36
37 \f
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.
45
46    In other words:
47
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.
51
52    - The dag_node_t interface exposes the existence of copy nodes,
53      whereas the svn_fs.h handles them transparently.
54
55    - dag_node_t's must be explicitly cloned, whereas the svn_fs.h
56      operations make clones implicitly.
57
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.  */
61
62 \f
63 /* Generic DAG node stuff.  */
64
65 typedef struct dag_node_t dag_node_t;
66
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);
75
76
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);
84
85 /* Return the filesystem containing NODE.  */
86 svn_fs_t *
87 svn_fs_x__dag_get_fs(dag_node_t *node);
88
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);
94
95
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);
100
101
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);
106
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);
111
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);
116
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);
121
122 /* Return TRUE, iff nodes LHS and RHS have the same node and copy IDs.
123  */
124 svn_boolean_t
125 svn_fs_x__dag_same_line_of_history(dag_node_t *lhs,
126                                    dag_node_t *rhs);
127
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);
132
133
134 /* Return the node revision ID of NODE's immediate predecessor.
135  */
136 const svn_fs_x__id_t *
137 svn_fs_x__dag_get_predecessor_id(dag_node_t *node);
138
139 /* Return the number of predecessors NODE has (recursively).
140  */
141 int
142 svn_fs_x__dag_get_predecessor_count(dag_node_t *node);
143
144 /* Return the number of node under NODE (inclusive) with svn:mergeinfo
145    properties.
146  */
147 apr_int64_t
148 svn_fs_x__dag_get_mergeinfo_count(dag_node_t *node);
149
150 /* Return TRUE, iff NODE is a directory with at least one descendant (not
151    including itself) with svn:mergeinfo.
152  */
153 svn_boolean_t
154 svn_fs_x__dag_has_descendants_with_mergeinfo(dag_node_t *node);
155
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);
159
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);
163
164 /* Return the node kind of NODE. */
165 svn_node_kind_t
166 svn_fs_x__dag_node_kind(dag_node_t *node);
167
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).
172
173    If properties do not exist on NODE, *PROPLIST_P will be set to
174    NULL.
175
176    Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries.
177  */
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);
183
184 /* Set the property list of NODE to PROPLIST, allocating from POOL.
185    The node being changed must be mutable.
186
187    Use SCRATCH_POOL for temporary allocations.
188  */
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);
193
194 /* Increment the mergeinfo_count field on NODE by INCREMENT.  The node
195    being changed must be mutable.
196
197    Use SCRATCH_POOL for temporary allocations.
198  */
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);
203
204 /* Set the has-mergeinfo flag on NODE to HAS_MERGEINFO.  The node
205    being changed must be mutable.
206
207    Use SCRATCH_POOL for temporary allocations.
208  */
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);
213
214
215 \f
216 /* Revision and transaction roots.  */
217
218
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);
228
229 \f
230 /* Directories.  */
231
232
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.
237  */
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);
244
245
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);
253
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);
262
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.
268
269    Use SCRATCH_POOL for temporary allocations.
270  */
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);
278
279
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.
287
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.
291
292    PATH is the canonicalized absolute path at which this node is being
293    created.
294
295    TXN_ID is the Subversion transaction under which this occurs.
296
297    Allocate *CHILD_P in RESULT_POOL and use SCRATCH_POOL for temporaries.
298  */
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);
309
310
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.
317
318    If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in
319    PARENT.
320
321    Use SCRATCH_POOL for temporary allocations.
322  */
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);
328
329
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.
338
339    Use SCRATCH_POOL for temporary allocations.
340  */
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);
349
350
351 \f
352 /* Files.  */
353
354
355 /* Set *CONTENTS to a readable generic stream which yields the
356    contents of FILE.  Allocate the stream in RESULT_POOL.
357
358    If FILE is not a file, return SVN_ERR_FS_NOT_FILE.
359  */
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);
364
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.
368
369    Use SCRATCH_POOL for temporary allocations.
370  */
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);
377
378
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.
382
383    Use SCRATCH_POOL for temporary allocations.
384  */
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);
391
392 /* Return a generic writable stream in *CONTENTS with which to set the
393    contents of FILE.  Allocate the stream in RESULT_POOL.
394
395    Any previous edits on the file will be deleted, and a new edit
396    stream will be constructed.
397  */
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);
402
403
404 /* Signify the completion of edits to FILE made using the stream
405    returned by svn_fs_x__dag_get_edit_stream.
406
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.
410
411    This operation is a no-op if no edits are present.
412
413    Use SCRATCH_POOL for temporary allocations.
414  */
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);
419
420
421 /* Set *LENGTH to the length of the contents of FILE.
422  */
423 svn_error_t *
424 svn_fs_x__dag_file_length(svn_filesize_t *length,
425                           dag_node_t *file);
426
427 /* Put the recorded checksum of type KIND for FILE into CHECKSUM, allocating
428    from RESULT_POOL.
429
430    If no stored checksum is available, do not calculate the checksum,
431    just put NULL into CHECKSUM.
432  */
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);
438
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.
446
447    Use SCRATCH_POOL for temporary allocations.
448  */
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);
457
458
459 \f
460 /* Copies */
461
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.
464
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.
470
471    If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored.
472
473    Use SCRATCH_POOL for temporary allocations.
474  */
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);
484
485 \f
486 /* Comparison */
487
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.
491
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.
494
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.
498
499    Use SCRATCH_POOL for temporary allocations.
500  */
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);
508
509
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.
512  */
513 void
514 svn_fs_x__dag_get_copyroot(svn_revnum_t *rev,
515                            const char **path,
516                            dag_node_t *node);
517
518 /* Return the copyfrom revision associated with NODE.
519  */
520 svn_revnum_t
521 svn_fs_x__dag_get_copyfrom_rev(dag_node_t *node);
522
523 /* Return the copyfrom path associated with NODE.
524  */
525 const char *
526 svn_fs_x__dag_get_copyfrom_path(dag_node_t *node);
527
528 /* Update *TARGET so that SOURCE is it's predecessor.
529
530    Use SCRATCH_POOL for temporary allocations.
531  */
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
537 }
538 #endif /* __cplusplus */
539
540 #endif /* SVN_LIBSVN_FS_X_DAG_H */