SkipList.st
author Claus Gittinger <cg@exept.de>
Tue, 25 Jun 2019 14:28:51 +0200
changeset 5050 44fa8672d102
parent 4396 e84a571deedd
permissions -rw-r--r--
#DOCUMENTATION by cg class: SharedQueue comment/format in: #next #nextWithTimeout:
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4396
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     1
"{ Package: 'stx:libbasic2' }"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
"{ NameSpace: Smalltalk }"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
Collection subclass:#SkipList
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	instanceVariableNames:'sortBlock pointers numElements level splice'
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	classVariableNames:'Rand'
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
	poolDictionaries:''
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
	category:'Collections-Ordered-Trees'
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
SkipList comment:'From "Skip Lists: A Probabilistic Alternative to Balanced Trees" by William Pugh ( http://epaperpress.com/sortsearch/download/skiplist.pdf ):
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    14
"Skip lists are a data structure that can be used in place of balanced trees.  Skip lists use probabilistic balancing rather than strictly enforcing balancing and as a result the algorithms for insertion and deletion in skip lists are much simpler and significantly faster than equivalent algorithms for balanced trees."
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    15
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    16
Notes:
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    17
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
The elements of the skip list must implement #< or you must provide a sort block.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
'
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    21
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    22
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    23
!SkipList class methodsFor:'documentation'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    24
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    25
documentation
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    26
"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    27
    From 'Skip Lists: A Probabilistic Alternative to Balanced Trees' by William Pugh 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    28
    ( http://epaperpress.com/sortsearch/download/skiplist.pdf ):
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
    Skip lists are a data structure that can be used in place of balanced trees.  
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    31
    Skip lists use probabilistic balancing rather than strictly enforcing balancing 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    32
    and as a result the algorithms for insertion and deletion in skip lists are much simpler 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
    and significantly faster than equivalent algorithms for balanced trees.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
    Notes:
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    36
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    37
    The elements of the skip list must implement #< or you must provide a sort block.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    39
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    40
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    41
!SkipList class methodsFor:'instance creation'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    42
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    43
maxLevel: maxLevel
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    44
	"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    45
	SkipList maxLevel: 5
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    46
	"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
	^ super new initialize: maxLevel
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
maxLevel: anInteger sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
	^ (self maxLevel: anInteger) sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
new
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
	"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
	SkipList new
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
	"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
	^ super new initialize: 10
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
new: anInteger
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
	^ self maxLevel: (anInteger log: 2) ceiling
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
new: anInteger sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
	^ (self new: anInteger) sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    69
sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
	^ self new sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
!SkipList methodsFor:'accessing'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    74
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    75
level
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
	^ level
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
maxLevel
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
	^ pointers size
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
maxLevel: n
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
        | newLevel oldPointers |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
        newLevel := n max:level.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
        oldPointers := pointers.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
        pointers := Array new:newLevel.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
        splice := Array new:newLevel.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
        1 to: level do: [:i | pointers at: i put: (oldPointers at: i)]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
    "Modified (format): / 18-06-2017 / 17:42:51 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
size
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
	^ numElements
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
sortBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    99
	^ sortBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
sortBlock: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
        sortBlock := aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
    "Modified (format): / 18-06-2017 / 17:44:44 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
!SkipList methodsFor:'adding'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
add: element 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
	self add: element ifPresent: nil.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
	^ element
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
add: element ifPresent: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
        | node lvl s |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
        node := self search:element updating:splice.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   118
        node notNil ifTrue: [aBlock notNil ifTrue: [^ aBlock value: node]].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
        lvl := self randomLevel.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
        node := SkipListNode on:element level:lvl.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
        level + 1 to: lvl do: [:i | splice at: i put: self].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
        1 to: lvl do: [:i |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   123
                                s := splice at:i.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   124
                                node atForward: i put: (s forward: i).
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   125
                                s atForward: i put: node].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   126
        numElements := numElements + 1.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
        splice atAllPut: nil.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
        ^ element
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   129
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
    "Modified: / 18-06-2017 / 17:32:23 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
!SkipList methodsFor:'element comparison'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
is: element1 equalTo: element2
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   136
	^ element1 = element2
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   137
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   138
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   139
!SkipList methodsFor:'enumerating'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   140
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   141
do: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   142
	self nodesDo: [:node | aBlock value: node object]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   143
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   144
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   145
!SkipList methodsFor:'initialization'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   146
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
initialize: maxLevel
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   148
        pointers := Array new:maxLevel.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
        splice := Array new:maxLevel.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   150
        numElements := 0.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
        level := 0.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   152
        Rand ifNil: [Rand := RandomGenerator new]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   153
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   154
    "Modified: / 18-06-2017 / 17:40:56 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   155
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   156
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   157
!SkipList methodsFor:'node enumeration'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   158
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   159
nodesDo: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   160
        | node |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   161
        node := pointers first.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   162
        [node notNil]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   163
                whileTrue:
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   164
                        [aBlock value: node.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   165
                        node := node next]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   166
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   167
    "Modified (format): / 18-06-2017 / 17:31:41 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   168
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   169
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   170
!SkipList methodsFor:'private'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   171
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   172
atForward: i put: node
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   173
        level := node
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   174
                ifNil: [pointers findLast: [:n | n notNil]]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   175
                ifNotNil: [level max: i].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   176
        ^ pointers at: i put: node
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   177
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   178
    "Modified (format): / 18-06-2017 / 17:32:30 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   179
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   180
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   181
forward: i 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   182
	^ pointers at: i
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   183
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   184
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   185
is: node before: element 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   186
        | object |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   187
        node isNil ifTrue: [^ false].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   188
        object := node object.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   189
        ^ sortBlock isNil 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   190
            ifTrue: [object < element]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   191
            ifFalse: [
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   192
                (self is: object equalTo: element) 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   193
                    ifTrue: [ false]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   194
                    ifFalse:[ sortBlock value: object value: element ]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   195
            ]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   196
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   197
    "Modified: / 18-06-2017 / 17:42:31 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   198
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   199
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   200
is: node theNodeFor: element 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   201
        node isNil ifTrue: [^ false].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   202
        node == self ifTrue: [^ false].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   203
        ^ self is: node object equalTo: element
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   204
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   205
    "Modified: / 18-06-2017 / 17:42:42 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   206
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   207
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   208
next
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   209
	^ pointers first
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   210
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   211
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   212
randomLevel
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   213
        | p answer max |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   214
        p := 0.5.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   215
        answer := 1.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   216
        max := self maxLevel.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   217
        [Rand next < p and: [answer < max]]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   218
                whileTrue: [answer := answer + 1].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   219
        ^ answer
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   220
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   221
    "Modified (format): / 18-06-2017 / 17:42:59 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   222
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   223
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   224
search: element updating: array
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   225
        | node forward |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   226
        node := self.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   227
        level to: 1 by: -1 do: [:i |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   228
                        [forward := node forward: i.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   229
                        self is: forward before: element] whileTrue: [node := forward].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   230
                        "At this point: node < element <= forward"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   231
                        array ifNotNil: [array at: i put: node]].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   232
        node := node next.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   233
        ^ (self is: node theNodeFor: element) 
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   234
                ifTrue: [node]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   235
                ifFalse:[nil]
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   236
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   237
    "Modified: / 18-06-2017 / 17:44:37 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   238
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   239
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   240
!SkipList methodsFor:'removing'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   241
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   242
remove: element ifAbsent: aBlock
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   243
        | node i s |
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   244
        node := self search:element updating:splice.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   245
        node isNil ifTrue:[
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   246
              ^ aBlock value
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   247
        ].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   248
        i := 1.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   249
        [s := splice at:i.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   250
        i <= level and: [(s forward: i) == node]] whileTrue: [
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   251
            s atForward: i put: (node forward: i).
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   252
            i := i + 1
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   253
        ].
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   254
        numElements := numElements - 1.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   255
        splice atAllPut: nil.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   256
        ^ node object
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   257
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   258
    "Modified (format): / 18-06-2017 / 17:43:30 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   259
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   260
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   261
removeAll
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   262
        pointers atAllPut: nil.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   263
        splice atAllPut: nil.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   264
        numElements := 0.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   265
        level := 0.
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   266
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   267
    "Modified (format): / 18-06-2017 / 17:43:39 / cg"
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   268
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   269
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   270
!SkipList methodsFor:'testing'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   271
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   272
includes: element
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   273
	^ (self search: element updating: nil) notNil
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   274
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   275
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   276
isEmpty
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   277
	^ numElements = 0
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   278
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   279
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   280
!SkipList class methodsFor:'documentation'!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   281
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   282
version
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   283
    ^ '$Header$'
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   284
!
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   285
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   286
version_CVS
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   287
    ^ '$Header$'
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   288
! !
e84a571deedd initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   289