diff --git a/rust/src/container.rs b/rust/src/container.rs index 60c73fb31e..41dfeea1b5 100644 --- a/rust/src/container.rs +++ b/rust/src/container.rs @@ -262,6 +262,7 @@ pub fn container_encapsulate(args: Vec) -> CxxResult<()> { }); let mut lowest_change_time = None; + let mut highest_change_time = None; let mut package_meta = HashMap::new(); for pkg in pkglist.iter() { let name = pkg.child_value(0); @@ -277,6 +278,13 @@ pub fn container_encapsulate(args: Vec) -> CxxResult<()> { } else { lowest_change_time = Some((Rc::clone(&nevra), pkgmeta.buildtime())) } + if let Some(hightime) = highest_change_time.as_mut() { + if *hightime > buildtime { + *hightime = buildtime; + } + } else { + highest_change_time = Some(pkgmeta.buildtime()) + } state.rpmsize += pkgmeta.size(); package_meta.insert(nevra, pkgmeta); } @@ -284,6 +292,8 @@ pub fn container_encapsulate(args: Vec) -> CxxResult<()> { // SAFETY: There must be at least one package. let (lowest_change_name, lowest_change_time) = lowest_change_time.expect("Failed to find any packages"); + let highest_change_time = highest_change_time.expect("Failed to find any packages"); + // Walk over the packages, and generate the `packagemeta` mapping, which is basically a subset of // package metadata abstracted for ostree. Note that right now, the package metadata includes // both a "unique identifer" and a "human readable name", but for rpm-ostree we're just making @@ -291,19 +301,25 @@ pub fn container_encapsulate(args: Vec) -> CxxResult<()> { for (nevra, pkgmeta) in package_meta.iter() { let buildtime = pkgmeta.buildtime(); let change_time_offset_secs: u32 = buildtime - .checked_sub(lowest_change_time) + .checked_sub(lowest_change_time .unwrap() .try_into() .unwrap(); // Convert to hours, because there's no strong use for caring about the relative difference of builds in terms // of minutes or seconds. let change_time_offset = change_time_offset_secs / (60 * 60); + let changelogs = pkgmeta.changelogs(); + let pruned_changelogs: Vec<&u64> = changelogs.iter().filter(|e| { + let curr_build = glib::DateTime::from_unix_utc(**e as i64).unwrap(); + let highest_time_build = glib::DateTime::from_unix_utc(highest_change_time as i64).unwrap(); + highest_time_build.difference(&curr_build).as_days() <= 365_i64 + }).collect(); state.packagemeta.insert(ObjectSourceMeta { identifier: Rc::clone(nevra), name: Rc::from(libdnf_sys::hy_split_nevra(&nevra)?.name), srcid: Rc::from(pkgmeta.src_pkg().to_str().unwrap()), change_time_offset, - change_frequency: pkgmeta.change_frequency(), + change_frequency: pruned_changelogs.len() as u32, }); } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 539e425ab0..7750afcb89 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -877,7 +877,7 @@ pub mod ffi { // Methods on PackageMeta fn size(self: &PackageMeta) -> u64; fn buildtime(self: &PackageMeta) -> u64; - fn change_frequency(self: &PackageMeta) -> u32; + fn changelogs(self: &PackageMeta) -> Vec; fn src_pkg(self: &PackageMeta) -> &CxxString; } diff --git a/src/libpriv/rpmostree-refts.cxx b/src/libpriv/rpmostree-refts.cxx index d9bbf8ad39..faa0f01b6a 100644 --- a/src/libpriv/rpmostree-refts.cxx +++ b/src/libpriv/rpmostree-refts.cxx @@ -18,6 +18,8 @@ * Boston, MA 02111-1307, USA. */ +#include + #include "config.h" #include "rpmostree-refts.h" @@ -124,7 +126,7 @@ RpmTs::package_meta (const rust::Str name) const retval->_buildtime = headerGetNumber (h, RPMTAG_BUILDTIME); retval->_src_pkg = headerGetString (h, RPMTAG_SOURCERPM); - // Get the update frequency of the package from changelogs + // Get the changelogs struct rpmtd_s nchanges_date_s; _cleanup_rpmtddata_ rpmtd nchanges_date = NULL; nchanges_date = &nchanges_date_s; @@ -132,23 +134,17 @@ RpmTs::package_meta (const rust::Str name) const int ncnum = rpmtdCount (nchanges_date); if (!ncnum) ncnum = 0; - int frequency_recent_updates = 0; - GDateTime *now_dt = g_date_time_new_now_utc (); + + std::vector epochs; while (ncnum > 0) { uint64_t nchange_date = 0; rpmtdNext (nchanges_date); nchange_date = rpmtdGetNumber (nchanges_date); - GDateTime *build_dt = g_date_time_new_from_unix_utc (nchange_date); - // Ignore updates older than a year since they are irrelevant in - // describing the probability that the package will get updated again - if (g_date_time_compare (build_dt, g_date_time_add_years (now_dt, -1))) - { - frequency_recent_updates++; - } + epochs.push_back (nchange_date); --ncnum; } - retval->_change_frequency = frequency_recent_updates; + retval->_changelogs = epochs; } else { diff --git a/src/libpriv/rpmostree-refts.h b/src/libpriv/rpmostree-refts.h index 1009b63888..4cfea9dfaa 100644 --- a/src/libpriv/rpmostree-refts.h +++ b/src/libpriv/rpmostree-refts.h @@ -27,6 +27,7 @@ #include #include #include +#include G_BEGIN_DECLS @@ -52,7 +53,7 @@ struct PackageMeta { uint64_t _size; uint64_t _buildtime; - uint32_t _change_frequency; + std::vector _changelogs; std::string _src_pkg; uint64_t @@ -65,10 +66,10 @@ struct PackageMeta { return _buildtime; }; - uint32_t - change_frequency () const + std::vector + changelogs () const { - return _change_frequency; + return _changelogs; }; const std::string &