github.com/kazu/loncha@v0.6.3/container_list/list.go (about) 1 // ListEntry is a base of http://golang.org/pkg/container/list/ 2 // this is tuning performancem, reduce heap usage. 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package list 8 9 import ( 10 "errors" 11 "unsafe" 12 13 "github.com/kazu/loncha/list_head" 14 ) 15 16 func New() (l *ListEntry) { 17 l = &ListEntry{} 18 l.Init() 19 return 20 } 21 22 func (d *ListEntry) Init() { 23 d.ListHead.Init() 24 } 25 26 // Next ... returns the next list element or nil. 27 func (d *ListEntry) Next() *ListEntry { 28 if d.ListHead.Next() == nil { 29 panic(errors.New("d.next is nil")) 30 } 31 return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(d.ListHead.Next())) - unsafe.Offsetof(d.ListHead))) 32 } 33 34 // Prev ... returns the previous list element or nil. 35 func (d *ListEntry) Prev() *ListEntry { 36 if d.ListHead.Next() == nil { 37 panic(errors.New("d.prev is nil")) 38 } 39 return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(d.ListHead.Prev())) - unsafe.Offsetof(d.ListHead))) 40 } 41 42 // NewListEntryList ... New returns an initialized list. 43 func NewListEntryList(h *ListEntry) *ListEntry { 44 h.Init() 45 return h 46 } 47 48 // Len ... size of list 49 func (d *ListEntry) Len() int { 50 return d.ListHead.Len() 51 } 52 53 // Add ... insert n after d 54 func (d *ListEntry) Add(n *ListEntry) *ListEntry { 55 d.ListHead.Add(&n.ListHead) 56 return n 57 } 58 59 // Delete ... delete d from linked-list 60 func (d *ListEntry) Delete() *ListEntry { 61 ptr := d.ListHead.Delete() 62 return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - unsafe.Offsetof(d.ListHead))) 63 } 64 65 // Remove ... Alias of Delete() 66 func (d *ListEntry) Remove() *ListEntry { 67 return d.Delete() 68 } 69 70 // ContainOf ... find same entry of ptr 71 func (d *ListEntry) ContainOf(ptr *list_head.ListHead) *ListEntry { 72 return (*ListEntry)(unsafe.Pointer(uintptr(unsafe.Pointer(ptr)) - unsafe.Offsetof(d.ListHead))) 73 } 74 75 // Front ... first value of ListEntry 76 func (d *ListEntry) Front() *ListEntry { 77 return d.ContainOf(d.ListHead.Front()) 78 } 79 80 // Back ... last entry of linked-list 81 func (d *ListEntry) Back() *ListEntry { 82 return d.ContainOf(d.ListHead.Back()) 83 } 84 85 // PushFront ... inserts a new value v at the front of list l and returns e. 86 func (d *ListEntry) PushFront(v *ListEntry) *ListEntry { 87 front := d.Front() 88 v.Add(front) 89 return v 90 } 91 92 // PushBack ... inserts a new element e with value v at the back of list l and returns e. 93 func (l *ListEntry) PushBack(v *ListEntry) *ListEntry { 94 last := l.Back() 95 last.Add(v) 96 return v 97 } 98 99 // InsertBefore inserts a new element e with value v immediately before mark and returns e. 100 // If mark is not an element of l, the list is not modified. 101 func (l *ListEntry) InsertBefore(v *ListEntry) *ListEntry { 102 l.Prev().Add(v) 103 return v 104 } 105 106 // InsertAfter ... inserts a new element e with value v immediately after mark and returns e. 107 // If mark is not an element of l, the list is not modified. 108 func (l *ListEntry) InsertAfter(v *ListEntry) *ListEntry { 109 l.Next().Add(v) 110 return v 111 } 112 113 // MoveToFront ... moves element e to the front of list l. 114 // If e is not an element of l, the list is not modified. 115 func (l *ListEntry) MoveToFront(v *ListEntry) *ListEntry { 116 v.Remove() 117 return l.PushFront(v) 118 } 119 120 // MoveToBack ... moves element e to later of list l. 121 // If e is not an element of l, the list is not modified. 122 func (l *ListEntry) MoveToBack(v *ListEntry) *ListEntry { 123 v.Remove() 124 return l.PushBack(v) 125 } 126 127 // MoveBefore ... moves element e to its new position before mark. 128 // If e or mark is not an element of l, or e == mark, the list is not modified. 129 func (l *ListEntry) MoveBefore(v *ListEntry) *ListEntry { 130 v.Remove() 131 l.Prev().Add(v) 132 return v 133 } 134 135 // MoveAfter ... moves element e to its new position after mark. 136 // If e is not an element of l, or e == mark, the list is not modified. 137 func (l *ListEntry) MoveAfter(v *ListEntry) *ListEntry { 138 v.Remove() 139 l.Add(v) 140 return v 141 } 142 143 func (l *ListEntry) PushBackList(other *ListEntry) { 144 l.Back().Add(other) 145 return 146 } 147 148 func (l *ListEntry) PushFrontList(other *ListEntry) { 149 other.PushBackList(l) 150 return 151 } 152 153 func (l *ListEntry) Each(fn func(e *ListEntry)) { 154 155 cur := l.Cursor() 156 157 for cur.Next() { 158 fn(l.ContainOf(cur.Pos)) 159 } 160 161 }