📄 dag.c
字号:
set_entry(dag_node_t *parent, const char *name, const svn_fs_id_t *id, const char *txn_id, trail_t *trail, apr_pool_t *pool){ node_revision_t *parent_noderev; const char *rep_key, *mutable_rep_key; apr_hash_t *entries = NULL; svn_stream_t *wstream; apr_size_t len; svn_string_t raw_entries; svn_stringbuf_t *raw_entries_buf; skel_t *entries_skel; svn_fs_t *fs = svn_fs_base__dag_get_fs(parent); /* Get the parent's node-revision. */ SVN_ERR(svn_fs_bdb__get_node_revision(&parent_noderev, fs, parent->id, trail, pool)); rep_key = parent_noderev->data_key; SVN_ERR(svn_fs_base__get_mutable_rep(&mutable_rep_key, rep_key, fs, txn_id, trail, pool)); /* If the parent node already pointed at a mutable representation, we don't need to do anything. But if it didn't, either because the parent didn't refer to any rep yet or because it referred to an immutable one, we must make the parent refer to the mutable rep we just created. */ if (! svn_fs_base__same_keys(rep_key, mutable_rep_key)) { node_revision_t *new_noderev = copy_node_revision(parent_noderev, pool); new_noderev->data_key = mutable_rep_key; SVN_ERR(svn_fs_bdb__put_node_revision(fs, parent->id, new_noderev, trail, pool)); } /* If the new representation inherited nothing, start a new entries list for it. Else, go read its existing entries list. */ if (rep_key) { SVN_ERR(svn_fs_base__rep_contents(&raw_entries, fs, rep_key, trail, pool)); entries_skel = svn_fs_base__parse_skel(raw_entries.data, raw_entries.len, pool); if (entries_skel) SVN_ERR(svn_fs_base__parse_entries_skel(&entries, entries_skel, pool)); } /* If we still have no ENTRIES hash, make one here. */ if (! entries) entries = apr_hash_make(pool); /* Now, add our new entry to the entries list. */ apr_hash_set(entries, name, APR_HASH_KEY_STRING, id); /* Finally, replace the old entries list with the new one. */ SVN_ERR(svn_fs_base__unparse_entries_skel(&entries_skel, entries, pool)); raw_entries_buf = svn_fs_base__unparse_skel(entries_skel, pool); SVN_ERR(svn_fs_base__rep_contents_write_stream(&wstream, fs, mutable_rep_key, txn_id, TRUE, trail, pool)); len = raw_entries_buf->len; SVN_ERR(svn_stream_write(wstream, raw_entries_buf->data, &len)); SVN_ERR(svn_stream_close(wstream)); return SVN_NO_ERROR;}/* Make a new entry named NAME in PARENT, as part of TRAIL. If IS_DIR is true, then the node revision the new entry points to will be a directory, else it will be a file. The new node will be allocated in POOL. PARENT must be mutable, and must not have an entry named NAME. */static svn_error_t *make_entry(dag_node_t **child_p, dag_node_t *parent, const char *parent_path, const char *name, svn_boolean_t is_dir, const char *txn_id, trail_t *trail, apr_pool_t *pool){ const svn_fs_id_t *new_node_id; node_revision_t new_noderev; /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) return svn_error_createf (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, _("Attempted to create a node with an illegal name '%s'"), name); /* Make sure that parent is a directory */ if (parent->kind != svn_node_dir) return svn_error_create (SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Attempted to create entry in non-directory parent")); /* Check that the parent is mutable. */ if (! svn_fs_base__dag_check_mutable(parent, txn_id)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to clone child of non-mutable node")); /* Check that parent does not already have an entry named NAME. */ SVN_ERR(dir_entry_id_from_node(&new_node_id, parent, name, trail, pool)); if (new_node_id) return svn_error_createf (SVN_ERR_FS_ALREADY_EXISTS, NULL, _("Attempted to create entry that already exists")); /* Create the new node's NODE-REVISION */ memset(&new_noderev, 0, sizeof(new_noderev)); new_noderev.kind = is_dir ? svn_node_dir : svn_node_file; new_noderev.created_path = svn_path_join(parent_path, name, pool); SVN_ERR(svn_fs_base__create_node (&new_node_id, svn_fs_base__dag_get_fs(parent), &new_noderev, svn_fs_base__id_copy_id(svn_fs_base__dag_get_id(parent)), txn_id, trail, pool)); /* Create a new dag_node_t for our new node */ SVN_ERR(svn_fs_base__dag_get_node(child_p, svn_fs_base__dag_get_fs(parent), new_node_id, trail, pool)); /* We can safely call set_entry because we already know that PARENT is mutable, and we just created CHILD, so we know it has no ancestors (therefore, PARENT cannot be an ancestor of CHILD) */ SVN_ERR(set_entry(parent, name, svn_fs_base__dag_get_id(*child_p), txn_id, trail, pool)); return SVN_NO_ERROR;}svn_error_t *svn_fs_base__dag_dir_entries(apr_hash_t **entries, dag_node_t *node, trail_t *trail, apr_pool_t *pool){ node_revision_t *noderev; SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, node->fs, node->id, trail, pool)); return get_dir_entries(entries, node->fs, noderev, trail, pool);}svn_error_t *svn_fs_base__dag_set_entry(dag_node_t *node, const char *entry_name, const svn_fs_id_t *id, const char *txn_id, trail_t *trail, apr_pool_t *pool){ /* Check it's a directory. */ if (node->kind != svn_node_dir) return svn_error_create (SVN_ERR_FS_NOT_DIRECTORY, NULL, _("Attempted to set entry in non-directory node")); /* Check it's mutable. */ if (! svn_fs_base__dag_check_mutable(node, txn_id)) return svn_error_create (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to set entry in immutable node")); return set_entry(node, entry_name, id, txn_id, trail, pool);}/*** Proplists. ***/svn_error_t *svn_fs_base__dag_get_proplist(apr_hash_t **proplist_p, dag_node_t *node, trail_t *trail, apr_pool_t *pool){ node_revision_t *noderev; apr_hash_t *proplist = NULL; svn_string_t raw_proplist; skel_t *proplist_skel; /* Go get a fresh NODE-REVISION for this node. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, node->fs, node->id, trail, pool)); /* Get property key (returning early if there isn't one) . */ if (! noderev->prop_key) { *proplist_p = NULL; return SVN_NO_ERROR; } /* Get the string associated with the property rep, parsing it as a skel, and then attempt to parse *that* into a property hash. */ SVN_ERR(svn_fs_base__rep_contents(&raw_proplist, svn_fs_base__dag_get_fs(node), noderev->prop_key, trail, pool)); proplist_skel = svn_fs_base__parse_skel(raw_proplist.data, raw_proplist.len, pool); if (proplist_skel) SVN_ERR(svn_fs_base__parse_proplist_skel(&proplist, proplist_skel, pool)); *proplist_p = proplist; return SVN_NO_ERROR;}svn_error_t *svn_fs_base__dag_set_proplist(dag_node_t *node, apr_hash_t *proplist, const char *txn_id, trail_t *trail, apr_pool_t *pool){ node_revision_t *noderev; const char *rep_key, *mutable_rep_key; svn_fs_t *fs = svn_fs_base__dag_get_fs(node); /* Sanity check: this node better be mutable! */ if (! svn_fs_base__dag_check_mutable(node, txn_id)) { svn_string_t *idstr = svn_fs_base__id_unparse(node->id, pool); return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Can't set proplist on *immutable* node-revision %s"), idstr->data); } /* Go get a fresh NODE-REVISION for this node. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, fs, node->id, trail, pool)); rep_key = noderev->prop_key; /* Get a mutable version of this rep (updating the node revision if this isn't a NOOP) */ SVN_ERR(svn_fs_base__get_mutable_rep(&mutable_rep_key, rep_key, fs, txn_id, trail, pool)); if (! svn_fs_base__same_keys(mutable_rep_key, rep_key)) { noderev->prop_key = mutable_rep_key; SVN_ERR(svn_fs_bdb__put_node_revision(fs, node->id, noderev, trail, pool)); } /* Replace the old property list with the new one. */ { svn_stream_t *wstream; apr_size_t len; skel_t *proplist_skel; svn_stringbuf_t *raw_proplist_buf; SVN_ERR(svn_fs_base__unparse_proplist_skel(&proplist_skel, proplist, pool)); raw_proplist_buf = svn_fs_base__unparse_skel(proplist_skel, pool); SVN_ERR(svn_fs_base__rep_contents_write_stream(&wstream, fs, mutable_rep_key, txn_id, TRUE, trail, pool)); len = raw_proplist_buf->len; SVN_ERR(svn_stream_write(wstream, raw_proplist_buf->data, &len)); SVN_ERR(svn_stream_close(wstream)); } return SVN_NO_ERROR;}/*** Roots. ***/svn_error_t *svn_fs_base__dag_revision_root(dag_node_t **node_p, svn_fs_t *fs, svn_revnum_t rev, trail_t *trail, apr_pool_t *pool){ const svn_fs_id_t *root_id; SVN_ERR(svn_fs_base__rev_get_root(&root_id, fs, rev, trail, pool)); return svn_fs_base__dag_get_node(node_p, fs, root_id, trail, pool);}svn_error_t *svn_fs_base__dag_txn_root(dag_node_t **node_p, svn_fs_t *fs, const char *txn_id, trail_t *trail, apr_pool_t *pool){ const svn_fs_id_t *root_id, *ignored; SVN_ERR(svn_fs_base__get_txn_ids(&root_id, &ignored, fs, txn_id, trail, pool)); return svn_fs_base__dag_get_node(node_p, fs, root_id, trail, pool);}svn_error_t *svn_fs_base__dag_txn_base_root(dag_node_t **node_p, svn_fs_t *fs, const char *txn_id, trail_t *trail, apr_pool_t *pool){ const svn_fs_id_t *base_root_id, *ignored; SVN_ERR(svn_fs_base__get_txn_ids(&ignored, &base_root_id, fs, txn_id, trail, pool)); return svn_fs_base__dag_get_node(node_p, fs, base_root_id, trail, pool);}svn_error_t *svn_fs_base__dag_clone_child(dag_node_t **child_p, dag_node_t *parent, const char *parent_path, const char *name, const char *copy_id, const char *txn_id, trail_t *trail, apr_pool_t *pool){ dag_node_t *cur_entry; /* parent's current entry named NAME */ const svn_fs_id_t *new_node_id; /* node id we'll put into NEW_NODE */ svn_fs_t *fs = svn_fs_base__dag_get_fs(parent); /* First check that the parent is mutable. */ if (! svn_fs_base__dag_check_mutable(parent, txn_id)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to clone child of non-mutable node")); /* Make sure that NAME is a single path component. */ if (! svn_path_is_single_path_component(name)) return svn_error_createf (SVN_ERR_FS_NOT_SINGLE_PATH_COMPONENT, NULL, _("Attempted to make a child clone with an illegal name '%s'"), name); /* Find the node named NAME in PARENT's entries list if it exists. */ SVN_ERR(svn_fs_base__dag_open(&cur_entry, parent, name, trail, pool)); /* Check for mutability in the node we found. If it's mutable, we don't need to clone it. */ if (svn_fs_base__dag_check_mutable(cur_entry, txn_id)) { /* This has already been cloned */ new_node_id = cur_entry->id; } else { node_revision_t *noderev; /* Go get a fresh NODE-REVISION for current child node. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, fs, cur_entry->id, trail, pool)); /* Do the clone thingy here. */ noderev->predecessor_id = cur_entry->id; if (noderev->predecessor_count != -1) noderev->predecessor_count++; noderev->created_path = svn_path_join(parent_path, name, pool); SVN_ERR(svn_fs_base__create_successor(&new_node_id, fs, cur_entry->id, noderev, copy_id, txn_id, trail, pool)); /* Replace the ID in the parent's ENTRY list with the ID which refers to the mutable clone of this child. */ SVN_ERR(set_entry(parent, name, new_node_id, txn_id, trail, pool)); } /* Initialize the youngster. */ return svn_fs_base__dag_get_node(child_p, fs, new_node_id, trail, pool);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -