go to post Julius Kavay · May 12 Just to put things into a correct light 1) java came out mid 90esat the time ObjectScript (or mumps or m) already had it's lock a quarter centuy. That said, one could ask, why didn't implemented Java the lock the same way as M? Maybe they didn't know about mumps, maybe they targeted something else, who knows... On the other hand, imagine, all the programming lanuages have the same commands, functions, syntaxes etc. Then all the time we just had one programming lanuage. 2) as you said, lock is a 'convention'. A convention, as many other things.It's a convention too, if you take a tramway you buy a ticket - and most people do buy a ticket, but some are fare dodger. And nobody says, that's the problem of the convention. 3) using a device as a program interlock did not targeted the lock command but setting a global.If you set a global node to mark something as 'occupied' and during this time your process dies, then the global won't be cleaned up by the system - except you set a process-private-global, but that mark is invisible to external processes.
go to post Julius Kavay · May 12 I'm neither a C# nor a Java guru, but I know definitively that a LOCK in ObjectScript protects YOUR resources to be to be taken by OTHERS. It does NOT prevents you, to use your OWN resource again and again. And yes, I know that you can get the lock count from ^$LOCK SSV. Locks like lock +^Test:1 if $test lock +^Test:1 if $test write "It's my resource!" lock -^Test,-^Test are pointless. The above locks could be a short version for: (Class)Method MyCrticalSection() { lock +^Test:1 if '$test quit // some commands do ..MyCriticalSection() // despite the lock, this call enters this section again // some more commands lock -^Test } whereas the above lock guards against OTHER jobs to enter that method, it doesn't locks my own job out.Maybe I don't understand your problem. People use to say, if there is a problem I do not understand, than either the problem is very simple or extraordinarily complicated...
go to post Julius Kavay · May 7 I don't entirely understand the problem, you ask for "inside same process" but further you write "protect some code for being called by multiple processes at same time" - same or multiple processes? The only way (I know) to reenter a code inside the same process is, using recursion (there are neither threads nor events in ObjectScript). If you don't want reentrace, do not use recursion. If you talk about multiple processes (running at the same time) then you have to use some kind of semaphore to let in just one process at any given time in a critical code section, see the examples below. I would use the version with device, because in all error cases (abnormal shut down, process error, etc) IRIS closes the device automagically - globals may have leftovers in case of errors. Class DC.OnlyOne Extends %RegisteredObject { /// device numbers 20-46 and 200-223 are routine interlock devices /// Choose one of them /// ClassMethod UsingDevice(testTime = 0) { set myDevice = 45 open myDevice::0 if $t { // run that critical section hang testTime set ans="Critical section is done" } else { set ans = "Critical section in use" } close myDevice quit ans } /// a more meaningful name then ^X would be reasonable /// a KILL ^X in %ZSTART.mac, label SYSTEM is also advisable /// for the case, the system was shut down abnormally ClassMethod UsingGlobal(testTime = 0) { if $i(^X)=1 { // run that critical section hang testTime set ans="Critical section is done" } else { set ans="Critical section in use" } if $i(^X,-1) quit ans } ClassMethod UsingLock(tim = 10) { // see John's example } }
go to post Julius Kavay · May 5 I had a real use case, where from an instance method a class method was called and that class method used $this as argument in a subsequent call. In the very first call the content of $this was the class name (as documented) but in subsequent calls it contained the OREF and that caused a <CLASS DOES NOT EXIST> error. A WRC ticket is already open.
go to post Julius Kavay · Apr 14 Since you want the smallest possible number of sets that cover the maximum number of elements, one of the simplest solutions (from a programming point of view) is to check all possible combinations of K out of N sets. However, keep in mind that combinations grow (very) quickly. If your N tends to leave the single-digit range, you may need to resort to linear programming methods. Some values for all combinations (K out of N) to see, how they grow: N : 1 2 3 4 5 10 15 20 25 50cnt: 1 3 7 15 31 1,023 32,767 1,048,575 33,554,431 1,125,899,906,842,623 Class DC.MaxCoverage Extends %RegisteredObject { ClassMethod Test(case = 0) { if case=4 { set list($i(list))="1,2,3" set list($i(list))="" set list($i(list))="1,2,3" } elseif case=3 { set list($i(list))="1,2,3" set list($i(list))="4,5,6" set list($i(list))="1,2,3" } elseif case=2 { set list($i(list))="1,2,3" set list($i(list))="7,8,9" set list($i(list))="11,12,13,14,15" set list($i(list))="2,8,12" set list($i(list))="15,16,17" set list($i(list))="12,17,19,21,22,23" set list($i(list))="11,21,31,32,33" set list($i(list))="34,35,36" } elseif case=1 { set list($i(list))="1,2,3,4" set list($i(list))="5,6,7,8,9,10,11,12" set list($i(list))="2,3,4,5,6,7" } else { // the original testcase set list($i(list))="3,5,6,7,9" set list($i(list))="1,2,6,9" set list($i(list))="5,8,9" set list($i(list))="2,4,6,8" set list($i(list))="4,7,9" } quit ..MinMax(.list) } /// minimum number of sets with maximum number of coverage /// ClassMethod MinMax(ByRef list) { // I assume, all numbers are // a) integers and greater then 0 (else map the numbers to integers in the toBits() method) // b) and all sets have less then ca. 262100 elements // set N=list for i=1:1:N s set(i)=..toBits(list(i)) // convert each list into a bitstring set max=0, min=N, lst="" // max=covered numbers, min=required sets, lst=list of combinations for k=1:1:N { // compute all (k out of n) combinations for each k set s=0, i(0)=0 // --+ compute k out of n 1 set s=s+1, i(s)=i(s-1), e(s)=N-k+s // | 2 for i(s)=i(s)+1:1:e(s) goto 1:s<k do chk // | check a particular combination 3 set s=s-1 if s goto 2:i(s)<e(s),3 // --+ } quit min_" set(s) covers "_max_" elements with sets: "_lst // return the result chk set c=i(1),v=set(i(1)) // take the first set for i=2:1:s s c=c_","_i(i), v=$bitlogic(v|set(i(i))) // OR it with the next set v=$bitcount(v,1) if v>max { set max=v,min=s,lst=c } elseif v=max,s<min { set min=s,lst=c } elseif v=max,s=min { s lst=lst_" or "_c } } /// convert a list of numbers into bitstring, i.e.: 1,2,4 --> 1101 /// ClassMethod toBits(x) { set b="" for i=1:1:$l(x,",")-(x="") set $bit(b,$p(x,",",i))=1 quit b } /// Sum of all combinations of N elements /// ClassMethod AllComb(N) { s s=0 f k=1:1:N s s=s+..Comb(k,N) q s } /// Count of combinations of K elements out of N elements /// ClassMethod Comb(k, n) { s c=1 f k=1:1:k s c=c/k*n, n=n-1 q c } } Tests USER>for i=0:1:4 write ##class(DC.MaxCoverage).Test(i),! 3 set(s) covers 9 elements with sets: 1,2,4 2 set(s) covers 12 elements with sets: 1,2 7 set(s) covers 23 elements with sets: 1,2,3,5,6,7,8 2 set(s) covers 6 elements with sets: 1,2 or 2,3 1 set(s) covers 3 elements with sets: 1 or 3 USER>
go to post Julius Kavay · Apr 12 Two questions. First, is the expected answer for the above collection of five sets: 1,2,4 (where the sets 1, 2 and 4 all together cover 9 different numbers: 3,5,6,7,9,1,2,4,8)? Second, may any of the sets contain a number, which is not included in the AllList?If the answer is a no (what I assume), then the AllList is't needed, because all numbers are in 'AllList', hence it's enough to search for a minimum number of sets with the maximum of distinctive elements.
go to post Julius Kavay · Mar 13 There is a somewhat "simple" method too /// search for the superserver job /// return the OS Username for that job ClassMethod OSUsername() { new $namespace set $namespace="%SYS" set job="" for {set job=$zj(job) quit:job="" set prc=##class(%SYS.ProcessQuery).%OpenId(job) if prc, prc.JobType=24 ret prc.OSUserName } ret "" }
go to post Julius Kavay · Mar 13 Try this method Class DC.Util Extends %RegisteredObject { /// Return: the OS username for this Cache/IRIS instance /// /// First, get the port of the superserver /// then search, which job owns that port /// then return the OSUsername for that job /// ClassMethod OSUsername() { new $namespace set $namespace="%SYS" if ##Class(Config.Startup).Get(.par),$d(par("DefaultPort"),port) { set job="", pattern=".e1""|TCP|"_port_"*"".e" for set job=$zj(job) quit:$v(-1,job)?@pattern||(job="") if job { set proc=##class(%SYS.ProcessQuery).%OpenId(job) ret:proc proc.OSUserName } } ret "" } } A note:- I know of a $zu(...) function which works and returns the superserver port but $zu() functions are deprecated/discouraged - and this one is not in the replacement list - why?
go to post Julius Kavay · Feb 20 in the above answer, after "...spiral way is this" and "You start..." there should be a picture - it seems, something is went wrong with the upload. I try it a second time...
go to post Julius Kavay · Feb 19 I think he didn't made it clear. The examples Test1x1Matrix() and TestAllSameCharacters() are exaples without any information. And by the way, a 1x1 and 2x2 matrices aren't the best examples to show a spiral way!
go to post Julius Kavay · Feb 19 In absence of clear rules, it's wasting time to write a code. Or one makes his own rule and writes a code which confirms to this rule. My perception of travelling along the cells of a quadratic matrix in a clockwise spiral way is this You start at the big red point (1,1) and go along the cells until the last cell. Of course, you can start at any point, including the last one (then is your start and endpoint are the same and no motion is requered). If you start, for example in a 4x4 matrix at (1,3), this means, you skip the first two cells: (1,1) and (1,2) and if you reached the last point (3,2) there is no way (I mean, no sense) to came back to (1,1)
go to post Julius Kavay · Feb 18 Exactly, that's the correct way (according to my opinion, and it seems, you go with me).In the above example, a 'H' never may be followed by an 'A', that would make a full circle but we want a spiral...
go to post Julius Kavay · Feb 17 I absence of welldefined rules, it's a matter of opinion, how one does a "clockwise spiral walk" in a quadratic matrix.First, I would define the TOP-LEFT corner as point (1,1) with the addition, that (1,1) is always the top-left corner.For a 1x1, 2x2, 3x3, 4x4 and 5x5 matrix I would go this way (I use the 25 letters to show my clockwise spiral way, starting at top-left with the letter 'a'): 1x1 2x2 3x3 4x4 5x5 a-a a-d a-i a- a-y a ab abc abcd abcde dc hid lmne pqrsf gfe kpof oxytg jihg nwvuh mlkji Matrix: 4x4, starting points: (1,1) --> abcdefghijklmnop (1,2) --> bcdefghijklmnop (2,3) --> nop (2,4) --> efghijklmnop (3,1) --> klmnop (3,2) --> p (3,3) --> op You always go from the starting point to the endpoint (in the center) All odd matrices (1x1, 3x3, 5x4,...) have a middle-point at (N+1\2, N+1\2) According to original constraints #2 "The starting position is always valid within the matrix". I interpret that as one can start at any point a clockwise spiral reading, for example, reading the 4x4 matrix, starting at (3,4) gives you: 'fghijklmnop' The sequence 'abcde' is skipped. A reading like: 'fghijklabcdenm' gives a clockwise spiral but never touches 'op' on the other hand, reading like: 'fghijklabcdenopm' is not clockwise-spiral because at the sequence 'eno' suddenly takes an counterclockwise turn!
go to post Julius Kavay · Feb 13 You talk about a multidimensional matrix but obviously mean a two dimensional matrix - right?You talk about a matrix of size: N x N but neither the given code signaure nor the task description specify where the value N is given. In your examples you create the matrix by continuous incrementing the root node of matrix - the root node is equal to N, is this always valid or just in your examples or in other words, would this be a valid call: kill box set box(1)="A,B" set box(2)="C,D" do ##class(codeGolf.ClockwiseWord).Solution(.box,1,1) I know, I one can obtain the value for N with a simple $order() set N = $order(matrix(""),-1) You expect a correct solution, we expect correct a descriptionjustmy2cents
go to post Julius Kavay · Feb 10 Before you start reading, set the lineterminator property to the desired value do myStream.Rewind() set myStream.LineTerminator=$c(13,10) // or $c(10) // or more general set myStream.LineTerminator=$case($zversion(1), 2:$c(13,10), 3:$c(10), :"") // now start reading set line = myStream.ReadLine() ... ...
go to post Julius Kavay · Feb 7 And do not forget, if the application has/uses parts of "older code" then the so called "naked syntax" may also be a issue (of course not, if you just want to know the name of the global). Classmethod Test() { kill ^myGlobal kill ^yourGlobal set ^myGlobal(2)="some data" do ..moreData("data1") set ^yourGlobal(3)="other data" do ..moreData("data2") // Now, the globals look like // // ^myGlobal(2)="some data" // ^myGlobal(9)="data1" // // ^yourGlobal(3)="other data" // ^yourGlobal(9)="data2" } ClassMethod moreData(data) { set ^(9)=data } Beside all the "nice" combinations of direct sets, indirections, naked synates etc. do not forget, your application may call routinies/methods which are in deployed mode (third party APIs and utilities - hopefully with documentation)