Remove some old code
This commit is contained in:
parent
4e41084f2a
commit
6ca20c9740
3 changed files with 0 additions and 380 deletions
|
|
@ -1,196 +0,0 @@
|
||||||
use std::ops::Range;
|
|
||||||
|
|
||||||
use super::info::{LinkInfo, PageInfo};
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Page<P> {
|
|
||||||
/// Index of the first link belonging to this page.
|
|
||||||
pub start: u32,
|
|
||||||
pub data: P,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P> Page<P> {
|
|
||||||
pub fn change_data<P2>(self, f: &impl Fn(P) -> P2) -> Page<P2> {
|
|
||||||
Page {
|
|
||||||
start: self.start,
|
|
||||||
data: f(self.data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
pub struct Link<L> {
|
|
||||||
/// Index of the page this link points to.
|
|
||||||
pub to: u32,
|
|
||||||
pub data: L,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<L> Link<L> {
|
|
||||||
pub fn change_data<L2>(self, f: &impl Fn(L) -> L2) -> Link<L2> {
|
|
||||||
Link {
|
|
||||||
to: self.to,
|
|
||||||
data: f(self.data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_data_with_page<P, L2>(self, page: &P, f: &impl Fn(&P, L) -> L2) -> Link<L2> {
|
|
||||||
Link {
|
|
||||||
to: self.to,
|
|
||||||
data: f(page, self.data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AdjacencyList<P, L> {
|
|
||||||
pub pages: Vec<Page<P>>,
|
|
||||||
pub links: Vec<Link<L>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P, L> Default for AdjacencyList<P, L> {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
pages: vec![],
|
|
||||||
links: vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P, L> AdjacencyList<P, L> {
|
|
||||||
pub fn push_page(&mut self, data: P) {
|
|
||||||
self.pages.push(Page {
|
|
||||||
start: self.links.len() as u32,
|
|
||||||
data,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_link(&mut self, to: u32, data: L) {
|
|
||||||
self.links.push(Link { to, data })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn page(&self, page_idx: u32) -> &Page<P> {
|
|
||||||
&self.pages[page_idx as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn page_mut(&mut self, page_idx: u32) -> &mut Page<P> {
|
|
||||||
&mut self.pages[page_idx as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn pages(&self) -> impl Iterator<Item = (u32, &Page<P>)> {
|
|
||||||
self.pages.iter().enumerate().map(|(i, p)| (i as u32, p))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn link(&self, link_idx: u32) -> &Link<L> {
|
|
||||||
&self.links[link_idx as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn link_mut(&mut self, link_idx: u32) -> &mut Link<L> {
|
|
||||||
&mut self.links[link_idx as usize]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn link_range(&self, page_idx: u32) -> Range<u32> {
|
|
||||||
let start_idx = self.pages[page_idx as usize].start;
|
|
||||||
let end_idx = match self.pages.get(page_idx as usize + 1) {
|
|
||||||
Some(page) => page.start,
|
|
||||||
None => self.links.len() as u32,
|
|
||||||
};
|
|
||||||
start_idx..end_idx
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn link_redirect(&self, page_idx: u32) -> Option<u32> {
|
|
||||||
let range = self.link_range(page_idx);
|
|
||||||
if range.is_empty() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(range.start)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn links(&self, page_idx: u32) -> impl Iterator<Item = (u32, &Link<L>)> {
|
|
||||||
self.link_range(page_idx).map(|i| (i, self.link(i)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_page_data<P2>(self, page_f: impl Fn(P) -> P2) -> AdjacencyList<P2, L> {
|
|
||||||
let pages = self
|
|
||||||
.pages
|
|
||||||
.into_iter()
|
|
||||||
.map(|p| p.change_data(&page_f))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
AdjacencyList {
|
|
||||||
pages,
|
|
||||||
links: self.links,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_link_data<L2>(self, link_f: impl Fn(L) -> L2) -> AdjacencyList<P, L2> {
|
|
||||||
let links = self
|
|
||||||
.links
|
|
||||||
.into_iter()
|
|
||||||
.map(|l| l.change_data(&link_f))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
AdjacencyList {
|
|
||||||
pages: self.pages,
|
|
||||||
links,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn change_link_data_with_page<L2>(
|
|
||||||
self,
|
|
||||||
link_f: impl Fn(&P, L) -> L2,
|
|
||||||
) -> AdjacencyList<P, L2> {
|
|
||||||
let mut pages = self.pages.iter().peekable();
|
|
||||||
let Some(mut cur_page) = pages.next() else {
|
|
||||||
// The list is empty, nothing to do
|
|
||||||
return AdjacencyList::default();
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut links = vec![];
|
|
||||||
|
|
||||||
for (i, link) in self.links.into_iter().enumerate() {
|
|
||||||
if let Some(page) = pages.peek() {
|
|
||||||
if i >= page.start as usize {
|
|
||||||
cur_page = page;
|
|
||||||
pages.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
links.push(link.change_data_with_page(&cur_page.data, &link_f));
|
|
||||||
}
|
|
||||||
|
|
||||||
AdjacencyList {
|
|
||||||
pages: self.pages,
|
|
||||||
links,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AdjacencyList<PageInfo, LinkInfo> {
|
|
||||||
pub fn check_consistency(&self) {
|
|
||||||
// Check that all types are large enough
|
|
||||||
assert!(self.pages.len() < u32::MAX as usize, "too many pages");
|
|
||||||
assert!(self.links.len() < u32::MAX as usize, "too many links");
|
|
||||||
for page in &self.pages {
|
|
||||||
assert!(
|
|
||||||
page.data.title.len() <= u8::MAX as usize,
|
|
||||||
"page title too long"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that all links contain valid indices. Links must not link to
|
|
||||||
// the sentinel page.
|
|
||||||
let range = 0..self.pages.len() as u32;
|
|
||||||
for link in &self.links {
|
|
||||||
assert!(range.contains(&link.to), "invalid link");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that all redirect pages have at most one link
|
|
||||||
for (page_idx, page) in self.pages.iter().enumerate() {
|
|
||||||
if page.data.redirect {
|
|
||||||
let range = self.link_range(page_idx as u32);
|
|
||||||
let amount = range.end - range.start;
|
|
||||||
assert!(amount <= 1, "too many redirect links");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct PageInfo {
|
|
||||||
pub id: u32,
|
|
||||||
pub title: String,
|
|
||||||
pub length: u32,
|
|
||||||
pub redirect: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
|
||||||
pub struct LinkInfo {
|
|
||||||
pub start: u32,
|
|
||||||
pub len: u32,
|
|
||||||
pub flags: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LinkInfo {
|
|
||||||
pub fn in_parens(self) -> bool {
|
|
||||||
self.flags & 0b1 != 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn in_structure(self) -> bool {
|
|
||||||
self.flags & 0b10 != 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,160 +0,0 @@
|
||||||
use std::io::{self, Read, Write};
|
|
||||||
|
|
||||||
use crate::graph::{EdgeIdx, Graph, NodeIdx};
|
|
||||||
|
|
||||||
use super::{
|
|
||||||
adjacency_list::{AdjacencyList, Link, Page},
|
|
||||||
info::{LinkInfo, PageInfo},
|
|
||||||
};
|
|
||||||
|
|
||||||
fn write_u8<W: Write>(n: u8, to: &mut W) -> io::Result<()> {
|
|
||||||
to.write_all(&n.to_le_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u8<R: Read>(from: &mut R) -> io::Result<u8> {
|
|
||||||
let mut buf = [0_u8; 1];
|
|
||||||
from.read_exact(&mut buf)?;
|
|
||||||
Ok(u8::from_le_bytes(buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_u16<W: Write>(n: u16, to: &mut W) -> io::Result<()> {
|
|
||||||
to.write_all(&n.to_le_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u16<R: Read>(from: &mut R) -> io::Result<u16> {
|
|
||||||
let mut buf = [0_u8; 2];
|
|
||||||
from.read_exact(&mut buf)?;
|
|
||||||
Ok(u16::from_le_bytes(buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_u32<W: Write>(n: u32, to: &mut W) -> io::Result<()> {
|
|
||||||
to.write_all(&n.to_le_bytes())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_u32<R: Read>(from: &mut R) -> io::Result<u32> {
|
|
||||||
let mut buf = [0_u8; 4];
|
|
||||||
from.read_exact(&mut buf)?;
|
|
||||||
Ok(u32::from_le_bytes(buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_str<W: Write>(s: &str, to: &mut W) -> io::Result<()> {
|
|
||||||
assert!(s.len() <= u16::MAX as usize);
|
|
||||||
write_u16(s.len() as u16, to)?;
|
|
||||||
to.write_all(s.as_bytes())?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_str<R: Read>(from: &mut R) -> io::Result<String> {
|
|
||||||
let len = read_u16(from)? as usize;
|
|
||||||
let mut buf = vec![0_u8; len];
|
|
||||||
from.read_exact(&mut buf)?;
|
|
||||||
Ok(String::from_utf8(buf).unwrap())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_page<W: Write>(page: &Page<PageInfo>, to: &mut W) -> io::Result<()> {
|
|
||||||
write_u32(page.start, to)?;
|
|
||||||
write_u32(page.data.id, to)?;
|
|
||||||
write_u32(page.data.length, to)?;
|
|
||||||
write_u8(if page.data.redirect { 1 } else { 0 }, to)?;
|
|
||||||
write_str(&page.data.title, to)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_page<R: Read>(from: &mut R) -> io::Result<Page<PageInfo>> {
|
|
||||||
let start_link_idx = read_u32(from)?;
|
|
||||||
let id = read_u32(from)?;
|
|
||||||
let length = read_u32(from)?;
|
|
||||||
let redirect = read_u8(from)? != 0;
|
|
||||||
let title = read_str(from)?;
|
|
||||||
|
|
||||||
Ok(Page {
|
|
||||||
start: start_link_idx,
|
|
||||||
data: PageInfo {
|
|
||||||
id,
|
|
||||||
length,
|
|
||||||
redirect,
|
|
||||||
title,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn write_link<W: Write>(link: &Link<LinkInfo>, to: &mut W) -> io::Result<()> {
|
|
||||||
write_u32(link.to, to)?;
|
|
||||||
write_u32(link.data.start, to)?;
|
|
||||||
write_u32(link.data.len, to)?;
|
|
||||||
write_u8(link.data.flags, to)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn read_link<R: Read>(from: &mut R) -> io::Result<Link<LinkInfo>> {
|
|
||||||
let to_page_idx = read_u32(from)?;
|
|
||||||
let start = read_u32(from)?;
|
|
||||||
let len = read_u32(from)?;
|
|
||||||
let flags = read_u8(from)?;
|
|
||||||
|
|
||||||
Ok(Link {
|
|
||||||
to: to_page_idx,
|
|
||||||
data: LinkInfo { start, len, flags },
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_adjacency_list<W: Write>(
|
|
||||||
al: &AdjacencyList<PageInfo, LinkInfo>,
|
|
||||||
to: &mut W,
|
|
||||||
) -> io::Result<()> {
|
|
||||||
write_u32(al.pages.len() as u32, to)?;
|
|
||||||
write_u32(al.links.len() as u32, to)?;
|
|
||||||
|
|
||||||
for page in &al.pages {
|
|
||||||
write_page(page, to)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
for link in &al.links {
|
|
||||||
write_link(link, to)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_adjacency_list<R: Read>(from: &mut R) -> io::Result<AdjacencyList<PageInfo, LinkInfo>> {
|
|
||||||
let n_pages = read_u32(from)?;
|
|
||||||
let n_links = read_u32(from)?;
|
|
||||||
|
|
||||||
let mut pages = vec![];
|
|
||||||
for _ in 0..n_pages {
|
|
||||||
pages.push(read_page(from)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut links = vec![];
|
|
||||||
for _ in 0..n_links {
|
|
||||||
links.push(read_link(from)?);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(AdjacencyList { pages, links })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn read_graph(from: &mut impl Read) -> io::Result<(Vec<PageInfo>, Vec<LinkInfo>, Graph)> {
|
|
||||||
let n_pages = read_u32(from)?;
|
|
||||||
let n_links = read_u32(from)?;
|
|
||||||
|
|
||||||
let mut pages = Vec::with_capacity(n_pages as usize);
|
|
||||||
let mut links = Vec::with_capacity(n_links as usize);
|
|
||||||
let mut graph = Graph::with_capacity(n_pages as usize, n_links as usize);
|
|
||||||
|
|
||||||
for _ in 0..n_pages {
|
|
||||||
let page = read_page(from)?;
|
|
||||||
graph.nodes.push(EdgeIdx(page.start));
|
|
||||||
pages.push(page.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
for _ in 0..n_links {
|
|
||||||
let link = read_link(from)?;
|
|
||||||
graph.edges.push(NodeIdx(link.to));
|
|
||||||
links.push(link.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
graph.check_consistency();
|
|
||||||
Ok((pages, links, graph))
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue