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 */