Skip to content

Commit 7555d9e

Browse files
Merge pull request TheAlgorithms#166 from KyleScharnhorst/add-circular-buffer
Add: circular buffer implementation.
2 parents 1a9aa87 + 0ade40c commit 7555d9e

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import java.util.Random;
2+
import java.util.concurrent.atomic.AtomicInteger;
3+
4+
public class CircularBuffer {
5+
private char[] _buffer;
6+
public final int _buffer_size;
7+
private int _write_index = 0;
8+
private int _read_index = 0;
9+
private AtomicInteger _readable_data = new AtomicInteger(0);
10+
11+
public CircularBuffer(int buffer_size) {
12+
if(!IsPowerOfTwo(buffer_size)) {
13+
throw new IllegalArgumentException();
14+
}
15+
this._buffer_size = buffer_size;
16+
_buffer = new char[buffer_size];
17+
}
18+
19+
private boolean IsPowerOfTwo(int i) {
20+
return (i & (i - 1)) == 0;
21+
}
22+
23+
private int getTrueIndex(int i) {
24+
return i % _buffer_size;
25+
}
26+
27+
public Character readOutChar() {
28+
Character result = null;
29+
30+
//if we have data to read
31+
if(_readable_data.get() > 0) {
32+
result = new Character(_buffer[getTrueIndex(_read_index)]);
33+
_readable_data.decrementAndGet();
34+
_read_index++;
35+
}
36+
37+
return result;
38+
}
39+
40+
public boolean writeToCharBuffer(char c) {
41+
boolean result = false;
42+
43+
//if we can write to the buffer
44+
if(_readable_data.get() < _buffer_size) {
45+
//write to buffer
46+
_buffer[getTrueIndex(_write_index)] = c;
47+
_readable_data.incrementAndGet();
48+
_write_index++;
49+
result = true;
50+
}
51+
52+
return result;
53+
}
54+
55+
private static class TestWriteWorker implements Runnable {
56+
String _alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
57+
Random _random = new Random();
58+
CircularBuffer _buffer;
59+
public TestWriteWorker(CircularBuffer cb) {
60+
this._buffer = cb;
61+
}
62+
63+
private char getRandomChar() {
64+
return _alphabet.charAt(_random.nextInt(_alphabet.length()));
65+
}
66+
67+
public void run() {
68+
while(!Thread.interrupted()) {
69+
if(!_buffer.writeToCharBuffer(getRandomChar())){
70+
Thread.yield();
71+
try{
72+
Thread.sleep(10);
73+
} catch (InterruptedException e) {
74+
return;
75+
}
76+
}
77+
}
78+
}
79+
}
80+
81+
private static class TestReadWorker implements Runnable {
82+
CircularBuffer _buffer;
83+
public TestReadWorker(CircularBuffer cb) {
84+
this._buffer = cb;
85+
}
86+
87+
public void run() {
88+
System.out.println("Printing Buffer:");
89+
while(!Thread.interrupted()) {
90+
Character c = _buffer.readOutChar();
91+
if(c != null) {
92+
System.out.print(c.charValue());
93+
} else {
94+
Thread.yield();
95+
try {
96+
Thread.sleep(10);
97+
} catch (InterruptedException e) {
98+
System.out.println();
99+
return;
100+
}
101+
}
102+
}
103+
}
104+
}
105+
106+
public static void main(String[] args) throws InterruptedException {
107+
int buffer_size = 1024;
108+
//create circular buffer
109+
CircularBuffer cb = new CircularBuffer(buffer_size);
110+
111+
//create threads that read and write the buffer.
112+
Thread write_thread = new Thread(new TestWriteWorker(cb));
113+
Thread read_thread = new Thread(new TestReadWorker(cb));
114+
read_thread.start();
115+
write_thread.start();
116+
117+
//wait some amount of time
118+
Thread.sleep(10000);
119+
120+
//interrupt threads and exit
121+
write_thread.interrupt();
122+
read_thread.interrupt();
123+
}
124+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy