Check for package upgrades in parallel; Search in packages in parallel;
This commit is contained in:
parent
26be99f408
commit
a1843cac33
@ -2,8 +2,16 @@ use ron::ser::PrettyConfig;
|
||||
|
||||
use {
|
||||
crate::{Package, Repository, Version},
|
||||
rayon::prelude::*,
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{collections::HashMap, error::Error, fmt, fs::{self, File}, path::PathBuf},
|
||||
std::{
|
||||
collections::HashMap,
|
||||
error::Error,
|
||||
fmt,
|
||||
fs::{self, File},
|
||||
path::PathBuf,
|
||||
sync::Mutex,
|
||||
},
|
||||
url::Url,
|
||||
zstd::{Decoder, Encoder},
|
||||
};
|
||||
@ -50,46 +58,48 @@ impl Database {
|
||||
|
||||
pub fn get_upgradable(&mut self) -> Result<HashMap<String, Update>, Box<dyn Error>> {
|
||||
self.update()?;
|
||||
let mut updates = HashMap::<String, Update>::new();
|
||||
for local_package in self.packages.values() {
|
||||
let name = local_package.name.clone();
|
||||
let updates = Mutex::new(HashMap::<String, Update>::new());
|
||||
self.packages.par_iter().for_each(|(key, local_package)| {
|
||||
for repo in self.available.values() {
|
||||
// Check if the remote has a package by this name
|
||||
if let Some(remote_package) = repo.packages.get(&name) {
|
||||
if let Some(remote_package) = repo.packages.get(key) {
|
||||
// Check if the remote package is an update
|
||||
if remote_package.is_upgrade(&local_package) {
|
||||
// Check if we've already pulled in an update from another repo,
|
||||
// and if so compare versions
|
||||
if let Some(other_update) = updates.get(&name) {
|
||||
if remote_package.version > other_update.version
|
||||
|| (remote_package.version == other_update.version
|
||||
&& remote_package.release > other_update.release)
|
||||
{
|
||||
// The remote version is an update to the already
|
||||
// pulled in update, so swap it out
|
||||
if let Ok(mut updates) = updates.lock() {
|
||||
// Check if we've already pulled in an update from another repo,
|
||||
// and if so compare versions
|
||||
if let Some(other_update) = updates.get(key) {
|
||||
if remote_package.version > other_update.version
|
||||
|| (remote_package.version == other_update.version
|
||||
&& remote_package.release > other_update.release)
|
||||
{
|
||||
// The remote version is an update to the already
|
||||
// pulled in update, so swap it out
|
||||
let update = Update {
|
||||
name: key.to_string(),
|
||||
version: remote_package.version.clone(),
|
||||
release: remote_package.release,
|
||||
url: repo.base_url.clone(),
|
||||
};
|
||||
updates.insert(key.to_string(), update);
|
||||
}
|
||||
} else {
|
||||
// First time we've seen this update, so insert it
|
||||
// into our hashmap
|
||||
let update = Update {
|
||||
name: name.clone(),
|
||||
name: key.to_string(),
|
||||
version: remote_package.version.clone(),
|
||||
release: remote_package.release,
|
||||
url: repo.base_url.clone(),
|
||||
};
|
||||
updates.insert(name.clone(), update);
|
||||
updates.insert(key.to_string(), update);
|
||||
}
|
||||
} else {
|
||||
// First time we've seen this update, so insert it
|
||||
// into our hashmap
|
||||
let update = Update {
|
||||
name: name.clone(),
|
||||
version: remote_package.version.clone(),
|
||||
release: remote_package.release,
|
||||
url: repo.base_url.clone(),
|
||||
};
|
||||
updates.insert(name.clone(), update);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
let updates = updates.into_inner()?;
|
||||
Ok(updates)
|
||||
}
|
||||
|
||||
@ -125,3 +135,20 @@ impl Database {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn update_to_string() {
|
||||
let up = Update {
|
||||
name: "hpk".to_string(),
|
||||
version: Version::Number(42),
|
||||
release: 1,
|
||||
url: Url::parse("https://hitchhiker-linux.org/pub/packages/").unwrap(),
|
||||
}
|
||||
.to_string();
|
||||
assert_eq!("hpk-42_1".to_string(), up);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,6 @@ pub fn get_dbdir(prefix: Option<PathBuf>) -> PathBuf {
|
||||
path
|
||||
}
|
||||
|
||||
|
||||
/// Gets the cache directory path. Takes an optional prefix variable for working
|
||||
/// with an alternate filesystem root.
|
||||
/// ## Examples
|
||||
@ -120,4 +119,3 @@ mod test {
|
||||
assert_eq!(cache, PathBuf::from("/mnt/aarch64/var/cache/hpk"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,8 +6,8 @@ use {
|
||||
ron::ser::{to_string_pretty, PrettyConfig},
|
||||
serde::{Deserialize, Serialize},
|
||||
std::{
|
||||
fs,
|
||||
error::Error,
|
||||
fs,
|
||||
fs::File,
|
||||
io::{BufWriter, Write},
|
||||
path::Path,
|
||||
|
@ -1,7 +1,10 @@
|
||||
use std::sync::PoisonError;
|
||||
|
||||
use {
|
||||
crate::Package,
|
||||
rayon::prelude::*,
|
||||
serde::{Deserialize, Serialize},
|
||||
std::collections::HashMap,
|
||||
std::{collections::HashMap, sync::Mutex},
|
||||
url::Url,
|
||||
};
|
||||
|
||||
@ -13,32 +16,40 @@ pub struct Repository {
|
||||
}
|
||||
|
||||
impl Repository {
|
||||
pub fn search_names(&self, query: &str) -> Vec<&Package> {
|
||||
pub fn search_names(&self, query: &str) -> Result<Vec<&Package>, PoisonError<Vec<&Package>>> {
|
||||
let mut results = vec![];
|
||||
if let Some(p) = self.packages.get(query) {
|
||||
results.push(p)
|
||||
}
|
||||
self.packages.iter().for_each(|(k, v)| {
|
||||
let results = Mutex::new(results);
|
||||
self.packages.par_iter().for_each(|(k, v)| {
|
||||
if k.contains(query) {
|
||||
results.push(v);
|
||||
if let Ok(mut r) = results.lock() {
|
||||
r.push(v);
|
||||
}
|
||||
}
|
||||
});
|
||||
results
|
||||
let results = results.into_inner()?;
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub fn search_all(&self, query: &str) -> Vec<&Package> {
|
||||
pub fn search_all(&self, query: &str) -> Result<Vec<&Package>, PoisonError<Vec<&Package>>> {
|
||||
let mut results = vec![];
|
||||
if let Some(p) = self.packages.get(query) {
|
||||
results.push(p)
|
||||
}
|
||||
self.packages.iter().for_each(|(k, v)| {
|
||||
let results = Mutex::new(results);
|
||||
self.packages.par_iter().for_each(|(k, v)| {
|
||||
if k.contains(query)
|
||||
|| v.description.contains(query)
|
||||
|| v.long_description.contains(query)
|
||||
{
|
||||
results.push(v);
|
||||
if let Ok(mut r) = results.lock() {
|
||||
r.push(v);
|
||||
}
|
||||
}
|
||||
});
|
||||
results
|
||||
let results = results.into_inner()?;
|
||||
Ok(results)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user