003 File Manager
Current Path:
/usr/src/contrib/subversion/subversion/libsvn_fs_x
usr
/
src
/
contrib
/
subversion
/
subversion
/
libsvn_fs_x
/
📁
..
📄
TODO
(9.58 KB)
📄
batch_fsync.c
(17.36 KB)
📄
batch_fsync.h
(3.74 KB)
📄
cached_data.c
(124.18 KB)
📄
cached_data.h
(8.98 KB)
📄
caching.c
(25.26 KB)
📄
changes.c
(18.9 KB)
📄
changes.h
(5.56 KB)
📄
dag.c
(33.9 KB)
📄
dag.h
(18.94 KB)
📄
dag_cache.c
(37.62 KB)
📄
dag_cache.h
(6.8 KB)
📄
fs.c
(20.49 KB)
📄
fs.h
(20.55 KB)
📄
fs_id.c
(9.6 KB)
📄
fs_id.h
(2.37 KB)
📄
fs_init.h
(1.24 KB)
📄
fs_x.c
(51.32 KB)
📄
fs_x.h
(8.89 KB)
📄
hotcopy.c
(32.16 KB)
📄
hotcopy.h
(2.05 KB)
📄
id.c
(4.92 KB)
📄
id.h
(4.41 KB)
📄
index.c
(136.28 KB)
📄
index.h
(17.5 KB)
📄
libsvn_fs_x.pc.in
(387 B)
📄
lock.c
(45.17 KB)
📄
lock.h
(3.94 KB)
📄
low_level.c
(40.89 KB)
📄
low_level.h
(9.21 KB)
📄
noderevs.c
(31.18 KB)
📄
noderevs.h
(5.39 KB)
📄
pack.c
(82.45 KB)
📄
pack.h
(2.33 KB)
📄
recovery.c
(12.25 KB)
📄
recovery.h
(1.46 KB)
📄
rep-cache-db.h
(2.25 KB)
📄
rep-cache-db.sql
(2.23 KB)
📄
rep-cache.c
(14 KB)
📄
rep-cache.h
(4.26 KB)
📄
reps.c
(29.63 KB)
📄
reps.h
(7.3 KB)
📄
rev_file.c
(17.15 KB)
📄
rev_file.h
(7.15 KB)
📄
revprops.c
(59.51 KB)
📄
revprops.h
(4.99 KB)
📄
string_table.c
(29.61 KB)
📄
string_table.h
(5.06 KB)
📄
structure
(14.88 KB)
📄
temp_serializer.c
(37.31 KB)
📄
temp_serializer.h
(10.7 KB)
📄
transaction.c
(147.9 KB)
📄
transaction.h
(13.26 KB)
📄
tree.c
(120.57 KB)
📄
tree.h
(3.98 KB)
📄
util.c
(22.6 KB)
📄
util.h
(16.85 KB)
📄
verify.c
(30.47 KB)
📄
verify.h
(1.78 KB)
Editing: changes.c
/* changes.h --- FSX changed paths lists container * * ==================================================================== * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * ==================================================================== */ #include "svn_private_config.h" #include "svn_sorts.h" #include "private/svn_packed_data.h" #include "changes.h" #include "string_table.h" #include "temp_serializer.h" /* These flags will be used with the FLAGS field in binary_change_t. */ /* the change contains a text modification */ #define CHANGE_TEXT_MOD 0x00001 /* the change contains a property modification */ #define CHANGE_PROP_MOD 0x00002 /* the change contains a mergeinfo modification */ #define CHANGE_MERGEINFO_MOD 0x00004 /* (flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT extracts the node type */ #define CHANGE_NODE_SHIFT 0x00003 #define CHANGE_NODE_MASK 0x00018 /* node types according to svn_node_kind_t */ #define CHANGE_NODE_NONE 0x00000 #define CHANGE_NODE_FILE 0x00008 #define CHANGE_NODE_DIR 0x00010 #define CHANGE_NODE_UNKNOWN 0x00018 /* (flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT extracts the change type */ #define CHANGE_KIND_SHIFT 0x00005 #define CHANGE_KIND_MASK 0x00060 /* node types according to svn_fs_path_change_kind_t */ #define CHANGE_KIND_MODIFY 0x00000 #define CHANGE_KIND_ADD 0x00020 #define CHANGE_KIND_DELETE 0x00040 #define CHANGE_KIND_REPLACE 0x00060 /* Our internal representation of a change */ typedef struct binary_change_t { /* define the kind of change and what specific information is present */ int flags; /* Path of the change. */ apr_size_t path; /* copy-from information. * Not present if COPYFROM_REV is SVN_INVALID_REVNUM. */ svn_revnum_t copyfrom_rev; apr_size_t copyfrom_path; } binary_change_t; /* The actual container object. Change lists are concatenated into CHANGES * and and their begins and ends are stored in OFFSETS. */ struct svn_fs_x__changes_t { /* The paths - either in 'builder' mode or finalized mode. * The respective other pointer will be NULL. */ string_table_builder_t *builder; string_table_t *paths; /* All changes of all change lists concatenated. * Array elements are binary_change_t.structs (not pointer!) */ apr_array_header_t *changes; /* [Offsets[index] .. Offsets[index+1]) is the range in CHANGES that * forms the contents of change list INDEX. */ apr_array_header_t *offsets; }; /* Create and return a new container object, allocated in RESULT_POOL with * an initial capacity of INITIAL_COUNT changes. The PATH and BUILDER * members must be initialized by the caller afterwards. */ static svn_fs_x__changes_t * changes_create_body(apr_size_t initial_count, apr_pool_t *result_pool) { svn_fs_x__changes_t *changes = apr_pcalloc(result_pool, sizeof(*changes)); changes->changes = apr_array_make(result_pool, (int)initial_count, sizeof(binary_change_t)); changes->offsets = apr_array_make(result_pool, 16, sizeof(int)); APR_ARRAY_PUSH(changes->offsets, int) = 0; return changes; } svn_fs_x__changes_t * svn_fs_x__changes_create(apr_size_t initial_count, apr_pool_t *result_pool) { svn_fs_x__changes_t *changes = changes_create_body(initial_count, result_pool); changes->builder = svn_fs_x__string_table_builder_create(result_pool); return changes; } /* Add CHANGE to the latest change list in CHANGES. */ static svn_error_t * append_change(svn_fs_x__changes_t *changes, svn_fs_x__change_t *change) { binary_change_t binary_change = { 0 }; /* CHANGE must be sufficiently complete */ SVN_ERR_ASSERT(change); SVN_ERR_ASSERT(change->path.data); /* define the kind of change and what specific information is present */ binary_change.flags = (change->text_mod ? CHANGE_TEXT_MOD : 0) | (change->prop_mod ? CHANGE_PROP_MOD : 0) | (change->mergeinfo_mod == svn_tristate_true ? CHANGE_MERGEINFO_MOD : 0) | ((int)change->change_kind << CHANGE_KIND_SHIFT) | ((int)change->node_kind << CHANGE_NODE_SHIFT); /* Path of the change. */ binary_change.path = svn_fs_x__string_table_builder_add(changes->builder, change->path.data, change->path.len); /* copy-from information, if presence is indicated by FLAGS */ if (SVN_IS_VALID_REVNUM(change->copyfrom_rev)) { binary_change.copyfrom_rev = change->copyfrom_rev; binary_change.copyfrom_path = svn_fs_x__string_table_builder_add(changes->builder, change->copyfrom_path, 0); } else { binary_change.copyfrom_rev = SVN_INVALID_REVNUM; binary_change.copyfrom_path = 0; } APR_ARRAY_PUSH(changes->changes, binary_change_t) = binary_change; return SVN_NO_ERROR; } svn_error_t * svn_fs_x__changes_append_list(apr_size_t *list_index, svn_fs_x__changes_t *changes, apr_array_header_t *list) { int i; /* CHANGES must be in 'builder' mode */ SVN_ERR_ASSERT(changes->builder); SVN_ERR_ASSERT(changes->paths == NULL); /* simply append the list and all changes */ for (i = 0; i < list->nelts; ++i) SVN_ERR(append_change(changes, APR_ARRAY_IDX(list, i, svn_fs_x__change_t *))); /* terminate the list by storing the next changes offset */ APR_ARRAY_PUSH(changes->offsets, int) = changes->changes->nelts; *list_index = (apr_size_t)(changes->offsets->nelts - 2); return SVN_NO_ERROR; } apr_size_t svn_fs_x__changes_estimate_size(const svn_fs_x__changes_t *changes) { /* CHANGES must be in 'builder' mode */ if (changes->builder == NULL) return 0; /* string table code makes its own prediction, * changes should be < 10 bytes each, * some static overhead should be assumed */ return svn_fs_x__string_table_builder_estimate_size(changes->builder) + changes->changes->nelts * 10 + 100; } svn_error_t * svn_fs_x__changes_get_list(apr_array_header_t **list, const svn_fs_x__changes_t *changes, apr_size_t idx, svn_fs_x__changes_context_t *context, apr_pool_t *result_pool) { int list_first; int list_last; int first; int last; int i; /* CHANGES must be in 'finalized' mode */ SVN_ERR_ASSERT(changes->builder == NULL); SVN_ERR_ASSERT(changes->paths); /* validate index */ if (idx + 1 >= (apr_size_t)changes->offsets->nelts) return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL, apr_psprintf(result_pool, _("Changes list index %%%s" " exceeds container size %%d"), APR_SIZE_T_FMT), idx, changes->offsets->nelts - 1); /* range of changes to return */ list_first = APR_ARRAY_IDX(changes->offsets, (int)idx, int); list_last = APR_ARRAY_IDX(changes->offsets, (int)idx + 1, int); /* Restrict it to the sub-range requested by the caller. * Clip the range to never exceed the list's content. */ first = MIN(context->next + list_first, list_last); last = MIN(first + SVN_FS_X__CHANGES_BLOCK_SIZE, list_last); /* Indicate to the caller whether the end of the list has been reached. */ context->eol = last == list_last; /* construct result */ *list = apr_array_make(result_pool, last - first, sizeof(svn_fs_x__change_t*)); for (i = first; i < last; ++i) { const binary_change_t *binary_change = &APR_ARRAY_IDX(changes->changes, i, binary_change_t); /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */ svn_fs_x__change_t *change = apr_pcalloc(result_pool, sizeof(*change)); change->path.data = svn_fs_x__string_table_get(changes->paths, binary_change->path, &change->path.len, result_pool); change->change_kind = (svn_fs_path_change_kind_t) ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT); change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0; change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0; change->mergeinfo_mod = (binary_change->flags & CHANGE_MERGEINFO_MOD) ? svn_tristate_true : svn_tristate_false; change->node_kind = (svn_node_kind_t) ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT); change->copyfrom_rev = binary_change->copyfrom_rev; change->copyfrom_known = TRUE; if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev)) change->copyfrom_path = svn_fs_x__string_table_get(changes->paths, binary_change->copyfrom_path, NULL, result_pool); /* add it to the result */ APR_ARRAY_PUSH(*list, svn_fs_x__change_t*) = change; } return SVN_NO_ERROR; } svn_error_t * svn_fs_x__write_changes_container(svn_stream_t *stream, const svn_fs_x__changes_t *changes, apr_pool_t *scratch_pool) { int i; string_table_t *paths = changes->paths ? changes->paths : svn_fs_x__string_table_create(changes->builder, scratch_pool); svn_packed__data_root_t *root = svn_packed__data_create_root(scratch_pool); /* one top-level stream for each array */ svn_packed__int_stream_t *offsets_stream = svn_packed__create_int_stream(root, TRUE, FALSE); svn_packed__int_stream_t *changes_stream = svn_packed__create_int_stream(root, FALSE, FALSE); /* structure the CHANGES_STREAM such we can extract much of the redundancy * from the binary_change_t structs */ svn_packed__create_int_substream(changes_stream, TRUE, FALSE); svn_packed__create_int_substream(changes_stream, TRUE, FALSE); svn_packed__create_int_substream(changes_stream, TRUE, TRUE); svn_packed__create_int_substream(changes_stream, TRUE, FALSE); /* serialize offsets array */ for (i = 0; i < changes->offsets->nelts; ++i) svn_packed__add_uint(offsets_stream, APR_ARRAY_IDX(changes->offsets, i, int)); /* serialize changes array */ for (i = 0; i < changes->changes->nelts; ++i) { const binary_change_t *change = &APR_ARRAY_IDX(changes->changes, i, binary_change_t); svn_packed__add_uint(changes_stream, change->flags); svn_packed__add_uint(changes_stream, change->path); svn_packed__add_int(changes_stream, change->copyfrom_rev); svn_packed__add_uint(changes_stream, change->copyfrom_path); } /* write to disk */ SVN_ERR(svn_fs_x__write_string_table(stream, paths, scratch_pool)); SVN_ERR(svn_packed__data_write(stream, root, scratch_pool)); return SVN_NO_ERROR; } svn_error_t * svn_fs_x__read_changes_container(svn_fs_x__changes_t **changes_p, svn_stream_t *stream, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { apr_size_t i; apr_size_t count; svn_fs_x__changes_t *changes = apr_pcalloc(result_pool, sizeof(*changes)); svn_packed__data_root_t *root; svn_packed__int_stream_t *offsets_stream; svn_packed__int_stream_t *changes_stream; /* read from disk */ SVN_ERR(svn_fs_x__read_string_table(&changes->paths, stream, result_pool, scratch_pool)); SVN_ERR(svn_packed__data_read(&root, stream, result_pool, scratch_pool)); offsets_stream = svn_packed__first_int_stream(root); changes_stream = svn_packed__next_int_stream(offsets_stream); /* read offsets array */ count = svn_packed__int_count(offsets_stream); changes->offsets = apr_array_make(result_pool, (int)count, sizeof(int)); for (i = 0; i < count; ++i) APR_ARRAY_PUSH(changes->offsets, int) = (int)svn_packed__get_uint(offsets_stream); /* read changes array */ count = svn_packed__int_count(svn_packed__first_int_substream(changes_stream)); changes->changes = apr_array_make(result_pool, (int)count, sizeof(binary_change_t)); for (i = 0; i < count; ++i) { binary_change_t change; change.flags = (int)svn_packed__get_uint(changes_stream); change.path = (apr_size_t)svn_packed__get_uint(changes_stream); change.copyfrom_rev = (svn_revnum_t)svn_packed__get_int(changes_stream); change.copyfrom_path = (apr_size_t)svn_packed__get_uint(changes_stream); APR_ARRAY_PUSH(changes->changes, binary_change_t) = change; } *changes_p = changes; return SVN_NO_ERROR; } svn_error_t * svn_fs_x__serialize_changes_container(void **data, apr_size_t *data_len, void *in, apr_pool_t *pool) { svn_fs_x__changes_t *changes = in; svn_stringbuf_t *serialized; /* make a guesstimate on the size of the serialized data. Erring on the * low side will cause the serializer to re-alloc its buffer. */ apr_size_t size = changes->changes->elt_size * changes->changes->nelts + changes->offsets->elt_size * changes->offsets->nelts + 10 * changes->changes->elt_size + 100; /* serialize array header and all its elements */ svn_temp_serializer__context_t *context = svn_temp_serializer__init(changes, sizeof(*changes), size, pool); /* serialize sub-structures */ svn_fs_x__serialize_string_table(context, &changes->paths); svn_fs_x__serialize_apr_array(context, &changes->changes); svn_fs_x__serialize_apr_array(context, &changes->offsets); /* return the serialized result */ serialized = svn_temp_serializer__get(context); *data = serialized->data; *data_len = serialized->len; return SVN_NO_ERROR; } svn_error_t * svn_fs_x__deserialize_changes_container(void **out, void *data, apr_size_t data_len, apr_pool_t *result_pool) { svn_fs_x__changes_t *changes = (svn_fs_x__changes_t *)data; /* de-serialize sub-structures */ svn_fs_x__deserialize_string_table(changes, &changes->paths); svn_fs_x__deserialize_apr_array(changes, &changes->changes, result_pool); svn_fs_x__deserialize_apr_array(changes, &changes->offsets, result_pool); /* done */ *out = changes; return SVN_NO_ERROR; } svn_error_t * svn_fs_x__changes_get_list_func(void **out, const void *data, apr_size_t data_len, void *baton, apr_pool_t *pool) { int first; int last; int i; apr_array_header_t *list; svn_fs_x__changes_get_list_baton_t *b = baton; apr_uint32_t idx = b->sub_item; const svn_fs_x__changes_t *container = data; /* resolve all the sub-container pointers we need */ const string_table_t *paths = svn_temp_deserializer__ptr(container, (const void *const *)&container->paths); const apr_array_header_t *serialized_offsets = svn_temp_deserializer__ptr(container, (const void *const *)&container->offsets); const apr_array_header_t *serialized_changes = svn_temp_deserializer__ptr(container, (const void *const *)&container->changes); const int *offsets = svn_temp_deserializer__ptr(serialized_offsets, (const void *const *)&serialized_offsets->elts); const binary_change_t *changes = svn_temp_deserializer__ptr(serialized_changes, (const void *const *)&serialized_changes->elts); /* validate index */ if (idx + 1 >= (apr_size_t)serialized_offsets->nelts) return svn_error_createf(SVN_ERR_FS_CONTAINER_INDEX, NULL, _("Changes list index %u exceeds container " "size %d"), (unsigned)idx, serialized_offsets->nelts - 1); /* range of changes to return */ first = offsets[idx]; last = offsets[idx+1]; /* Restrict range to the block requested by the BATON. * Tell the caller whether we reached the end of the list. */ first = MIN(first + b->start, last); last = MIN(first + SVN_FS_X__CHANGES_BLOCK_SIZE, last); *b->eol = last == offsets[idx+1]; /* construct result */ list = apr_array_make(pool, last - first, sizeof(svn_fs_x__change_t*)); for (i = first; i < last; ++i) { const binary_change_t *binary_change = &changes[i]; /* convert BINARY_CHANGE into a standard FSX svn_fs_x__change_t */ svn_fs_x__change_t *change = apr_pcalloc(pool, sizeof(*change)); change->path.data = svn_fs_x__string_table_get_func(paths, binary_change->path, &change->path.len, pool); change->change_kind = (svn_fs_path_change_kind_t) ((binary_change->flags & CHANGE_KIND_MASK) >> CHANGE_KIND_SHIFT); change->text_mod = (binary_change->flags & CHANGE_TEXT_MOD) != 0; change->prop_mod = (binary_change->flags & CHANGE_PROP_MOD) != 0; change->node_kind = (svn_node_kind_t) ((binary_change->flags & CHANGE_NODE_MASK) >> CHANGE_NODE_SHIFT); change->copyfrom_rev = binary_change->copyfrom_rev; change->copyfrom_known = TRUE; if (SVN_IS_VALID_REVNUM(binary_change->copyfrom_rev)) change->copyfrom_path = svn_fs_x__string_table_get_func(paths, binary_change->copyfrom_path, NULL, pool); /* add it to the result */ APR_ARRAY_PUSH(list, svn_fs_x__change_t*) = change; } *out = list; return SVN_NO_ERROR; }
Upload File
Create Folder