Threaded Content in the In-Memory Driver

by Unknown user

The In-Memory Database Driver, a/k/a IMDD, a/k/a "the Memory Driver," is perhaps the best-received Clarion add-on in recent history. I certainly consider it a "must have." I am currently working on a project using a version of Clarion for which no one, including SoftVelocity, has an IMDD install. While I can use queues, of course (the Memory Driver appears to be "just" a file driver wrapper for queues), my inability to have IMDD files in my dictionary is a constant source of frustration.

Why is the Memory Driver so popular?

  • It allows use of standard file I/O commands for my queues.
  • IMDD files, like queues, allow completely private data. Data declared globally can be seen only by the app in which it is declared; data declared in lower scopes are invisible to other modules/procedures in the same app. As the on-line help asserts:

In-Memory tables provide highly exclusive data access. Storing data in a In-Memory table you can be sure of its security and privacy. Even two programs simultaneously running on the same computer will each use their own data copy

  • IMDD files, unlike queues, can be used in any SoftVelocity or third party template that calls for a File.
  • As with queues, on a spec change, no data conversion is necessary, only a restart of the application (no possibility of an ErrorCode 47, none whatsoever).
  • Unlike queues, IMDD files are automatically disposed, no inadvertent memory leaks:

In addition all stored data will be automatically destroyed when application terminates, and you will never have any undeleted temporary files.

A queue declared in hand code must be FREEd to avoid a memory leak. 

  • The "biggie" is that IMDD files, unlike any other Clarion data structure, is (claimed to be) inherently thread-safe.

Unlike a global queue, you do not have to write code to synchronize threaded access, because synchronization is built into the driver.

I have never tested this claim myself but a number of very knowledgeable Clarioneers also make this claim. And, knowing many of them, I am inclined to believe they did not agree with the thread-safe claim simply because SoftVelocity said it.
There is even a template that allows synchronizing an IMDD file with its underlying disk file. But I have never used it.

IMDD's Latest Feature


Recently, "threaded content" (the subject of this article) was added to the IMDD. In fact, very recently, a question came up about this driver string on the news groups.

What is "ThreadedContent" supposed to do? The on-line documentation states:

 

THREADEDCONTENT
DRIVER('Memory', '/THREADEDCONTENT')
The THREADEDCONTENT switch makes an in-memory table only visible on the thread where it was created. Any In-Memory table defined with the THREADEDCONTENT switch active is completely invisible to other threads.
Normally, an In-Memory file with the THREAD attribute shares the same data across all threads. However, if you want to have unique data on each thread, then you can set the driver string to /THREADEDCONTENT.

 

The documentation implies that, with "ThreadedContent," IMDD data is not only invisible to other instances of the application but also invisible to any procedure on a different thread.
Testing this claim seems easy enough.

Testing "ThreadedContent"


I intended to wizard up an app based on a DCT containing one file only, an IMDD file, and "ThreadedContent" will be switched on for that file.



Figure 1: Creating an IMDD file



Figure2: Setting the "ThreadedContent" Switch


I intend to create an autonumber key. If I try to add records on two threads, this will surely show whether or not multiple threads can "see" the autonumbered values on another thread.

In the wizarded app, I really only need a browse-form combination. If I open the browse and add records and then open another instance of the browse and add some more records, I should see whether or not the two threads "see" each other's data – especially the autonumbered field.

The only code I expect to embed is:

Thread = Thread()

(where "Thread" is a local Long) to display on the browse window. This will confirm that I am on different threads.

The Proof of the Pudding


Run the attached app, downloadable at the end of this article. It is an 8.0.8973 app and the app tree will show that it is a wizarded app. The compiled EXE is compiled in "Lib" ("Local") mode so everyone can run it.
When you run the app, you should be able to get results similar to this:



Figure 3: Result of adding records on two threads

Indeed, these results show that both threads can have a record 1. If the IMDD files were not thread-specific, I should have seen this:



Figure 4: "Normal" autonumbering result

when I started to add a record in the second browse.

And I cannot get records entered on one thread to appear on another.

Q.E.D. "ThreadedContent" does create thread-specific IMDD data sets. IMDD data can be made rigidly scope-specific.

Download the source