1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
use anyhow::Context;
use sqlx::{migrate::MigrateDatabase, QueryBuilder, Sqlite};
use std::{fs::File, time::Instant};
mod graph;
mod geng;
use crate::geng::GengIterator;
mod compute;
use simplelog::*;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok();
CombinedLogger::init(vec![
TermLogger::new(
LevelFilter::Info,
Config::default(),
TerminalMode::Mixed,
ColorChoice::Auto,
),
WriteLogger::new(
LevelFilter::Debug,
Config::default(),
File::create("test.log").unwrap(),
),
])
.unwrap();
let vert_num = std::env::args()
.nth(1)
.context("You should provide number of vertices in argument")?
.parse::<usize>()?;
let database_url =
std::env::var("DATABASE_URL").expect("Expected DATABASE_URL in env");
if !sqlx::Sqlite::database_exists(&database_url).await? {
log::info!("Database file doesn't exist. Creating '{database_url}'.");
sqlx::Sqlite::create_database(&database_url).await?;
}
let db = sqlx::SqlitePool::connect(&database_url).await?;
sqlx::query(
"CREATE TABLE IF NOT EXISTS graphs (\
g6 VARCHAR NOT NULL,\
size INT NOT NULL,\
ind_dom INT NOT NULL,\
forced_geod INT NOT NULL);",
)
.execute(&db)
.await?;
let gi = GengIterator::new(vert_num);
let start = Instant::now();
const BATCH_SIZE: usize = 5000;
log::info!("Started computation for {vert_num} vertices");
let mut count = 0;
loop {
let graphs = gi.take(BATCH_SIZE);
let batch = Instant::now();
let tasks: Vec<_> = graphs
.map(|g| tokio::spawn(compute::dominating_numbers(g)))
.collect();
let part = futures::future::join_all(tasks).await;
let sz = part.len();
let mut query = QueryBuilder::<Sqlite>::new(
"INSERT INTO graphs (g6, size, ind_dom, forced_geod) ",
);
query.push_values(part, |mut b, res| {
match res {
Ok((g6, size, ind_dom, fg)) => {
// log::debug!(
// "inserting {} {} {:?} {:?}",
// g6,
// size,
// ind_dom,
// fg
// );
b.push_bind(g6)
.push_bind(size as u32)
.push_bind(ind_dom.unwrap_or(0))
.push_bind(fg.unwrap_or(0));
}
Err(_) => log::error!("Unable to push into query"),
};
});
let err = query.build().execute(&db).await;
if let Err(e) = err {
log::error!("{e}");
}
count += sz;
log::info!(
"Counted {count} in {}s",
batch.elapsed().as_nanos() as f64 / 1e9
);
if sz < BATCH_SIZE {
break;
}
}
let elapsed = start.elapsed();
let time = elapsed.as_nanos();
log::info!("Time elapsed: {}s", time as f64 / 1e9);
db.close().await;
Ok(())
}
|