Skip to content

Instantly share code, notes, and snippets.

@tayloraswift
Created September 30, 2017 00:20
Show Gist options
  • Save tayloraswift/0860334278aeab5c1cbaefbefb050268 to your computer and use it in GitHub Desktop.
Save tayloraswift/0860334278aeab5c1cbaefbefb050268 to your computer and use it in GitHub Desktop.
struct QueueCore<Element>
{
// capacity always power of 2
private
var buffer:UnsafeMutableBufferPointer<Element> =
UnsafeMutableBufferPointer<Element>(start: nil, count: 0),
zero:Int = 0
public private(set)
var count:Int = 0
public
var capacity:Int
{
return self.buffer.count
}
private
func bufferPosition(of index:Int) -> Int
{
return (index + self.zero) & (self.capacity - 1)
}
public mutating
func enqueue(_ data:Element)
{
if self.count == self.capacity
{
let newCapacity:Int = max(8, self.capacity << 1),
newBuffer:UnsafeMutableBufferPointer<Element> =
UnsafeMutableBufferPointer<Element>.allocate(capacity: newCapacity)
newBuffer.moveInitialize(at: 0, from: self.buffer[self.zero... ])
newBuffer.moveInitialize(at: self.zero, from: self.buffer[0 ..< self.zero])
self.buffer.deallocate()
self.zero = 0
self.buffer = newBuffer
}
(self.buffer.baseAddress! + self.bufferPosition(of: self.count)).initialize(to: data)
self.count += 1
}
@discardableResult
public mutating
func dequeue() -> Element?
{
guard self.count > 0
else
{
return nil
}
let dequeued:Element = (self.buffer! + self.zero).move()
self.zero = self.bufferPosition(of: 1)
self.count -= 1
return dequeued
}
}
struct QueueCore<Element>
{
// capacity always power of 2
private
var buffer:UnsafeMutableBufferPointer<Element> =
UnsafeMutableBufferPointer<Element>(start: nil, count: 0),
zero:Int = 0
public private(set)
var count:Int = 0
public
var capacity:Int
{
return self.buffer.count
}
private
func bufferPosition(of index:Int) -> Int
{
return (index + self.zero) & (self.capacity - 1)
}
public mutating
func enqueue(_ data:Element)
{
if self.count == self.capacity
{
let newCapacity:Int = max(8, self.capacity << 1),
newBuffer:UnsafeMutableBufferPointer<Element> =
UnsafeMutableBufferPointer<Element>.allocate(capacity: newCapacity)
newBuffer[0... ].moveInitialize(from: self.buffer[self.zero... ])
newBuffer[self.zero ... self.zero << 1].moveInitialize(from: self.buffer[0 ..< self.zero])
self.buffer.deallocate()
self.zero = 0
self.buffer = newBuffer
}
(self.buffer.baseAddress! + self.bufferPosition(of: self.count)).initialize(to: data)
self.count += 1
}
@discardableResult
public mutating
func dequeue() -> Element?
{
guard self.count > 0
else
{
return nil
}
let dequeued:Element = (self.buffer! + self.zero).move()
self.zero = self.bufferPosition(of: 1)
self.count -= 1
return dequeued
}
}
struct QueueCore<Element>
{
private
var buffer:UnsafeMutablePointer<Element>? = nil,
zero:Int = 0
public private(set)
var capacity:Int = 0, // capacity always power of 2
count:Int = 0
private
func bufferPosition(of index:Int) -> Int
{
return (index + self.zero) & (self.capacity - 1)
}
public mutating
func enqueue(_ data:Element)
{
if self.count == self.capacity
{
let newCapacity:Int = max(8, self.capacity << 1),
newBuffer:UnsafeMutablePointer<Element> =
UnsafeMutablePointer<Element>.allocate(capacity: newCapacity)
if let buffer:UnsafeMutablePointer<Element> = self.buffer
{
newBuffer .moveInitialize( from: buffer + self.zero,
count: self.capacity - self.zero)
(newBuffer + self.zero).moveInitialize( from: buffer,
count: self.zero)
buffer.deallocate(capacity: self.capacity)
}
self.zero = 0
self.buffer = newBuffer
self.capacity = newCapacity
}
(self.buffer! + self.bufferPosition(of: self.count)).initialize(to: data)
self.count += 1
}
@discardableResult
public mutating
func dequeue() -> Element?
{
guard self.count > 0
else
{
return nil
}
let dequeued:Element = (self.buffer! + self.zero).move()
self.zero = self.bufferPosition(of: 1)
self.count -= 1
return dequeued
}
}
class TestElement
{
private static
var instances:Int = 0
private
var id:Int
init()
{
self.id = TestElement.instances
TestElement.instances += 1
print("created instance \(self.id)")
}
deinit
{
print("deleted instance \(self.id)")
TestElement.instances -= 1
}
}
var q:QueueCore<TestElement> = QueueCore<TestElement>()
for _ in 0 ..< 89
{
q.enqueue(TestElement())
}
for _ in 0 ..< 89
{
q.dequeue()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment