Skip to content

Commit

Permalink
implementation complete,added working tests
Browse files Browse the repository at this point in the history
  • Loading branch information
BazookaMusic committed Mar 30, 2019
1 parent 86f305b commit bbb2ccf
Show file tree
Hide file tree
Showing 9 changed files with 474 additions and 355 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.vscode
21 changes: 21 additions & 0 deletions debug.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package main

import "fmt"

// just prints the skiplist
func skiplist_debug(a *skiplist) {
level := a.n_levels - 1
finger := a.head

for ; level >= 0; level-- {
counter := 0
if finger.next[level] == nil {
fmt.Print(nil)
}
for node := finger.next[level]; node != nil; node = node.next[level] {
counter++
fmt.Print(" ", node.value)
}
fmt.Println(" nil", counter)
}
}
30 changes: 30 additions & 0 deletions rand_func.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"math/rand"
"time"
)

const Mask = ((1 << SKIPLIST_MAX_LEVEL) - 1)

func coin_tosses(prob float64, max_levels int) (counter int) {
t1 := time.Now()

counter = 1

res_mask := rand.Uint64() & Mask
// find first zero in float representation
for ; res_mask&1 == 0; res_mask >>= 1 {
counter++
}

//res := rand.Float64()
//for res < prob {
// res = rand.Float64()
// counter++
//}

randtime += time.Now().Sub(t1)
return counter

}
Binary file modified skiplist
Binary file not shown.
143 changes: 35 additions & 108 deletions skiplist.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ package main

import (
"fmt"
"math/rand"
"sync"
"time"
)

Expand All @@ -30,7 +28,6 @@ func (initial *skiplist) Init_skiplist(prob float64, max_levels int) {
initial.max_levels = max_levels

var head *skiplist_node = new(skiplist_node)
head.value = -1
head.fully_linked = true
head.marked = false

Expand All @@ -56,11 +53,11 @@ func debug(a skiplist) {
}
}

