2008-03-05 09:52:00 -05:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// Microsoft Research Singularity
|
|
|
|
//
|
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
//
|
|
|
|
// File: VectorQueue.sg
|
|
|
|
//
|
|
|
|
// Note: File is part of Sing# runtime files and copied into Singularity tree
|
|
|
|
// whenever a new version of Sing# is dropped.
|
2008-11-17 18:29:00 -05:00
|
|
|
// Coordinate any changes with Sing# team.
|
2008-03-05 09:52:00 -05:00
|
|
|
//
|
|
|
|
|
|
|
|
using Microsoft.SingSharp;
|
|
|
|
|
2008-11-17 18:29:00 -05:00
|
|
|
namespace Microsoft.Singularity.Channels
|
|
|
|
{
|
2008-03-05 09:52:00 -05:00
|
|
|
|
|
|
|
public class VectorQueue<T> : ITracked where T:unmanaged struct {
|
|
|
|
|
|
|
|
private Node! listHead;
|
|
|
|
private Node! listTail;
|
|
|
|
|
|
|
|
public VectorQueue() {
|
|
|
|
Node node = this.listHead = new Node();
|
|
|
|
this.listTail = node;
|
|
|
|
base();
|
|
|
|
}
|
|
|
|
|
|
|
|
private class Node {
|
|
|
|
unsafe internal T[] in ExHeap data;
|
|
|
|
|
|
|
|
internal Node! next;
|
|
|
|
internal Node! prev;
|
|
|
|
|
|
|
|
internal Node() {
|
|
|
|
this.next = this;
|
|
|
|
this.prev = this;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal Node([Claims] T[]! in ExHeap arg) {
|
|
|
|
this.next = this;
|
|
|
|
this.prev = this;
|
|
|
|
this.data = arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal T[] in ExHeap Unlink() {
|
|
|
|
this.prev.next = this.next;
|
|
|
|
this.next.prev = this.prev;
|
|
|
|
this.next = this;
|
|
|
|
this.prev = this;
|
|
|
|
return this.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal void LinkAsNext([Claims] T[]! in ExHeap data) {
|
|
|
|
Node next = new Node(data);
|
|
|
|
next.next = this.next;
|
|
|
|
this.next = next;
|
|
|
|
next.prev = this;
|
|
|
|
next.next.prev = next;
|
|
|
|
}
|
|
|
|
|
|
|
|
internal void LinkAsPrev([Claims] T[]! in ExHeap data) {
|
|
|
|
Node prev = new Node(data);
|
|
|
|
prev.prev = this.prev;
|
|
|
|
this.prev = prev;
|
|
|
|
prev.next = this;
|
|
|
|
prev.prev.next = prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#region ITracked members
|
|
|
|
|
|
|
|
void ITracked.Release() {}
|
|
|
|
void ITracked.Acquire() {}
|
|
|
|
public void Dispose()
|
|
|
|
{
|
|
|
|
Node current = this.listHead.next;
|
|
|
|
while (current != this.listHead) {
|
|
|
|
// temporary hack until we fix the upcast in receiver context
|
|
|
|
unsafe {
|
|
|
|
T[] in ExHeap data = current.data;
|
|
|
|
delete data;
|
|
|
|
}
|
|
|
|
current = current.next;
|
|
|
|
}
|
|
|
|
this.listTail = this.listHead = new Node();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ITracked.Expose() {}
|
|
|
|
void ITracked.UnExpose() {}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
public void AddHead([Claims] T[]! in ExHeap data) {
|
|
|
|
this.listHead.LinkAsNext(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void AddTail([Claims] T[]! in ExHeap data) {
|
|
|
|
this.listTail.LinkAsPrev(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
public bool Empty { get { return this.listHead.next == this.listTail; } }
|
|
|
|
|
|
|
|
|
|
|
|
public T[] in ExHeap ExtractHead() {
|
|
|
|
if (this.Empty) return null;
|
|
|
|
Node candidate = this.listHead.next;
|
|
|
|
return candidate.Unlink();
|
|
|
|
}
|
|
|
|
|
|
|
|
public T[] in ExHeap ExtractTail() {
|
|
|
|
if (this.Empty) return null;
|
|
|
|
Node candidate = this.listTail.prev;
|
|
|
|
return candidate.Unlink();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|