Eliminate left and right cursors in favor of ring buffer
This commit is contained in:
parent
cc66a7ff20
commit
4d3faae5cd
2 changed files with 33 additions and 30 deletions
|
@ -206,10 +206,6 @@ pub struct Printer {
|
||||||
margin: isize,
|
margin: isize,
|
||||||
/// Number of spaces left on line
|
/// Number of spaces left on line
|
||||||
space: isize,
|
space: isize,
|
||||||
/// Index of left side of input stream
|
|
||||||
left: usize,
|
|
||||||
/// Index of right side of input stream
|
|
||||||
right: usize,
|
|
||||||
/// Ring-buffer of tokens and calculated sizes
|
/// Ring-buffer of tokens and calculated sizes
|
||||||
buf: RingBuffer<BufEntry>,
|
buf: RingBuffer<BufEntry>,
|
||||||
/// Running size of stream "...left"
|
/// Running size of stream "...left"
|
||||||
|
@ -245,8 +241,6 @@ impl Printer {
|
||||||
out: String::new(),
|
out: String::new(),
|
||||||
margin: linewidth as isize,
|
margin: linewidth as isize,
|
||||||
space: linewidth as isize,
|
space: linewidth as isize,
|
||||||
left: 0,
|
|
||||||
right: 0,
|
|
||||||
buf: RingBuffer::new(),
|
buf: RingBuffer::new(),
|
||||||
left_total: 0,
|
left_total: 0,
|
||||||
right_total: 0,
|
right_total: 0,
|
||||||
|
@ -281,22 +275,18 @@ impl Printer {
|
||||||
if self.scan_stack.is_empty() {
|
if self.scan_stack.is_empty() {
|
||||||
self.left_total = 1;
|
self.left_total = 1;
|
||||||
self.right_total = 1;
|
self.right_total = 1;
|
||||||
self.right = self.left;
|
|
||||||
self.buf.clear();
|
self.buf.clear();
|
||||||
} else {
|
|
||||||
self.right += 1;
|
|
||||||
}
|
}
|
||||||
self.buf.push(BufEntry { token: Token::Begin(b), size: -self.right_total });
|
let right = self.buf.push(BufEntry { token: Token::Begin(b), size: -self.right_total });
|
||||||
self.scan_stack.push_front(self.right);
|
self.scan_stack.push_front(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scan_end(&mut self) {
|
fn scan_end(&mut self) {
|
||||||
if self.scan_stack.is_empty() {
|
if self.scan_stack.is_empty() {
|
||||||
self.print_end();
|
self.print_end();
|
||||||
} else {
|
} else {
|
||||||
self.right += 1;
|
let right = self.buf.push(BufEntry { token: Token::End, size: -1 });
|
||||||
self.buf.push(BufEntry { token: Token::End, size: -1 });
|
self.scan_stack.push_front(right);
|
||||||
self.scan_stack.push_front(self.right);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -304,14 +294,12 @@ impl Printer {
|
||||||
if self.scan_stack.is_empty() {
|
if self.scan_stack.is_empty() {
|
||||||
self.left_total = 1;
|
self.left_total = 1;
|
||||||
self.right_total = 1;
|
self.right_total = 1;
|
||||||
self.right = self.left;
|
|
||||||
self.buf.clear();
|
self.buf.clear();
|
||||||
} else {
|
} else {
|
||||||
self.check_stack(0);
|
self.check_stack(0);
|
||||||
self.right += 1;
|
|
||||||
}
|
}
|
||||||
self.buf.push(BufEntry { token: Token::Break(b), size: -self.right_total });
|
let right = self.buf.push(BufEntry { token: Token::Break(b), size: -self.right_total });
|
||||||
self.scan_stack.push_front(self.right);
|
self.scan_stack.push_front(right);
|
||||||
self.right_total += b.blank_space;
|
self.right_total += b.blank_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,7 +307,6 @@ impl Printer {
|
||||||
if self.scan_stack.is_empty() {
|
if self.scan_stack.is_empty() {
|
||||||
self.print_string(&s);
|
self.print_string(&s);
|
||||||
} else {
|
} else {
|
||||||
self.right += 1;
|
|
||||||
let len = s.len() as isize;
|
let len = s.len() as isize;
|
||||||
self.buf.push(BufEntry { token: Token::String(s), size: len });
|
self.buf.push(BufEntry { token: Token::String(s), size: len });
|
||||||
self.right_total += len;
|
self.right_total += len;
|
||||||
|
@ -329,22 +316,22 @@ impl Printer {
|
||||||
|
|
||||||
fn check_stream(&mut self) {
|
fn check_stream(&mut self) {
|
||||||
while self.right_total - self.left_total > self.space {
|
while self.right_total - self.left_total > self.space {
|
||||||
if self.scan_stack.back() == Some(&self.left) {
|
if *self.scan_stack.back().unwrap() == self.buf.index_of_first() {
|
||||||
self.scan_stack.pop_back().unwrap();
|
self.scan_stack.pop_back().unwrap();
|
||||||
self.buf[self.left].size = SIZE_INFINITY;
|
self.buf.first_mut().unwrap().size = SIZE_INFINITY;
|
||||||
}
|
}
|
||||||
self.advance_left();
|
self.advance_left();
|
||||||
if self.left == self.right {
|
if self.buf.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn advance_left(&mut self) {
|
fn advance_left(&mut self) {
|
||||||
let mut left_size = self.buf[self.left].size;
|
let mut left_size = self.buf.first().unwrap().size;
|
||||||
|
|
||||||
while left_size >= 0 {
|
while left_size >= 0 {
|
||||||
let left = self.buf[self.left].token.clone();
|
let left = self.buf.first().unwrap().token.clone();
|
||||||
|
|
||||||
let len = match left {
|
let len = match left {
|
||||||
Token::Break(b) => b.blank_space,
|
Token::Break(b) => b.blank_space,
|
||||||
|
@ -360,14 +347,12 @@ impl Printer {
|
||||||
|
|
||||||
self.left_total += len;
|
self.left_total += len;
|
||||||
|
|
||||||
if self.left == self.right {
|
self.buf.advance_left();
|
||||||
|
if self.buf.is_empty() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.buf.advance_left();
|
left_size = self.buf.first().unwrap().size;
|
||||||
self.left += 1;
|
|
||||||
|
|
||||||
left_size = self.buf[self.left].size;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,14 @@ impl<T> RingBuffer<T> {
|
||||||
RingBuffer { data: VecDeque::new(), offset: 0 }
|
RingBuffer { data: VecDeque::new(), offset: 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push(&mut self, value: T) {
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.data.is_empty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(&mut self, value: T) -> usize {
|
||||||
|
let index = self.offset + self.data.len();
|
||||||
self.data.push_back(value);
|
self.data.push_back(value);
|
||||||
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn advance_left(&mut self) {
|
pub fn advance_left(&mut self) {
|
||||||
|
@ -35,6 +41,18 @@ impl<T> RingBuffer<T> {
|
||||||
self.data.clear();
|
self.data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn index_of_first(&self) -> usize {
|
||||||
|
self.offset
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first(&self) -> Option<&T> {
|
||||||
|
self.data.front()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn first_mut(&mut self) -> Option<&mut T> {
|
||||||
|
self.data.front_mut()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn last(&self) -> Option<&T> {
|
pub fn last(&self) -> Option<&T> {
|
||||||
self.data.back()
|
self.data.back()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue