This is the second try.
This is a test for the page length and check two types of walking through the items on the structure, the peek() function and the iterator object. The iterator object prepared inside a method of the object superstack. The iterator is an object which defined using the Group statement. Because we want to fill the group with values, the Group statement has code which see the variables of the function. Also we want the iterator to iterate each time we read it as a value. So this group has a value { } block which tell to interpreter that this group return value through this hidden function. This group has two properties (read only), the index (we get the current index of the "current" item) and the value (as name for property here) which return any type of value from the item at the index. We do not use peek(index) function, so we handle the pointers through the list (and the pages, which may have variable length)
A property, lets say property index, has a hidden (private) variable behind, the [index]. so the Value { } part of property do this;make a Value variable with the value of [index] we can set the value or leave it as is, at the exit of the Value { } part the value of Value variable return as the final value. Because the value get the type from [index] we have to pass the same type (or we get a conversion, if is possible). A property Property Alfa {Value} = 0&& is a long long type (=0&& is the part which set the initial value). Also the Value has no block so we tell that Alfa is readonly, and we can alter the value from a member method of the parent object using This.[Alfa]<=500 or .[Alfa]<=500 (see the dot prefix), Properties are object too. We can add methods or other propeties adding a Group Alfa { } block.
So the test swow for page 300 and page 30, time for filling the structure (and prepare the sum), time for peeking the values and make the sum, and time for iteration through iterator object.
Using iterator is faster than filling the structure; Also using iterator has a little difference from 300 to 30 length of page. The worst time was the peeking values using 30 items per page (although the data part double the page for each new page.
What happen with the pages (which are objects Node) after the end of the module?
The two objects, a and m hold pointers. Iterator if terminate erase the pointers. At the end of module all the "named" objects destroyed, so nodes destroyed.
We can put the remove part of the object, node and we can see when and how big is each node which destroyed; (See the Remove{ } block). This functionality used for those objects which are alive (in scope) through a pointer at least.. The named like a and m they didn't use the remove part (if you wish you may have one, because either a Clear a start the remove part, or you may produce a copy and hold it through a pointer.
Class Node {
{z=pointer()
Read p as long=64, z, m as boolean=false
if m then p1=0 else p1=p
}
dim v(p)
long level=p1
long low=-1
pRead=z
remove {
print "destroyed:", len(.v())
}
}
The block inside Node { } with no name executed as code inside the function Node(). the other code is like code inside a Group Node {type:Node. .... } block. So it is another form from Group Iterator...
' super stack v0.2
' removed onetime variable (inserted for secure reasons).
' When, in peek, we start with useThis as pFirst, we didn't get again pFirst because the count stopped
' Iterator object. We can extract
' Data module expand each time two times, so pages have not the same length.
' st=SuperStack(12) ' number is the page length
' stack grows using nodes, each node has an array v()
' Data, Push, Peek(index from 1), Remove index from 1, Pop or Pop(), length
' When we pop values the nodes destroyed when not have values.
' Also when we delete items then nodes deleted if there are no values from v() in use
' data append to the end of stack (FIFO)
' push push to the start of stack (LIFO)
' pop always read from start - and remove item
' peek read at index
' you can combine peek and push to do OVER (like the statement of M2000 for stacks)
' yoy can combine peek, remove, push to do SHIFT (like the statement of M2000 for stacks)
' to do:
' insert at index ' so combined with peek, insert, remove you do the SHIFTBACK (like the statement of M2000 for stacks)
' split from index to a second stack
' merge two stacks
class superstack {
private:
Class Node {
{z=pointer()
Read p as long=64, z, m as boolean=false
if m then p1=0 else p1=p
}
dim v(p)
long level=p1
long low=-1
pRead=z
}
CurNode=Pointer()
pLast=Pointer()
pFirst=Pointer()
long counter
long pagelen=64, ex=2
public:
Function Iterator {
if .CurNode is type Null then
Usethis=.pFirst
else
UseThis=.CurNode
end if
p=.pFirst
if useThis is type Node then
startLevel=useThis=>level
else
startLevel=.pagelen
end if
long c=.counter, pg
for UseThis {
pg=len(.v())
}
group Iterator {
type:NodeIterator
private:
pFirst=p
StartNode=UseThis
max=c
left=c
lim=pg
pc=startLevel-1
public:
property index {
value {
link parent max,left,pc to m,l,pc
if pc=-1 then error "use a while loop to advance the index"
value=m-l
}
}=0&
Property Value {
value { clear ' we like to use variant as value type
link parent StartNode, pc to SN, pc
variant value
if pc<0 then Error "use a while loop to advance the index"
for SN {
value=.v(pc)
}
}
}
Set {
let This=Group
}
value {
if .left>0 then
.pc++
.left--
=true
if .pc>=.lim then
.StartNode<=.StartNode=>pRead
if .StartNode is type null then
.StartNode<=.pFirst
end if
if .StartNode is type null then
=false
else
For .StartNode, this {
..pc<=.level
..lim<=len(.v())
}
end if
end if
else
.StartNode<=Pointer()
.pFirst<=Pointer()
=false
end if
}
}
=Group(Iterator)
}
Module Data {
if .pLast is type Null then
.pLast<=Pointer(.Node(.PageLen,,true))
.pFirst<=.pLast
end if
boolean NeedOne
thisnew=pointer()
while not empty
for .pLast, this {
while not empty
.low++
if .low=len(.v()) then
NeedOne=true
thisnew<=Pointer(..Node(len(.v())*..ex,,true)) '..pagelen
.pRead<=thisnew
exit
else
read .v(.low)
..counter++
end if
end while
}
if NeedOne then
.pLast<=thisnew:thisnew=pointer()
NeedOne~
end if
end while
}
Module Push {
Long many=stack.size
Boolean NeedOne
if .curNode is type Null Then
.curNode<=Pointer(.Node(.PageLen))
end if
while not empty
for .curNode {
while not empty
if .level=0 then NeedOne=true: Exit
.level--
read .v(.level)
end while
}
if NeedOne then
.CurNode<=Pointer(.Node(.pagelen, .CurNode))
NeedOne~
end if
end while
.counter+=many
}
Function Peek(where as long=1) {
if where<1 then Error "index too low"
if .CurNode is type Null and .pFirst is type Null then Error "Empty Stack"
if .counter=0 then Error "Empty Stack"
if where>.counter then Error "index too high"
boolean newpage=true
z=pointer()
if .CurNode is type Null then
Usethis=.pFirst
else
UseThis=.CurNode
end if
newpage=false
while where>0 and useThis is type Node
for useThis, this {
lim=len(.v())
if .level=lim then
newpage=true
z=.pRead
if z is type null then
z=..pFirst
end if
exit
end if
st=.level
w=len(.v())-st
if w<where then
newpage=true
where-=w
z=.pRead
if z is type null then
z=..pFirst
end if
else
=.v(st+where-1)
where=0
end if
}
if newpage then
useThis=Z:Z=pointer()
newpage~
end if
end while
}
Module Remove (where as long=1) {
if where<1 then Error "index too low"
if .CurNode is type Null and .pFirst is type Null then Error "Empty Stack"
if .counter=0 then Error "Empty Stack"
if where>.counter then Error "index too high"
boolean newpage=true
z=pointer()
if .CurNode is type Null then
Usethis=.pFirst
else
UseThis=.CurNode
end if
newpage=false
oldPointer=Pointer()
boolean removelastnode
while where>0 and useThis is type Node
for useThis, this {
lim=len(.v())
if .level=lim then
newpage=true
z=.pRead
if z is type null then
z=..pFirst
end if
exit
end if
st=.level
w=len(.v())-st
if w<where then
newpage=true:
where-=w
z=.pRead
if z is type null then
z=..pFirst
end if
else
uplim=st+where-1
if .level<uplim then
stock .v(.level) keep uplim-.level, .v(.level+1)
.level++
else
.v(st+where-1)=0
.level++
end if
..counter--
where=0
if .level>=len(.v()) then
z=.pRead
if z is type null then
z=..pFirst
end if
removelastnode=true
end if
end if
}
if removelastnode then
newpage=false
if oldPointer is type null then
.CurNode<=z
else
oldPointer=>pRead=z
end if
else.if newpage then
oldPointer=useThis
useThis=Z:Z=pointer()
newpage~
end if
end while
}
Group Pop {
value {
link parent Pop() to p()
=p()
}
}
Function Pop() {
if .CurNode is type Null and .pFirst is type Null then Error "Empty Stack"
if .counter=0 then Error "Empty Stack"
boolean newpage=true, cur
z=pointer()
variant cl
if .CurNode is type Null then
Usethis=.pFirst
.pFirst<=Pointer()
else
UseThis=.CurNode
cur=true
.CurNode<=Pointer()
end if
while newpage and useThis is type Node
for useThis, this {
lim=len(.v())
if .level=lim then
// pen #ff2277 {print "<<>>",}
z=.pRead
if z is type null then
z=..pFirst
end if
else
=.v(.level)
swap .v(.level), cl
cl=0
.level++
..counter--
newpage~
end if
}
if newpage then
useThis<=Z:Z=pointer()
end if
end While
if cur then
.curNode<=UseThis
else
.pFirst<=UseThis
end if
}
Property Length {
value {
link parent counter to c
value=c
}
}=0&
class:
module superstack(.pagelen){
}
}
flush
const iteratorlegend=" time to read each value through iterator, which hold last page and last position"
const peeklegend=" time to read each value using peek(i) - so each time start from first page"
const filllegend=" time to fill the structure and get the sum of all values"
N=500
Print "Page 300"
a=superstack(300)
long long acc=0, z
acc=0
z=1
profiler
for i=1 to N{
a.push z
a.data z+1
acc+=z*2+1
z+=2
}
? int(timecount), filllegend
? acc
refresh
z=0
profiler
for i=1 to a.length
z+=a.peek(i)
next
? int(timecount), peeklegend
? z
m=a.iterator()
// beacause m return value we have to use group(m) to get the group (the object)
//? group(m) is type NodeIterator ' true
z=0
profiler
while m
z+=m.value
end while
? int(timecount), iteratorlegend
? z
Print "Page 30"
a=superstack(30)
long long acc=0, z
acc=0
z=1
profiler
for i=1 to N{
a.push z
a.data z+1
acc+=z*2+1
z+=2
}
? int(timecount), filllegend
? acc
refresh
z=0
profiler
for i=1 to a.length
z+=a.peek(i)
next
? int(timecount), peeklegend
? z
m=a.iterator()
z=0
profiler
while m
z+=m.value
end while
? int(timecount), iteratorlegend
? z
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.