]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - contrib/subversion/subversion/libsvn_fs_x/dag.h
MFC r275385 (by bapt):
[FreeBSD/stable/10.git] / contrib / subversion / subversion / libsvn_fs_x / dag.h
1 /* dag.h : DAG-like interface filesystem, private to libsvn_fs
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_DAG_H
24 #define SVN_LIBSVN_FS_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 /* If NODE has been allocated in POOL, return NODE.  Otherwise, return
86    a copy created in RESULT_POOL with svn_fs_fs__dag_dup. */
87 dag_node_t *
88 svn_fs_x__dag_copy_into_pool(dag_node_t *node,
89                              apr_pool_t *result_pool);
90
91 /* Serialize a DAG node, except don't try to preserve the 'fs' member.
92    Implements svn_cache__serialize_func_t */
93 svn_error_t *
94 svn_fs_x__dag_serialize(void **data,
95                         apr_size_t *data_len,
96                         void *in,
97                         apr_pool_t *pool);
98
99 /* Deserialize a DAG node, leaving the 'fs' member as NULL.
100    Implements svn_cache__deserialize_func_t */
101 svn_error_t *
102 svn_fs_x__dag_deserialize(void **out,
103                           void *data,
104                           apr_size_t data_len,
105                           apr_pool_t *pool);
106
107 /* Return the filesystem containing NODE.  */
108 svn_fs_t *
109 svn_fs_x__dag_get_fs(dag_node_t *node);
110
111 /* Changes the filesystem containing NODE to FS.  (Used when pulling
112    nodes out of a shared cache, say.) */
113 void
114 svn_fs_x__dag_set_fs(dag_node_t *node,
115                      svn_fs_t *fs);
116
117
118 /* Return NODE's revision number.  If NODE has never been committed as
119    part of a revision, set *REV to SVN_INVALID_REVNUM.  */
120 svn_revnum_t
121 svn_fs_x__dag_get_revision(const dag_node_t *node);
122
123
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);
128
129 /* Return the node ID of NODE.  The value returned is shared with NODE,
130    and will be deallocated when NODE is.  */
131 svn_error_t *
132 svn_fs_x__dag_get_node_id(svn_fs_x__id_t *node_id,
133                           dag_node_t *node);
134
135 /* Return the copy ID of NODE.  The value returned is shared with NODE,
136    and will be deallocated when NODE is.  */
137 svn_error_t *
138 svn_fs_x__dag_get_copy_id(svn_fs_x__id_t *copy_id,
139                           dag_node_t *node);
140
141 /* Set *SAME to TRUE, if nodes LHS and RHS have the same node ID. */
142 svn_error_t *
143 svn_fs_x__dag_related_node(svn_boolean_t *same,
144                            dag_node_t *lhs,
145                            dag_node_t *rhs);
146
147 /* Set *SAME to TRUE, if nodes LHS and RHS have the same node and copy IDs.
148  */
149 svn_error_t *
150 svn_fs_x__dag_same_line_of_history(svn_boolean_t *same,
151                                    dag_node_t *lhs,
152                                    dag_node_t *rhs);
153
154 /* Return the created path of NODE.  The value returned is shared
155    with NODE, and will be deallocated when NODE is.  */
156 const char *
157 svn_fs_x__dag_get_created_path(dag_node_t *node);
158
159
160 /* Set *ID_P to the node revision ID of NODE's immediate predecessor.
161  */
162 svn_error_t *
163 svn_fs_x__dag_get_predecessor_id(svn_fs_x__id_t *id_p,
164                                  dag_node_t *node);
165
166
167 /* Set *COUNT to the number of predecessors NODE has (recursively).
168  */
169 /* ### This function is currently only used by 'verify'. */
170 svn_error_t *
171 svn_fs_x__dag_get_predecessor_count(int *count,
172                                     dag_node_t *node);
173
174 /* Set *COUNT to the number of node under NODE (inclusive) with
175    svn:mergeinfo properties.
176  */
177 svn_error_t *
178 svn_fs_x__dag_get_mergeinfo_count(apr_int64_t *count,
179                                   dag_node_t *node);
180
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
183    svn:mergeinfo.
184  */
185 svn_error_t *
186 svn_fs_x__dag_has_descendants_with_mergeinfo(svn_boolean_t *do_they,
187                                              dag_node_t *node);
188
189 /* Set *HAS_MERGEINFO to a flag indicating whether or not NODE itself
190    has svn:mergeinfo set on it.
191  */
192 svn_error_t *
193 svn_fs_x__dag_has_mergeinfo(svn_boolean_t *has_mergeinfo,
194                             dag_node_t *node);
195
196 /* Return non-zero IFF NODE is currently mutable. */
197 svn_boolean_t
198 svn_fs_x__dag_check_mutable(const dag_node_t *node);
199
200 /* Return the node kind of NODE. */
201 svn_node_kind_t
202 svn_fs_x__dag_node_kind(dag_node_t *node);
203
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
207    values).
208
209    If properties do not exist on NODE, *PROPLIST_P will be set to
210    NULL.
211
212    Allocate the result in RESULT_POOL and use SCRATCH_POOL for temporaries.
213  */
214 svn_error_t *
215 svn_fs_x__dag_get_proplist(apr_hash_t **proplist_p,
216                            dag_node_t *node,
217                            apr_pool_t *result_pool,
218                            apr_pool_t *scratch_pool);
219
220 /* Set the property list of NODE to PROPLIST, allocating from POOL.
221    The node being changed must be mutable.
222
223    Use SCRATCH_POOL for temporary allocations.
224  */
225 svn_error_t *
226 svn_fs_x__dag_set_proplist(dag_node_t *node,
227                            apr_hash_t *proplist,
228                            apr_pool_t *scratch_pool);
229
230 /* Increment the mergeinfo_count field on NODE by INCREMENT.  The node
231    being changed must be mutable.
232
233    Use SCRATCH_POOL for temporary allocations.
234  */
235 svn_error_t *
236 svn_fs_x__dag_increment_mergeinfo_count(dag_node_t *node,
237                                         apr_int64_t increment,
238                                         apr_pool_t *scratch_pool);
239
240 /* Set the has-mergeinfo flag on NODE to HAS_MERGEINFO.  The node
241    being changed must be mutable.
242
243    Use SCRATCH_POOL for temporary allocations.
244  */
245 svn_error_t *
246 svn_fs_x__dag_set_has_mergeinfo(dag_node_t *node,
247                                 svn_boolean_t has_mergeinfo,
248                                 apr_pool_t *scratch_pool);
249
250
251 \f
252 /* Revision and transaction roots.  */
253
254
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.*/
258 svn_error_t *
259 svn_fs_x__dag_revision_root(dag_node_t **node_p,
260                             svn_fs_t *fs,
261                             svn_revnum_t rev,
262                             apr_pool_t *result_pool,
263                             apr_pool_t *scratch_pool);
264
265
266 /* Set *NODE_P to the root of transaction TXN_ID in FS, allocating
267    from RESULT_POOL.  Use SCRATCH_POOL for temporary allocations. */
268 svn_error_t *
269 svn_fs_x__dag_txn_root(dag_node_t **node_p,
270                        svn_fs_t *fs,
271                        svn_fs_x__txn_id_t txn_id,
272                        apr_pool_t *result_pool,
273                        apr_pool_t *scratch_pool);
274
275 \f
276 /* Directories.  */
277
278
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.
283  */
284 svn_error_t *
285 svn_fs_x__dag_open(dag_node_t **child_p,
286                    dag_node_t *parent,
287                    const char *name,
288                    apr_pool_t *result_pool,
289                    apr_pool_t *scratch_pool);
290
291
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. */
295 svn_error_t *
296 svn_fs_x__dag_dir_entries(apr_array_header_t **entries_p,
297                           dag_node_t *node,
298                           apr_pool_t *result_pool,
299                           apr_pool_t *scratch_pool);
300
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
305    occurs.
306
307    Use SCRATCH_POOL for temporary allocations.
308  */
309 svn_error_t *
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);
316
317
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.
325
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.
329
330    PATH is the canonicalized absolute path at which this node is being
331    created.
332
333    TXN_ID is the Subversion transaction under which this occurs.
334
335    Allocate *CHILD_P in RESULT_POOL and use SCRATCH_POOL for temporaries.
336  */
337 svn_error_t *
338 svn_fs_x__dag_clone_child(dag_node_t **child_p,
339                           dag_node_t *parent,
340                           const char *parent_path,
341                           const char *name,
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);
347
348
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
354    which this occurs.
355
356    If return SVN_ERR_FS_NO_SUCH_ENTRY, then there is no entry NAME in
357    PARENT.
358
359    Use SCRATCH_POOL for temporary allocations.
360  */
361 svn_error_t *
362 svn_fs_x__dag_delete(dag_node_t *parent,
363                      const char *name,
364                      svn_fs_x__txn_id_t txn_id,
365                      apr_pool_t *scratch_pool);
366
367
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.
376
377    Use SCRATCH_POOL for temporary allocations.
378  */
379 svn_error_t *
380 svn_fs_x__dag_make_dir(dag_node_t **child_p,
381                        dag_node_t *parent,
382                        const char *parent_path,
383                        const char *name,
384                        svn_fs_x__txn_id_t txn_id,
385                        apr_pool_t *result_pool,
386                        apr_pool_t *scratch_pool);
387
388
389 \f
390 /* Files.  */
391
392
393 /* Set *CONTENTS to a readable generic stream which yields the
394    contents of FILE.  Allocate the stream in RESULT_POOL.
395
396    If FILE is not a file, return SVN_ERR_FS_NOT_FILE.
397  */
398 svn_error_t *
399 svn_fs_x__dag_get_contents(svn_stream_t **contents,
400                            dag_node_t *file,
401                            apr_pool_t *result_pool);
402
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.
406
407    Use SCRATCH_POOL for temporary allocations.
408  */
409 svn_error_t *
410 svn_fs_x__dag_try_process_file_contents(svn_boolean_t *success,
411                                         dag_node_t *node,
412                                         svn_fs_process_contents_func_t processor,
413                                         void* baton,
414                                         apr_pool_t *scratch_pool);
415
416
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.
420
421    Use SCRATCH_POOL for temporary allocations.
422  */
423 svn_error_t *
424 svn_fs_x__dag_get_file_delta_stream(svn_txdelta_stream_t **stream_p,
425                                     dag_node_t *source,
426                                     dag_node_t *target,
427                                     apr_pool_t *result_pool,
428                                     apr_pool_t *scratch_pool);
429
430 /* Return a generic writable stream in *CONTENTS with which to set the
431    contents of FILE.  Allocate the stream in RESULT_POOL.
432
433    Any previous edits on the file will be deleted, and a new edit
434    stream will be constructed.
435  */
436 svn_error_t *
437 svn_fs_x__dag_get_edit_stream(svn_stream_t **contents,
438                               dag_node_t *file,
439                               apr_pool_t *result_pool);
440
441
442 /* Signify the completion of edits to FILE made using the stream
443    returned by svn_fs_x__dag_get_edit_stream.
444
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.
448
449    This operation is a no-op if no edits are present.
450
451    Use SCRATCH_POOL for temporary allocations.
452  */
453 svn_error_t *
454 svn_fs_x__dag_finalize_edits(dag_node_t *file,
455                              const svn_checksum_t *checksum,
456                              apr_pool_t *scratch_pool);
457
458
459 /* Set *LENGTH to the length of the contents of FILE.
460  */
461 svn_error_t *
462 svn_fs_x__dag_file_length(svn_filesize_t *length,
463                           dag_node_t *file);
464
465 /* Put the recorded checksum of type KIND for FILE into CHECKSUM, allocating
466    from RESULT_POOL.
467
468    If no stored checksum is available, do not calculate the checksum,
469    just put NULL into CHECKSUM.
470  */
471 svn_error_t *
472 svn_fs_x__dag_file_checksum(svn_checksum_t **checksum,
473                             dag_node_t *file,
474                             svn_checksum_kind_t kind,
475                             apr_pool_t *result_pool);
476
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.
484
485    Use SCRATCH_POOL for temporary allocations.
486  */
487 svn_error_t *
488 svn_fs_x__dag_make_file(dag_node_t **child_p,
489                         dag_node_t *parent,
490                         const char *parent_path,
491                         const char *name,
492                         svn_fs_x__txn_id_t txn_id,
493                         apr_pool_t *result_pool,
494                         apr_pool_t *scratch_pool);
495
496
497 \f
498 /* Copies */
499
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.
502
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
507    here.
508
509    If PRESERVE_HISTORY is false, FROM_PATH and FROM_REV are ignored.
510
511    Use SCRATCH_POOL for temporary allocations.
512  */
513 svn_error_t *
514 svn_fs_x__dag_copy(dag_node_t *to_node,
515                    const char *entry,
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);
522
523 \f
524 /* Comparison */
525
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.
529
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.
532
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.
536
537    Use SCRATCH_POOL for temporary allocations.
538  */
539 svn_error_t *
540 svn_fs_x__dag_things_different(svn_boolean_t *props_changed,
541                                svn_boolean_t *contents_changed,
542                                dag_node_t *node1,
543                                dag_node_t *node2,
544                                svn_boolean_t strict,
545                                apr_pool_t *scratch_pool);
546
547
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.
550  */
551 svn_error_t *
552 svn_fs_x__dag_get_copyroot(svn_revnum_t *rev,
553                            const char **path,
554                            dag_node_t *node);
555
556 /* Set *REV to the copyfrom revision associated with NODE.
557  */
558 svn_error_t *
559 svn_fs_x__dag_get_copyfrom_rev(svn_revnum_t *rev,
560                                dag_node_t *node);
561
562 /* Set *PATH to the copyfrom path associated with NODE.
563  */
564 svn_error_t *
565 svn_fs_x__dag_get_copyfrom_path(const char **path,
566                                 dag_node_t *node);
567
568 /* Update *TARGET so that SOURCE is it's predecessor.
569
570    Use SCRATCH_POOL for temporary allocations.
571  */
572 svn_error_t *
573 svn_fs_x__dag_update_ancestry(dag_node_t *target,
574                               dag_node_t *source,
575                               apr_pool_t *scratch_pool);
576 #ifdef __cplusplus
577 }
578 #endif /* __cplusplus */
579
580 #endif /* SVN_LIBSVN_FS_DAG_H */