Inside COBOL #51 (Using Image b-trees in COBOL)
The Image lab recently (MPE/iX 5.5 powerpatch 3) gave us b-trees as an integral part of Image. This means you now have the ability to do wild card searches, range retrievals, and greater than/less than style searches. The only real problem with this enhancement is the almost complete lack of documentation. The best I have been able to find is a short paper at http://jazz.external.hp.com/papers/btree.txt by Stan Sieler giving some documentation on the various modes and arguments.
Armed with this knowledge, I set out to write a little program that used b-trees. The first thing you have to do is enable the b-tree index on the key item. There are three new commands in DBUTIL to allow you to add, delete and rebuild indexes, they adhere to the following form;
ADDI[ndex] database name[/maint word]
DROPI[ndex] database name[/maint word]
REBUILDI[ndex] database name[/maint word]
You can also enable a mode 1 DBFIND to support wild card searches with the following command in DBUTIL;
SET database name[/maint word]
BTREEMODE1 = <
You can also modify what the wildcard characters is going to be with this command, by default it is the @ sign. The simplest way to make use of this feature is to enable BTREEMODE1, and then let the user put in an @ sign in the search value. You will automatically get the chain for the wildcarded set. This doesn’t involve any extra programming on your part.
I am going to describe how to do a range retrieval in my example, because that is the most confusing to understand initially. First we need to construct a complex argument structure, the following will work;
01 BTREE-ARGUE. 03 BA-TYPE PIC X(02) VALUE "". 03 BA-VER PIC S9(4) COMP VALUE 0. 03 BA-ARG1-LEN PIC S9(4) COMP VALUE 6. 03 BA-ARG2-LEN PIC S9(4) COMP VALUE 6. 03 BA-ARG1 PIC X(06) VALUE SPACES. 03 BA-ARG2 PIC X(06) VALUE SPACES. The BA-TYPE value of  indicates a range retrieval, valid values for complex argument retrievals are; "< " search for key values LESS than argument1 "<=" search for key values LEQ argument1 "= " search for key values EQL argument1 (i.e., similar to a DBFIND mode 1) ">=" search for key values GEQ argument1 "> " search for key values GTR argument1 "" search for key values GEQ argument1 AND LEQ argument2
BA-VER is the version, and is currently always zero. The next two fields indicate the lengths of the two arguments. From what I can tell, these must be the same length. Then of course our last two values are the arguments themselves. The actual call to DBFIND will look like the following;
CALL "DBFIND" USING MYDB, MYDATASET, MODE4, DB-STATUS-AREA, MYSEARCHITEM, BTREE-ARGUE.
You would now proceed with your MODE5 DBGET to read your chain. What you should notice is that we are doing a MODE4 DBFIND. There are four new DBFIND modes available, and they have enhanced MODE1.
Mode = 1, Do a standard DBFIND unless BTREEMODE1 is on for the database, and there is a wildcard in the argument, then do a btree lookup.
Mode = 4, Do a b-tree find with accurate chain counts using the complex form of the argument parameter.
Mode = 10, Do a non b-tree DBFIND mode 1 equivalent.
Mode = 21, Same as mode 1, but is high speed and doesn’t return accurate chain counts.
Mode = 24, Same as mode 4, but is high speed and doesn’t return accurate chain counts.
I’m not really sure why you would use modes 21 and 24, unless you are really returning a large number of records, and the performance is noticeable.
An important thing to understand is that the b-tree indexes are actually added to the master dataset. This is what makes them so efficient, they don’t have to store as much data. They are essentially KSAM files that are linked to the master key. This opens up a whole slew of new keying strategies, such as NAME, where you never would have put a key in the past.
Next month I am going to talk about how to share file opens between sub-programs.