Commit 83940d7c authored by David Symonds's avatar David Symonds

Add a unique list ID to list elements, and verify it as necessary.

This makes the list closed under its provided operations.

R=rsc,gri
APPROVED=rsc
DELTA=18  (14 added, 0 deleted, 4 changed)
OCL=32388
CL=32395
parent 40a66ef5
...@@ -11,6 +11,9 @@ type Element struct { ...@@ -11,6 +11,9 @@ type Element struct {
// The front of the list has prev = nil, and the back has next = nil. // The front of the list has prev = nil, and the back has next = nil.
next, prev *Element; next, prev *Element;
// A unique ID for the list to which this element belongs.
id *byte;
// The contents of this list element. // The contents of this list element.
Value interface {}; Value interface {};
} }
...@@ -19,6 +22,7 @@ type Element struct { ...@@ -19,6 +22,7 @@ type Element struct {
type List struct { type List struct {
front, back *Element; front, back *Element;
len int; len int;
id *byte;
} }
// Init initializes or clears a List. // Init initializes or clears a List.
...@@ -26,6 +30,7 @@ func (l *List) Init() *List { ...@@ -26,6 +30,7 @@ func (l *List) Init() *List {
l.front = nil; l.front = nil;
l.back = nil; l.back = nil;
l.len = 0; l.len = 0;
l.id = new(byte);
return l return l
} }
...@@ -46,6 +51,9 @@ func (l *List) Back() *Element { ...@@ -46,6 +51,9 @@ func (l *List) Back() *Element {
// Remove removes the element from the list. // Remove removes the element from the list.
func (l *List) Remove(e *Element) { func (l *List) Remove(e *Element) {
if e.id != l.id {
return
}
if e.prev == nil { if e.prev == nil {
l.front = e.next; l.front = e.next;
} else { } else {
...@@ -88,21 +96,27 @@ func (l *List) insertBack(e *Element) { ...@@ -88,21 +96,27 @@ func (l *List) insertBack(e *Element) {
// PushFront inserts the value at the front of the list, and returns a new Element containing it. // PushFront inserts the value at the front of the list, and returns a new Element containing it.
func (l *List) PushFront(value interface {}) *Element { func (l *List) PushFront(value interface {}) *Element {
e := &Element{ nil, nil, value }; if l.id == nil {
l.Init();
}
e := &Element{ nil, nil, l.id, value };
l.insertFront(e); l.insertFront(e);
return e return e
} }
// PushBack inserts the value at the back of the list, and returns a new Element containing it. // PushBack inserts the value at the back of the list, and returns a new Element containing it.
func (l *List) PushBack(value interface {}) *Element { func (l *List) PushBack(value interface {}) *Element {
e := &Element{ nil, nil, value }; if l.id == nil {
l.Init();
}
e := &Element{ nil, nil, l.id, value };
l.insertBack(e); l.insertBack(e);
return e return e
} }
// MoveToFront moves the element to the front of the list. // MoveToFront moves the element to the front of the list.
func (l *List) MoveToFront(e *Element) { func (l *List) MoveToFront(e *Element) {
if l.front == e { if e.id != l.id || l.front == e {
return return
} }
l.Remove(e); l.Remove(e);
...@@ -111,7 +125,7 @@ func (l *List) MoveToFront(e *Element) { ...@@ -111,7 +125,7 @@ func (l *List) MoveToFront(e *Element) {
// MoveToBack moves the element to the back of the list. // MoveToBack moves the element to the back of the list.
func (l *List) MoveToBack(e *Element) { func (l *List) MoveToBack(e *Element) {
if l.back == e { if e.id != l.id || l.back == e {
return return
} }
l.Remove(e); l.Remove(e);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment