Skip to content

Commit 225749b

Browse files
committed
Simplify API surface
1 parent 0e77eca commit 225749b

4 files changed

Lines changed: 47 additions & 62 deletions

File tree

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,20 @@ import (
3333
)
3434

3535
func main() {
36-
rc := ringchan.New[string](3)
36+
input := make(chan string, 5)
37+
ring := ringchan.New(input, 3)
3738

3839
go func() {
3940
inputs := []string{"A", "B", "C", "D", "E"}
4041
for _, v := range inputs {
41-
rc.In <- v
42+
input <- v
4243
}
43-
rc.Close()
44+
close(input)
4445
}()
4546

4647
time.Sleep(50 * time.Millisecond)
4748

48-
for v := range rc.Out {
49+
for v := range ring.C {
4950
fmt.Println("Got:", v)
5051
}
5152

example_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,20 @@ import (
88
)
99

1010
func ExampleNew() {
11-
rc := ringchan.New[string](3)
11+
input := make(chan string, 5)
12+
ring := ringchan.New(input, 3)
1213

1314
go func() {
1415
inputs := []string{"A", "B", "C", "D", "E"}
1516
for _, v := range inputs {
16-
rc.In <- v
17+
input <- v
1718
}
18-
rc.Close()
19+
close(input)
1920
}()
2021

2122
time.Sleep(50 * time.Millisecond)
2223

23-
for v := range rc.Out {
24+
for v := range ring.C {
2425
fmt.Println("Got:", v)
2526
}
2627

ringchan.go

Lines changed: 20 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,37 @@
11
package ringchan
22

33
type Ring[T any] struct {
4-
in chan T
5-
out chan T
6-
7-
// In is the channel to send values to.
8-
In chan<- T
9-
// Out is the channel to receive values from.
10-
Out <-chan T
4+
// C is the channel to receive values from.
5+
C <-chan T
116
}
127

13-
// New creates a ring-buffered channel with fixed capacity.
8+
// New creates a ring-buffered channel with fixed capacity from incoming channel.
149
// When full, new inserts will drop the oldest items to make space.
15-
func New[T any](capacity int) *Ring[T] {
16-
in := make(chan T, capacity)
17-
out := make(chan T, capacity)
10+
func New[T any](in <-chan T, size int) *Ring[T] {
11+
out := make(chan T, size)
1812

1913
rc := &Ring[T]{
20-
in: in,
21-
out: out,
22-
In: in,
23-
Out: out,
14+
C: out,
2415
}
2516

26-
go rc.run()
27-
return rc
28-
}
17+
go func() {
18+
defer close(out)
2919

30-
func (rc *Ring[T]) run() {
31-
defer close(rc.out)
32-
33-
for v := range rc.in {
34-
select {
35-
case rc.out <- v:
36-
default:
37-
// Do non-blocking receive to drop the oldest item
38-
// if the buffer is full. This avoids blocking in case of an empty buffer.
20+
for v := range in {
3921
select {
40-
case <-rc.out:
41-
rc.out <- v
22+
case out <- v:
4223
default:
43-
rc.out <- v
24+
// Do non-blocking receive to drop the oldest item
25+
// if the buffer is full. This avoids blocking in case of an empty buffer.
26+
select {
27+
case <-out:
28+
out <- v
29+
default:
30+
out <- v
31+
}
4432
}
4533
}
46-
}
47-
}
48-
49-
// Len returns the number of items currently in the ring buffer.
50-
func (rc *Ring[T]) Len() int {
51-
return len(rc.out)
52-
}
34+
}()
5335

54-
// Close closes the input channel, ending the ring.
55-
func (rc *Ring[T]) Close() {
56-
close(rc.in)
36+
return rc
5737
}

ringchan_test.go

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,25 @@ import (
66
)
77

88
func TestRingChanBasic(t *testing.T) {
9-
rc := New[int](3)
9+
input := make(chan int, 5)
10+
rc := New(input, 3)
1011

1112
go func() {
1213
for i := 1; i <= 5; i++ {
13-
rc.In <- i
14+
input <- i
1415
}
15-
rc.Close()
16+
close(input)
1617
}()
1718

1819
time.Sleep(50 * time.Millisecond)
1920

20-
l := rc.Len()
21+
l := len(rc.C)
2122
if l != 3 {
2223
t.Fatalf("expected Len()=%v, got %v", 3, l)
2324
}
2425

2526
var got []int
26-
for v := range rc.Out {
27+
for v := range rc.C {
2728
got = append(got, v)
2829
}
2930

@@ -40,29 +41,31 @@ func TestRingChanBasic(t *testing.T) {
4041
}
4142

4243
func TestRingChanBlockingReceive(t *testing.T) {
43-
rc := New[int](1)
44+
input := make(chan int, 1)
45+
rc := New(input, 1)
4446

4547
go func() {
4648
time.Sleep(100 * time.Millisecond)
47-
rc.In <- 42
48-
rc.Close()
49+
input <- 42
50+
close(input)
4951
}()
5052

51-
val := <-rc.Out
53+
val := <-rc.C
5254
if val != 42 {
5355
t.Errorf("expected 42, got %v", val)
5456
}
5557
}
5658

5759
func TestRingChanRangeAfterClose(t *testing.T) {
58-
rc := New[string](2)
60+
input := make(chan string, 2)
61+
rc := New(input, 2)
5962

60-
rc.In <- "foo"
61-
rc.In <- "bar"
62-
rc.Close()
63+
input <- "foo"
64+
input <- "bar"
65+
close(input)
6366

6467
var results []string
65-
for v := range rc.Out {
68+
for v := range rc.C {
6669
results = append(results, v)
6770
}
6871

0 commit comments

Comments
 (0)