📄 dag.c
字号:
SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, file->fs, file->id, trail, pool)); if (noderev->data_key) SVN_ERR(svn_fs_base__rep_contents_checksum(digest, file->fs, noderev->data_key, trail, pool)); else memset(digest, 0, APR_MD5_DIGESTSIZE); return SVN_NO_ERROR;}svn_error_t *svn_fs_base__dag_get_edit_stream(svn_stream_t **contents, dag_node_t *file, const char *txn_id, trail_t *trail, apr_pool_t *pool){ svn_fs_t *fs = file->fs; /* just for nicer indentation */ node_revision_t *noderev; const char *mutable_rep_key; svn_stream_t *ws; /* Make sure our node is a file. */ if (file->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, _("Attempted to set textual contents of a *non*-file node")); /* Make sure our node is mutable. */ if (! svn_fs_base__dag_check_mutable(file, txn_id)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to set textual contents of an immutable node")); /* Get the node revision. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, fs, file->id, trail, pool)); /* If this node already has an EDIT-DATA-KEY, destroy the data associated with that key. */ if (noderev->edit_key) SVN_ERR(svn_fs_base__delete_rep_if_mutable(fs, noderev->edit_key, txn_id, trail, pool)); /* Now, let's ensure that we have a new EDIT-DATA-KEY available for use. */ SVN_ERR(svn_fs_base__get_mutable_rep(&mutable_rep_key, NULL, fs, txn_id, trail, pool)); /* We made a new rep, so update the node revision. */ noderev->edit_key = mutable_rep_key; SVN_ERR(svn_fs_bdb__put_node_revision(fs, file->id, noderev, trail, pool)); /* Return a writable stream with which to set new contents. */ SVN_ERR(svn_fs_base__rep_contents_write_stream(&ws, fs, mutable_rep_key, txn_id, FALSE, trail, pool)); *contents = ws; return SVN_NO_ERROR;}svn_error_t *svn_fs_base__dag_finalize_edits(dag_node_t *file, const char *checksum, const char *txn_id, trail_t *trail, apr_pool_t *pool){ svn_fs_t *fs = file->fs; /* just for nicer indentation */ node_revision_t *noderev; const char *old_data_key; /* Make sure our node is a file. */ if (file->kind != svn_node_file) return svn_error_createf (SVN_ERR_FS_NOT_FILE, NULL, _("Attempted to set textual contents of a *non*-file node")); /* Make sure our node is mutable. */ if (! svn_fs_base__dag_check_mutable(file, txn_id)) return svn_error_createf (SVN_ERR_FS_NOT_MUTABLE, NULL, _("Attempted to set textual contents of an immutable node")); /* Get the node revision. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, fs, file->id, trail, pool)); /* If this node has no EDIT-DATA-KEY, this is a no-op. */ if (! noderev->edit_key) return SVN_NO_ERROR; if (checksum) { unsigned char digest[APR_MD5_DIGESTSIZE]; const char *hex; SVN_ERR(svn_fs_base__rep_contents_checksum (digest, fs, noderev->edit_key, trail, pool)); hex = svn_md5_digest_to_cstring_display(digest, pool); if (strcmp(checksum, hex) != 0) return svn_error_createf (SVN_ERR_CHECKSUM_MISMATCH, NULL, _("Checksum mismatch, rep '%s':\n" " expected: %s\n" " actual: %s\n"), noderev->edit_key, checksum, hex); } /* Now, we want to delete the old representation and replace it with the new. Of course, we don't actually delete anything until everything is being properly referred to by the node-revision skel. */ old_data_key = noderev->data_key; noderev->data_key = noderev->edit_key; noderev->edit_key = NULL; SVN_ERR(svn_fs_bdb__put_node_revision(fs, file->id, noderev, trail, pool)); /* Only *now* can we safely destroy the old representation (if it even existed in the first place). */ if (old_data_key) SVN_ERR(svn_fs_base__delete_rep_if_mutable(fs, old_data_key, txn_id, trail, pool)); return SVN_NO_ERROR;}dag_node_t *svn_fs_base__dag_dup(dag_node_t *node, apr_pool_t *pool){ /* Allocate our new node. */ dag_node_t *new_node = apr_pcalloc(pool, sizeof(*new_node)); new_node->fs = node->fs; new_node->id = svn_fs_base__id_copy(node->id, pool); new_node->kind = node->kind; new_node->created_path = apr_pstrdup(pool, node->created_path); return new_node;}svn_error_t *svn_fs_base__dag_open(dag_node_t **child_p, dag_node_t *parent, const char *name, trail_t *trail, apr_pool_t *pool){ const svn_fs_id_t *node_id; /* Ensure that NAME exists in PARENT's entry list. */ SVN_ERR(dir_entry_id_from_node(&node_id, parent, name, trail, pool)); if (! node_id) return svn_error_createf (SVN_ERR_FS_NOT_FOUND, NULL, _("Attempted to open non-existent child node '%s'"), name); /* 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 open node with an illegal name '%s'"), name); /* Now get the node that was requested. */ return svn_fs_base__dag_get_node(child_p, svn_fs_base__dag_get_fs(parent), node_id, trail, pool);}svn_error_t *svn_fs_base__dag_copy(dag_node_t *to_node, const char *entry, dag_node_t *from_node, svn_boolean_t preserve_history, svn_revnum_t from_rev, const char *from_path, const char *txn_id, trail_t *trail, apr_pool_t *pool){ const svn_fs_id_t *id; if (preserve_history) { node_revision_t *noderev; const char *copy_id; svn_fs_t *fs = svn_fs_base__dag_get_fs(from_node); const svn_fs_id_t *src_id = svn_fs_base__dag_get_id(from_node); const char *from_txn_id = NULL; /* Make a copy of the original node revision. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev, fs, from_node->id, trail, pool)); /* Reserve a copy ID for this new copy. */ SVN_ERR(svn_fs_bdb__reserve_copy_id(©_id, fs, trail, pool)); /* Create a successor with its predecessor pointing at the copy source. */ noderev->predecessor_id = svn_fs_base__id_copy(src_id, pool); if (noderev->predecessor_count != -1) noderev->predecessor_count++; noderev->created_path = svn_path_join (svn_fs_base__dag_get_created_path(to_node), entry, pool); SVN_ERR(svn_fs_base__create_successor(&id, fs, src_id, noderev, copy_id, txn_id, trail, pool)); /* Translate FROM_REV into a transaction ID. */ SVN_ERR(svn_fs_base__rev_get_txn_id(&from_txn_id, fs, from_rev, trail, pool)); /* Now that we've done the copy, we need to add the information about the copy to the `copies' table, using the COPY_ID we reserved above. */ SVN_ERR(svn_fs_bdb__create_copy (fs, copy_id, svn_fs_base__canonicalize_abspath(from_path, pool), from_txn_id, id, copy_kind_real, trail, pool)); /* Finally, add the COPY_ID to the transaction's list of copies so that, if this transaction is aborted, the `copies' table entry we added above will be cleaned up. */ SVN_ERR(svn_fs_base__add_txn_copy(fs, txn_id, copy_id, trail, pool)); } else /* don't preserve history */ { id = svn_fs_base__dag_get_id(from_node); } /* Set the entry in to_node to the new id. */ SVN_ERR(svn_fs_base__dag_set_entry(to_node, entry, id, txn_id, trail, pool)); return SVN_NO_ERROR;}/*** Deltification ***/svn_error_t *svn_fs_base__dag_deltify(dag_node_t *target, dag_node_t *source, svn_boolean_t props_only, trail_t *trail, apr_pool_t *pool){ node_revision_t *source_nr, *target_nr; svn_fs_t *fs = svn_fs_base__dag_get_fs(target); /* Get node revisions for the two nodes. */ SVN_ERR(svn_fs_bdb__get_node_revision(&target_nr, fs, target->id, trail, pool)); SVN_ERR(svn_fs_bdb__get_node_revision(&source_nr, fs, source->id, trail, pool)); /* If TARGET and SOURCE both have properties, and are not sharing a property key, deltify TARGET's properties. */ if (target_nr->prop_key && source_nr->prop_key && (strcmp(target_nr->prop_key, source_nr->prop_key))) SVN_ERR(svn_fs_base__rep_deltify(fs, target_nr->prop_key, source_nr->prop_key, trail, pool)); /* If we are not only attending to properties, and if TARGET and SOURCE both have data, and are not sharing a data key, deltify TARGET's data. */ if ((! props_only) && target_nr->data_key && source_nr->data_key && (strcmp(target_nr->data_key, source_nr->data_key))) SVN_ERR(svn_fs_base__rep_deltify(fs, target_nr->data_key, source_nr->data_key, trail, pool)); return SVN_NO_ERROR;}/*** Committing ***/svn_error_t *svn_fs_base__dag_commit_txn(svn_revnum_t *new_rev, svn_fs_t *fs, const char *txn_id, trail_t *trail, apr_pool_t *pool){ revision_t revision; svn_string_t date; apr_hash_t *txnprops; /* Remove any temporary transaction properties initially created by begin_txn(). */ SVN_ERR(svn_fs_base__txn_proplist_in_trail(&txnprops, txn_id, trail)); if (txnprops) { if (apr_hash_get(txnprops, SVN_FS_PROP_TXN_CHECK_OOD, APR_HASH_KEY_STRING)) SVN_ERR(svn_fs_base__set_txn_prop (fs, txn_id, SVN_FS_PROP_TXN_CHECK_OOD, NULL, trail, pool)); if (apr_hash_get(txnprops, SVN_FS_PROP_TXN_CHECK_LOCKS, APR_HASH_KEY_STRING)) SVN_ERR(svn_fs_base__set_txn_prop (fs, txn_id, SVN_FS_PROP_TXN_CHECK_LOCKS, NULL, trail, pool)); } /* Add new revision entry to `revisions' table. */ revision.txn_id = txn_id; *new_rev = SVN_INVALID_REVNUM; SVN_ERR(svn_fs_bdb__put_rev(new_rev, fs, &revision, trail, pool)); /* Promote the unfinished transaction to a committed one. */ SVN_ERR(svn_fs_base__txn_make_committed(fs, txn_id, *new_rev, trail, pool)); /* Set a date on the commit. We wait until now to fetch the date, so it's definitely newer than any previous revision's date. */ date.data = svn_time_to_cstring(apr_time_now(), pool); date.len = strlen(date.data); SVN_ERR(svn_fs_base__set_rev_prop(fs, *new_rev, SVN_PROP_REVISION_DATE, &date, trail, pool)); return SVN_NO_ERROR;}/*** Comparison. ***/svn_error_t *svn_fs_base__things_different(svn_boolean_t *props_changed, svn_boolean_t *contents_changed, dag_node_t *node1, dag_node_t *node2, trail_t *trail, apr_pool_t *pool){ node_revision_t *noderev1, *noderev2; /* If we have no place to store our results, don't bother doing anything. */ if (! props_changed && ! contents_changed) return SVN_NO_ERROR; /* The the node revision skels for these two nodes. */ SVN_ERR(svn_fs_bdb__get_node_revision(&noderev1, node1->fs, node1->id, trail, pool)); SVN_ERR(svn_fs_bdb__get_node_revision(&noderev2, node2->fs, node2->id, trail, pool)); /* Compare property keys. */ if (props_changed != NULL) *props_changed = (! svn_fs_base__same_keys(noderev1->prop_key, noderev2->prop_key)); /* Compare contents keys. */ if (contents_changed != NULL) *contents_changed = (! svn_fs_base__same_keys(noderev1->data_key, noderev2->data_key)); return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -