Skip to content

Commit 8e5e83c

Browse files
committed
Abstract the ring buffer to be infinitely sized
1 parent 778168d commit 8e5e83c

File tree

3 files changed

+58
-19
lines changed

3 files changed

+58
-19
lines changed

src/algorithm.rs

Lines changed: 11 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#![allow(dead_code)]
44

5+
use crate::ring::RingBuffer;
56
use std::borrow::Cow;
67
use std::collections::VecDeque;
78

@@ -68,7 +69,6 @@ pub const SIZE_INFINITY: isize = 0xffff;
6869

6970
pub struct Printer {
7071
out: String,
71-
buf_max_len: usize,
7272
// Width of lines we're constrained to
7373
margin: isize,
7474
// Number of spaces left on line
@@ -78,7 +78,7 @@ pub struct Printer {
7878
// Index of right side of input stream
7979
right: usize,
8080
// Ring-buffer of tokens and calculated sizes
81-
buf: Vec<BufEntry>,
81+
buf: RingBuffer<BufEntry>,
8282
// Running size of stream "...left"
8383
left_total: isize,
8484
// Running size of stream "...right"
@@ -114,18 +114,15 @@ impl Default for BufEntry {
114114
impl Printer {
115115
pub fn new() -> Self {
116116
let linewidth = 78;
117-
// Yes 55, it makes the ring buffers big enough to never fall behind.
118-
let n: usize = 55 * linewidth;
117+
let mut buf = RingBuffer::new();
118+
buf.advance_right();
119119
Printer {
120120
out: String::new(),
121-
buf_max_len: n,
122121
margin: linewidth as isize,
123122
space: linewidth as isize,
124123
left: 0,
125124
right: 0,
126-
// Initialize a single entry; advance_right() will extend it on
127-
// demand up to `buf_max_len` elements.
128-
buf: vec![BufEntry::default()],
125+
buf,
129126
left_total: 0,
130127
right_total: 0,
131128
scan_stack: VecDeque::new(),
@@ -155,8 +152,8 @@ impl Printer {
155152
if self.scan_stack.is_empty() {
156153
self.left_total = 1;
157154
self.right_total = 1;
158-
self.left = 0;
159-
self.right = 0;
155+
self.right = self.left;
156+
self.buf.truncate(1);
160157
} else {
161158
self.advance_right();
162159
}
@@ -182,8 +179,8 @@ impl Printer {
182179
if self.scan_stack.is_empty() {
183180
self.left_total = 1;
184181
self.right_total = 1;
185-
self.left = 0;
186-
self.right = 0;
182+
self.right = self.left;
183+
self.buf.truncate(1);
187184
} else {
188185
self.advance_right();
189186
}
@@ -242,12 +239,7 @@ impl Printer {
242239

243240
fn advance_right(&mut self) {
244241
self.right += 1;
245-
self.right %= self.buf_max_len;
246-
// Extend the buf if necessary.
247-
if self.right == self.buf.len() {
248-
self.buf.push(BufEntry::default());
249-
}
250-
assert_ne!(self.right, self.left);
242+
self.buf.advance_right();
251243
}
252244

253245
fn advance_left(&mut self) {
@@ -274,8 +266,8 @@ impl Printer {
274266
break;
275267
}
276268

269+
self.buf.advance_left();
277270
self.left += 1;
278-
self.left %= self.buf_max_len;
279271

280272
left_size = self.buf[self.left].size;
281273
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod lit;
1111
mod mac;
1212
mod pat;
1313
mod path;
14+
mod ring;
1415
mod stmt;
1516
mod token;
1617
mod ty;

src/ring.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use std::collections::VecDeque;
2+
use std::ops::{Index, IndexMut};
3+
4+
pub struct RingBuffer<T> {
5+
data: VecDeque<T>,
6+
// Abstract index of data[0] in infinitely sized queue
7+
offset: usize,
8+
}
9+
10+
impl<T> RingBuffer<T> {
11+
pub fn new() -> Self {
12+
RingBuffer {
13+
data: VecDeque::new(),
14+
offset: 0,
15+
}
16+
}
17+
18+
pub fn advance_right(&mut self)
19+
where
20+
T: Default,
21+
{
22+
self.data.push_back(T::default());
23+
}
24+
25+
pub fn advance_left(&mut self) {
26+
self.data.pop_front().unwrap();
27+
self.offset += 1;
28+
}
29+
30+
pub fn truncate(&mut self, len: usize) {
31+
self.data.truncate(len);
32+
}
33+
}
34+
35+
impl<T> Index<usize> for RingBuffer<T> {
36+
type Output = T;
37+
fn index(&self, index: usize) -> &Self::Output {
38+
&self.data[index.checked_sub(self.offset).unwrap()]
39+
}
40+
}
41+
42+
impl<T> IndexMut<usize> for RingBuffer<T> {
43+
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
44+
&mut self.data[index.checked_sub(self.offset).unwrap()]
45+
}
46+
}

0 commit comments

Comments
 (0)