func (list *skiplist) ToSortedArray() []int {
func (list *skiplist) ToSortedArray() []interface{} {
/* make a sorted array out of the skiplist
returns the lowest level */
arr := make([]int, list.n_elements, list.n_elements)
fmt.Println(list.n_elements)
arr := make([]interface{}, list.n_elements, list.n_elements)
//fmt.Println(list.n_elements)
counter := 0
for current_node := list.head.next[0]; current_node != nil; current_node = current_node.next[0] {
arr[counter] = current_node.value
Expand All @@ -74,16 +71,18 @@ func (list *skiplist) ToSortedArray() []int {

}

func (head *skiplist) Find(val int, prev, next []*skiplist_node) (found_level int) {
func (head *skiplist) Find(val interface{}, prev, next []*skiplist_node) (found_level int) {
/* Find where the element should be
and return the first level where it was found and
next and previous elements for every level.
Returns -1 when not found */
Returns the first level where it was found or
-1 when not found */

// could be modified by inserts
head.lock.Lock()
level := head.n_levels - 1
head.lock.Unlock()
// much faster than starting at max

pred := head.head
found_level = -1
Expand All @@ -93,13 +92,13 @@ func (head *skiplist) Find(val int, prev, next []*skiplist_node) (found_level in
for ; level >= 0; level-- {
// horizontally
curr = pred.next[level]
for curr != nil && curr.value < val {
for curr != nil && Less(curr.value, val) {
pred = curr
curr = pred.next[level]
}

// next of where it should be
if curr != nil && curr.value == val && found_level == -1 {
if curr != nil && Equals(curr.value, val) && found_level == -1 {
found_level = level
}

Expand All @@ -112,7 +111,7 @@ func (head *skiplist) Find(val int, prev, next []*skiplist_node) (found_level in
return found_level
}

func (head *skiplist) Contains(val int) bool {
func (head *skiplist) Contains(val interface{}) bool {
/* same function as find but returns
as soon as item is found, ignoring below levels
and does not return prev,next */
Expand All @@ -127,14 +126,14 @@ func (head *skiplist) Contains(val int) bool {
for ; level >= 0; level-- {
// horizontally
curr = pred.next[level]
for curr != nil && curr.value < val {
for curr != nil && Less(curr.value, val) {
pred = curr
curr = pred.next[level]
}
//found something or have to go down

// is the next element what I seek
if curr != nil && curr.value == val {
if curr != nil && Equals(curr.value, val) {
node := curr
return node.fully_linked && !node.marked
}
Expand All @@ -143,7 +142,7 @@ func (head *skiplist) Contains(val int) bool {
return false
}

func (head *skiplist) Insert(v int) bool {
func (head *skiplist) Insert(v interface{}) bool {

// highest level of insertion
top_level := coin_tosses(head.prob, head.max_levels)
Expand All @@ -155,11 +154,12 @@ func (head *skiplist) Insert(v int) bool {
}
head.lock.Unlock()

for {
// buffers to store prev and next pointers
var prev, next []*skiplist_node
prev = make([]*skiplist_node, SKIPLIST_MAX_LEVEL)
next = make([]*skiplist_node, SKIPLIST_MAX_LEVEL)

var prev, next []*skiplist_node
prev = make([]*skiplist_node, SKIPLIST_MAX_LEVEL)
next = make([]*skiplist_node, SKIPLIST_MAX_LEVEL)
for {

// find insertion point and previous and next nodes
found_level := head.Find(v, prev, next)
Expand Down Expand Up @@ -206,19 +206,20 @@ func (head *skiplist) Insert(v int) bool {
}

// can the insertion proceed
// node is locked so we can check next
valid = !pred.marked && (succ == nil || !succ.marked) && pred.next[level] == succ
}

// cannot add
if !valid {
// unlock to try again
var _prevPred *skiplist_node = nil
prevPred = nil
for i := highest_locked; i >= 0; i-- {
//fmt.Println("Unlocking", i, prev[i].value)
if _prevPred != prev[i] {
if prevPred != prev[i] {
prev[i].mux.Unlock()
}
_prevPred = prev[i]
prevPred = prev[i]

}
// restart attempt
Expand All @@ -238,21 +239,17 @@ func (head *skiplist) Insert(v int) bool {
}
// new node is ok
newNode.fully_linked = true
//fmt.Println("highest locked", highest_locked)

//unlock
prevPred = nil
for i := highest_locked; i >= 0; i-- {
//fmt.Println("Unlocking", i, prev[i].value)
if prevPred != prev[i] {
prev[i].mux.Unlock()
}
prevPred = prev[i]

}

//fmt.Println(head.Len())

head.lock.Lock()
head.n_elements = head.n_elements + 1
head.lock.Unlock()
Expand All @@ -262,7 +259,7 @@ func (head *skiplist) Insert(v int) bool {

}

func (head *skiplist) Remove(val int) bool {
func (head *skiplist) Remove(val interface{}) bool {
/* remove node */

var nodeToDelete *skiplist_node = nil
Expand All @@ -272,7 +269,6 @@ func (head *skiplist) Remove(val int) bool {
var prev, next [SKIPLIST_MAX_LEVEL]*skiplist_node

for {
//fmt.Println("looping")
// try to find node
found_level := head.Find(val, prev[:], next[:])
//fmt.Println("level", found_level)
Expand Down Expand Up @@ -323,6 +319,17 @@ func (head *skiplist) Remove(val int) bool {

// can't delete try again
if !valid {

// unlock to try again
prevPred = nil
for i := highest_locked; i >= 0; i-- {
//fmt.Println("Unlocking", i, prev[i].value)
if prevPred != prev[i] {
prev[i].mux.Unlock()
}
prevPred = prev[i]
}

continue
}
// actually delete node
Expand Down Expand Up @@ -354,90 +361,10 @@ func (head *skiplist) Remove(val int) bool {
}
}

//
func CanDelete(candidate *skiplist_node, found_level int) bool {
fmt.Println("aaa", candidate.fully_linked, candidate.top_level, found_level, candidate.marked)
//fmt.Println("aaa", candidate.fully_linked, candidate.top_level, found_level, candidate.marked)
return candidate.fully_linked && candidate.top_level == found_level && !candidate.marked
}

func coin_tosses(prob float64, max_levels int) int {
t1 := time.Now()

var counter int = 1

/*
res_mask := math.Float64bits(rand.Float64()) & ((1 << SKIPLIST_MAX_LEVEL) - 1)
// find first zero in float representation
for ; res_mask&1 == 0; res_mask >>= 1 {
counter++
}
*/

res := rand.Float64()
for res < prob {
res = rand.Float64()
counter++
}

randtime += time.Now().Sub(t1)
return counter

}

func eval_sort(arr []int) {
if len(arr) == 0 {
return
}
prev := arr[0]
for index := 1; index < len(arr); index++ {
if arr[index] < prev {
fmt.Println(prev, arr[index], index)
}
prev = arr[index]
}

fmt.Println(len(arr))
}

func (head *skiplist) Inserter(v int, wg *sync.WaitGroup) {
for index := v; index < (v+1)*2500000; index++ {
head.Insert(index)
}
defer wg.Done()

}

func (head *skiplist) Remover(v int, wg *sync.WaitGroup) {
head.Remove(v)
defer wg.Done()

}

func main() {
start := time.Now()
rand.Seed(time.Now().UTC().UnixNano())

var head *skiplist = new(skiplist)
head.Init_skiplist(0.5, 20)

var arr []int = make([]int, 10000000)
var wg sync.WaitGroup
wg.Add(1)
for index := 0; index < 1; index++ {
go head.Inserter(index, &wg)
arr[index] = index
}

wg.Wait()

sorted := head.ToSortedArray()
eval_sort(sorted)

t := time.Now()
elapsed := t.Sub(start)
fmt.Println(elapsed)
fmt.Println(randtime)
//debug(*head)

//debug(head)
}
Loading

0 comments on commit bbb2ccf

Please sign in to comment.