implemented more methods for OrderedCollection

This commit is contained in:
hyunghwan.chung 2018-05-24 10:10:52 +00:00
parent 29a5f0716d
commit 90e6e6c8cf
3 changed files with 120 additions and 23 deletions

View File

@ -60,10 +60,30 @@ class Collection(Object)
^coll ^coll
} }
*) *)
method emptyCheck
{
if (self size <= 0) { Exception signal: 'empty collection' }.
}
} }
## ------------------------------------------------------------------------------- ## -------------------------------------------------------------------------------
class(#pointer) Array(Collection) class SequenceableCollection(Collection)
{
method do: aBlock
{
0 to: (self size - 1) do: [:i | aBlock value: (self at: i)].
}
method reverseDo: aBlock
{
(self size - 1) to: 0 by: -1 do: [:i | aBlock value: (self at: i)].
}
}
## -------------------------------------------------------------------------------
class(#pointer) Array(SequenceableCollection)
{ {
method size method size
{ {
@ -90,10 +110,7 @@ class(#pointer) Array(Collection)
^self at: (self size - 1). ^self at: (self size - 1).
} }
method do: aBlock
{
0 priorTo: (self size) do: [:i | aBlock value: (self at: i)].
}
method copy: anArray method copy: anArray
{ {
@ -143,6 +160,23 @@ class(#pointer) Array(Collection)
^(self class new: newsz) copy: self from: start to: end ^(self class new: newsz) copy: self from: start to: end
} }
method replaceFrom: start to: stop with: replacement
{
self replaceFrom: start to: stop with: replacement startingAt: 0.
}
method replaceFrom: start to: stop with: replacement startingAt: rstart
{
| offset i |
offset := rstart - start.
i := start.
while (i <= stop)
{
self at: i put: (replacement at: i + offset).
i := i + 1.
}.
}
method = anArray method = anArray
{ {
| size i | | size i |
@ -254,15 +288,12 @@ class(#byte) ByteArray(Array)
} }
## ------------------------------------------------------------------------------- ## -------------------------------------------------------------------------------
class SequenceableCollection(Collection)
{
}
class OrderedCollection(SequenceableCollection) class OrderedCollection(SequenceableCollection)
{ {
var contents. var contents.
var firstIndex. var firstIndex.
var lastIndex. var lastIndex. ## this is the last index plus 1.
method(#class) new method(#class) new
{ {
@ -271,47 +302,57 @@ class OrderedCollection(SequenceableCollection)
method(#class) new: size method(#class) new: size
{ {
^super _basicNew initialize: size. ^self _basicNew initialize: size.
} }
method initialize: size method initialize: size
{ {
self.contents := Array new: size. self.contents := Array new: size.
self.firstIndex := size // 2 max: 1. self.firstIndex := size div: 2.
self.lastIndex := self.firstIndex - 1. self.lastIndex := self.firstIndex.
} }
method size method size
{ {
^self.lastIndex - self.firstIndex + 1. ^self.lastIndex - self.firstIndex.
} }
method at: index method at: index
{ {
| i | | i |
i := index + self.firstIndex - 1. i := index + self.firstIndex.
if (i >= self.firstIndex and: [i <= self.lastIndex]) { ^self.contents at: index }. if (i >= self.firstIndex and: [i < self.lastIndex]) { ^self.contents at: index }.
Exception signal: ('index ' & index asString & ' out of range'). Exception signal: ('index ' & index asString & ' out of range').
} }
method at: index put: obj method at: index put: obj
{ {
| i | | i |
i := index + self.firstIndex - 1. i := index + self.firstIndex.
if (i >= self.firstIndex and: [i <= self.lastIndex]) { ^self.contents at: index put: obj }. if (i >= self.firstIndex and: [i < self.lastIndex]) { ^self.contents at: index put: obj }.
Exception signal: ('index ' & index asString & ' out of range'). Exception signal: ('index ' & index asString & ' out of range').
} }
method addFirst: obj method addFirst: obj
{ {
if (self.firstIndex == 0) { self growBy: 8 shiftBy: 8 }.
self.firstIndex := self.firstIndex - 1.
^self.contents at: self.firstIndex put: obj.
} }
method addLast: obj method addLast: obj
{ {
| k |
if (self.lastIndex == self.contents size) { self growBy: 8 shiftBy: 0 }.
k := self.contents at: self.lastIndex put: obj.
self.lastIndex := self.lastIndex + 1.
^k.
} }
method add: obj beforeIndex: index method add: obj beforeIndex: index
{ {
self insert: obj beforeIndex: index.
^obj
} }
method add: obj afterIndex: index method add: obj afterIndex: index
@ -321,20 +362,75 @@ class OrderedCollection(SequenceableCollection)
method removeFirst method removeFirst
{ {
| obj |
self emptyCheck.
obj := self.contents at: self.firstIndex.
self.contents at: self.firstIndex put: nil.
self.firstIndex := self.firstIndex + 1.
^obj.
} }
method removeLast method removeLast
{ {
| obj li |
self emptyCheck.
li := self.lastIndex - 1.
obj := self.contents at: li.
self.contents at: li put: nil.
self.lastIndex := li.
^obj
}
method removeIndex: index
{
| obj |
obj := self at: index.
self.contents replaceFrom: index + self.firstIndex
to: self.lastIndex - 2
with: self.contents
startingAt: index + self.firstIndex + 1.
self.lastIndex := self.lastIndex - 1.
self.contents at: self.lastIndex put: nil.
System log(System.Log.FATAL, S'REMOVING ... ', obj, '--->', self.lastIndex, S'\n').
^obj
} }
method remove: obj ifAbsent: error_block method remove: obj ifAbsent: error_block
{ {
} }
method growBy: size ## ------------------------------------------------
## ENUMERATING
## ------------------------------------------------
method do: block
{ {
##^self.firstIndex to: (self.lastIndex - 1) do: [:i | block value: (self.contents at: i)].
| i |
i := self.firstIndex.
while (i < self.lastIndex)
{
block value: (self.contents at: i).
i := i + 1.
}.
}
## ------------------------------------------------
## PRIVATE METHODS
## ------------------------------------------------
method growBy: grow_size shiftBy: shift_count
{
| newcon |
newcon := (self.contents class) new: (self.contents size + grow_size).
newcon replaceFrom: (self.firstIndex + shift_count)
to: (self.lastIndex - 1 + shift_count)
with: self.contents startingAt: (self.firstIndex).
self.contents := newcon.
self.firstIndex := self.firstIndex + shift_count.
self.lastIndex := self.lastIndex + shift_count.
} }
} }
## ------------------------------------------------------------------------------- ## -------------------------------------------------------------------------------
class Set(Collection) class Set(Collection)
@ -573,7 +669,6 @@ class Set(Collection)
^self removeKey: (assoc key) ifAbsent: error_block ^self removeKey: (assoc key) ifAbsent: error_block
} }
method do: block method do: block
{ {
| bs | | bs |

View File

@ -333,7 +333,7 @@ class SemaphoreHeap(Object)
method parentIndex: anIndex method parentIndex: anIndex
{ {
^(anIndex - 1) quo: 2 ^(anIndex - 1) div: 2
} }
method leftChildIndex: anIndex method leftChildIndex: anIndex
@ -384,7 +384,7 @@ class SemaphoreHeap(Object)
| base capa cindex item | base capa cindex item
left right younger xitem | left right younger xitem |
base := self.size quo: 2. base := self.size div: 2.
if (anIndex >= base) { ^anIndex }. if (anIndex >= base) { ^anIndex }.
cindex := anIndex. cindex := anIndex.

View File

@ -2127,10 +2127,12 @@ static void setup_tick (void)
act.sa_flags = SA_RESTART; act.sa_flags = SA_RESTART;
sigaction (SIGVTALRM, &act, MOO_NULL); sigaction (SIGVTALRM, &act, MOO_NULL);
/*#define MOO_ITIMER_TICK 10000*/ /* microseconds. 0.01 seconds */
#define MOO_ITIMER_TICK 20000 /* microseconds. 0.02 seconds. */
itv.it_interval.tv_sec = 0; itv.it_interval.tv_sec = 0;
itv.it_interval.tv_usec = 10000; /* microseconds */ itv.it_interval.tv_usec = MOO_ITIMER_TICK;
itv.it_value.tv_sec = 0; itv.it_value.tv_sec = 0;
itv.it_value.tv_usec = 10000; itv.it_value.tv_usec = MOO_ITIMER_TICK;
setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL); setitimer (ITIMER_VIRTUAL, &itv, MOO_NULL);
#else #else