M Web Magazine 007 (June 5, 1998 - September 4, 1998)

M Tutorial (part 5/5)

 

$QUERY(<var>,<direction>) or $Q(<var>,<direction>)

$ORDER was used to set a particular subscript with the preceding or succeeding subscript (or null if the beginning or end of the array had been reached).

$QUERY returns the preceding or succeeding branch of the global or null when at the end or the beginning.

GLB019Þ;Program demonstrates arrays and globals - Chris Bonnici - Mar 1998
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN I,SUB,EXIT,DIR
ÞK ^GLB
ÞF I=1:1:50 D
Þ.I $R(10)#2=0 S ^GLB(I)="LEVEL 1:"_I
Þ.I $R(10)#2=0 S ^GLB(I,"A")="LEVEL 2:"_I
Þ.I $R(10)#2=0 S ^GLB(I,"A","DATA")="LEVEL 3:"_I
Þ.Q
ÞS EXIT=0
ÞF D Q:EXIT
Þ.R !,"Enter Subscript: (0 - Exit) ",SUB
Þ.I SUB=0 S EXIT=1 Q
Þ.R !,"Go <U>p or <D>own: ",DIR#1
Þ.S DIR=$S(DIR="U":-1,1:1)
Þ.W !,"Node: ",$Q(^GLB(SUB),DIR)
Þ.Q
ÞQ

The program GLB019 demonstrates how the $QUERY functions. It tells you the next node that contains data. For example if we have a global ^GLB consisting of:

^GLB(1)
^GLB(2,5,9)

$Q(^GLB(1)) gives ^GLB(2,5,9). With $ORDER (assuming we do not know the data nodes) we have to go through the different subscripts and use $DATA. GLB020 benchmarks the two functions.

Before you run this program, backup your database.

GLB020Þ;Program demonstrates arrays and globals - Chris Bonnici - Mar 1998
Þ;M Web Magazine @ http://geocities.datacellar.net/SiliconValley/7041/mwm.html
Þ;You are using this program at your own risk
Þ;
ÞN ANS,I,OTIME1,QTIME1,OTIME2,QTIME2
ÞW #,"$O and $Q benchmarker"
ÞW !!,"You should make a backup of you database before you continue with this program."
ÞW !,"It creates a large global called ^GLB and may cause problems if it runs out of"
ÞW !,"disk space"
ÞR !,"Press <Y>+<enter> to continue ",ANS
ÞQ:ANS'="Y"
ÞK ^GLB
ÞF I=1:1:20000 D
Þ.W /CUP(20,1),"Creating Record: ",I,"/20000"
Þ.I $R(10)#2=0 S ^GLB(I)="LEV 1:"_I
Þ.I $R(10)#2=0 S ^GLB(I,"A","X")="LEV 3:"_I
Þ.I $R(10)#2=0 S ^GLB(I,"A","X","Y","Z")="LEV 5:"_I
Þ.Q
ÞS OTIME1=$$PROCO
ÞS QTIME1=$$PROCQ
ÞS QTIME2=$$PROCQ
ÞS OTIME2=$$PROCO
ÞW !!,"USING $O: ",OTIME1
ÞW !!,"USING $Q: ",QTIME1
ÞW !!,"USING $O: ",OTIME2
ÞW !!,"USING $Q: ",QTIME2
ÞK ^GLB
ÞQ
Þ;*** EOR ***
PROCO()ÞN SUB1,SUB2,SUB3,SUB4,SUB5,STIME
ÞS STIME=$P($H,",",2)
ÞS (SUB1,SUB2,SUB3,SUB4,SUB5)=""
PA10ÞS SUB1=$O(^GLB(SUB1)) Q:SUB1="" $P($H,",",2)-STIME
ÞI $D(^GLB(SUB1))#10=1 W !,^GLB(SUB1)
PA20ÞS SUB2=$O(^GLB(SUB1,SUB2)) G:SUB2="" PA10
PA30ÞS SUB3=$O(^GLB(SUB1,SUB2,SUB3)) G:SUB3="" PA20
ÞI $D(^GLB(SUB1,SUB2,SUB3))#10=1 W !,^GLB(SUB1,SUB2,SUB3)
PA40ÞS SUB4=$O(^GLB(SUB1,SUB2,SUB3,SUB4)) G:SUB4="" PA30
PA50ÞS SUB5=$O(^GLB(SUB1,SUB2,SUB3,SUB4,SUB5)) G:SUB5="" PA40
ÞW !,^GLB(SUB1,SUB2,SUB3,SUB4,SUB5)
ÞG PA50
Þ;*** EOR ***
PROCQ()ÞN REF,STIME
ÞS STIME=$P($H,",",2)
ÞS REF="^GLB"
ÞF S REF=$Q(@REF) Q:REF="" W !,@REF
ÞQ $P($H,",",2)-STIME

Notes on GLB020:

  • With fast underlying hardware (especially the disk subsystem) the difference will be minimal.
  • We are using indirection @REF. We will not be delving into this topic today.

Before we conclude this section, we would like to point out that what we have just said for globals applies to memory based arrays (with the exception of naked references).

 

mwmtryit.gif (2244 bytes)Globals and $PIECE

In MWM006 we talked considerably about the $PIECE function. Combining these two into a logical and consistent manner makes it possible to for us to write programs that store information within a global using $PIECE to separate the fields. With large amounts of data (a global entry can contain up to a maximum of 511 characters) we may have to split the data into multiple nodes. Try writing a program that places data within a database and one that reads it.

In MWM008 we will be taking on from here.

 

^%GS and ^%GR

If you are trying out the programs accompanying this tutorial you must have used ^%RR (Routine Restore). We talked about these command in MWM001. The programs ^%GS (Global Save) and ^%GR (Global Restore) allow you to transfer globals to/from the operating system.

Pressing ? next to any of the prompts will display what should be entered at that prompt.

 

^%FGS and ^%FGR

With large globals ^%GS and ^%GR may take a considerable amount of time. Micronetics’ ^%FGS (Fast Global Save) and ^%FGR (Fast Global Restore) speed up this process considerably although:

  • Note that the globals saved this way cannot be read by implementations of M by other vendors.
  • The resulting file is larger.

 

E&OE

1