You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: Ring Buffer/README.markdown
+17-19Lines changed: 17 additions & 19 deletions
Original file line number
Diff line number
Diff line change
@@ -17,7 +17,7 @@ Initially, the array is empty and the read (`r`) and write (`w`) pointers are at
17
17
Let's add some data to this array. We'll write, or "enqueue", the number `123`:
18
18
19
19
[ 123, , , , ]
20
-
r
20
+
r
21
21
---> w
22
22
23
23
Each time we add data, the write pointer moves one step forward. Let's add a few more elements:
@@ -46,7 +46,7 @@ Whoops, the write pointer has reached the end of the array, so there is no more
46
46
[ 555, 456, 789, 666, 333 ]
47
47
---> w r
48
48
49
-
We can now read the remaining three items, `666`, `333`, and `555`.
49
+
We can now read the remaining three items, `666`, `333`, and `555`.
50
50
51
51
[ 555, 456, 789, 666, 333 ]
52
52
w --------> r
@@ -63,16 +63,15 @@ Here is a very basic implementation in Swift:
63
63
64
64
```swift
65
65
publicstructRingBuffer<T> {
66
-
privatevar array: [T?]
67
-
privatevar readIndex =0
68
-
privatevar writeIndex =0
69
-
66
+
fileprivatevar array: [T?]
67
+
fileprivatevar readIndex =0
68
+
fileprivatevar writeIndex =0
69
+
70
70
publicinit(count: Int) {
71
-
array = [T?](count: count, repeatedValue: nil)
71
+
array = [T?](repeating: nil, count: count)
72
72
}
73
-
74
-
/* Returns false if out of space. */
75
-
publicmutatingfuncwrite(element: T) ->Bool {
73
+
74
+
publicmutatingfuncwrite(_element: T) ->Bool {
76
75
if!isFull {
77
76
array[writeIndex % array.count] = element
78
77
writeIndex +=1
@@ -81,8 +80,7 @@ public struct RingBuffer<T> {
81
80
returnfalse
82
81
}
83
82
}
84
-
85
-
/* Returns nil if the buffer is empty. */
83
+
86
84
publicmutatingfuncread() -> T? {
87
85
if!isEmpty {
88
86
let element = array[readIndex % array.count]
@@ -92,19 +90,19 @@ public struct RingBuffer<T> {
92
90
returnnil
93
91
}
94
92
}
95
-
96
-
privatevar availableSpaceForReading: Int {
93
+
94
+
fileprivatevar availableSpaceForReading: Int {
97
95
return writeIndex - readIndex
98
96
}
99
-
97
+
100
98
publicvar isEmpty: Bool {
101
99
return availableSpaceForReading ==0
102
100
}
103
-
104
-
privatevar availableSpaceForWriting: Int {
101
+
102
+
fileprivatevar availableSpaceForWriting: Int {
105
103
return array.count- availableSpaceForReading
106
104
}
107
-
105
+
108
106
publicvar isFull: Bool {
109
107
return availableSpaceForWriting ==0
110
108
}
@@ -130,7 +128,7 @@ In other words, we take the modulo (or the remainder) of the read index and writ
130
128
The reason this is a bit controversial is that `writeIndex` and `readIndex` always increment, so in theory these values could become too large to fit into an integer and the app will crash. However, a quick back-of-the-napkin calculation should take away those fears.
131
129
132
130
Both `writeIndex` and `readIndex` are 64-bit integers. If we assume that they are incremented 1000 times per second, which is a lot, then doing this continuously for one year requires `ceil(log_2(365 * 24 * 60 * 60 * 1000)) = 35` bits. That leaves 28 bits to spare, so that should give you about 2^28 years before running into problems. That's a long time. :-)
133
-
131
+
134
132
To play with this ring buffer, copy the code to a playground and do the following to mimic the example above:
0 commit comments