Skip to content

Commit

Permalink
update metadata for commit
Browse files Browse the repository at this point in the history
  • Loading branch information
EloyMartinez committed Jan 8, 2025
1 parent 3433a80 commit 1c5719b
Show file tree
Hide file tree
Showing 4 changed files with 160 additions and 1 deletion.
136 changes: 135 additions & 1 deletion src/lib/src/core/v0_19_0/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::view::PaginatedDirEntries;
use std::collections::HashMap;
use std::path::Path;

use super::index::CommitMerkleTree;
use super::index::{CommitMerkleTree, MerkleNodeDB};

pub fn get_directory(
repo: &LocalRepository,
Expand Down Expand Up @@ -442,3 +442,137 @@ pub fn list_for_commit(
.map(|entry| CommitEntry::from_file_node(&entry.file_node))
.collect())
}

pub fn update_metadata(repo: &LocalRepository, revision: impl AsRef<str>) -> Result<(), OxenError> {
let commit = repositories::revisions::get(repo, revision.as_ref())?
.ok_or_else(|| OxenError::revision_not_found(revision.as_ref().to_string().into()))?;
let tree: CommitMerkleTree = CommitMerkleTree::from_commit(repo, &commit)?;
let mut node = tree.root;

// Initialize data structures for aggregation
let mut num_bytes = 0;

// Start the recursive traversal
traverse_and_update(repo, &mut node, &mut num_bytes)?;

Ok(())
}

fn traverse_and_update(
repo: &LocalRepository,
node: &mut MerkleTreeNode,
num_bytes: &mut u64,
) -> Result<(HashMap<String, u64>, HashMap<String, u64>), OxenError> {

Check failure on line 465 in src/lib/src/core/v0_19_0/entries.rs

View workflow job for this annotation

GitHub Actions / Clippy

very complex type used. Consider factoring parts into `type` definitions
let mut local_counts: HashMap<String, u64> = HashMap::new();
let mut local_sizes: HashMap<String, u64> = HashMap::new();

let children: &mut Vec<MerkleTreeNode> = &mut node.children;

match &mut node.node {
EMerkleTreeNode::Commit(commit_node) => {
log::debug!("Traversing node {:?}", commit_node);
process_children(
repo,
children,
&mut local_counts,
&mut local_sizes,
num_bytes,
)?;
let mut dir_db = MerkleNodeDB::open_read_write(repo, commit_node, node.parent_id)?;
add_children_to_db(&mut dir_db, &node.children)?;
}
EMerkleTreeNode::VNode(vnode) => {
log::debug!("Traversing vnode {:?}", vnode);
process_children(
repo,
children,
&mut local_counts,
&mut local_sizes,
num_bytes,
)?;
let mut dir_db = MerkleNodeDB::open_read_write(repo, vnode, node.parent_id)?;
add_children_to_db(&mut dir_db, &node.children)?;
}
EMerkleTreeNode::Directory(dir_node) => {
log::debug!("No need to aggregate dir {}", dir_node.name);
process_children(
repo,
children,
&mut local_counts,
&mut local_sizes,
num_bytes,
)?;
dir_node.data_type_counts = local_counts.clone();
dir_node.data_type_sizes = local_sizes.clone();
let mut dir_db = MerkleNodeDB::open_read_write(repo, dir_node, node.parent_id)?;
add_children_to_db(&mut dir_db, &node.children)?;
}
EMerkleTreeNode::File(file_node) => {
log::debug!(
"Updating hash for file {} -> hash {}",
file_node.name,
file_node.hash
);
*num_bytes += file_node.num_bytes;
*local_counts
.entry(file_node.data_type.to_string())
.or_insert(0) += 1;
*local_sizes
.entry(file_node.data_type.to_string())
.or_insert(0) += file_node.num_bytes as u64;

Check failure on line 522 in src/lib/src/core/v0_19_0/entries.rs

View workflow job for this annotation

GitHub Actions / Clippy

casting to the same type is unnecessary (`u64` -> `u64`)
}
_ => {
return Err(OxenError::basic_str(format!(
"compute_dir_node found unexpected node type: {:?}",
node.node
)));
}
}

Ok((local_counts, local_sizes))
}

fn process_children(
repo: &LocalRepository,
children: &mut Vec<MerkleTreeNode>,

Check failure on line 537 in src/lib/src/core/v0_19_0/entries.rs

View workflow job for this annotation

GitHub Actions / Clippy

writing `&mut Vec` instead of `&mut [_]` involves a new object where a slice will do
local_counts: &mut HashMap<String, u64>,
local_sizes: &mut HashMap<String, u64>,
num_bytes: &mut u64,
) -> Result<(), OxenError> {
for child in children.iter_mut() {
let (child_counts, child_sizes) = traverse_and_update(repo, child, num_bytes)?;
for (key, count) in child_counts {
*local_counts.entry(key).or_insert(0) += count;
}
for (key, size) in child_sizes {
*local_sizes.entry(key).or_insert(0) += size;
}
}
Ok(())
}

fn add_children_to_db(
dir_db: &mut MerkleNodeDB,
children: &[MerkleTreeNode],
) -> Result<(), OxenError> {
for child in children {
match &child.node {
EMerkleTreeNode::Commit(commit_node) => {
dir_db.add_child(commit_node)?;
}
EMerkleTreeNode::Directory(dir_node) => {
dir_db.add_child(dir_node)?;
}
EMerkleTreeNode::File(file_node) => {
dir_db.add_child(file_node)?;
}
EMerkleTreeNode::VNode(vnode) => {
dir_db.add_child(vnode)?;
}
_ => {
return Err(OxenError::basic_str("Unsupported node type"));
}
}
}
Ok(())
}
9 changes: 9 additions & 0 deletions src/lib/src/repositories/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ pub fn list_directory_w_version(
}
}

pub fn update_metadata(repo: &LocalRepository, revision: impl AsRef<str>) -> Result<(), OxenError> {
match repo.min_version() {
MinOxenVersion::V0_10_0 => {
panic!("update_metadata not implemented for oxen v0.10.0")
}
MinOxenVersion::V0_19_0 => core::v0_19_0::entries::update_metadata(repo, revision),
}
}

/// Get the entry for a given path in a commit.
/// Could be a file or a directory.
pub fn get_meta_entry(
Expand Down
12 changes: 12 additions & 0 deletions src/server/src/controllers/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,3 +224,15 @@ pub async fn agg_dir(
Ok(HttpResponse::BadRequest().json(StatusMessage::resource_not_found()))
}
}

pub async fn update_metadata(req: HttpRequest) -> actix_web::Result<HttpResponse, OxenHttpError> {
let app_data = app_data(&req)?;
let namespace = path_param(&req, "namespace")?;
let repo_name = path_param(&req, "repo_name")?;
let repo = get_repo(&app_data.path, &namespace, &repo_name)?;
let resource = parse_resource(&req, &repo)?;

repositories::entries::update_metadata(&repo, resource.version.to_str().unwrap_or_default())?;

Ok(HttpResponse::Ok().json(StatusMessage::resource_updated()))
}
4 changes: 4 additions & 0 deletions src/server/src/services/meta.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,8 @@ pub fn meta() -> Scope {
web::get().to(controllers::metadata::agg_dir),
)
.route("/{resource:.*}", web::get().to(controllers::metadata::file))
.route(
"/{resource:.*}",
web::post().to(controllers::metadata::update_metadata),
)
}

0 comments on commit 1c5719b

Please sign in to comment.