An Interface between IMS ODBM and a Java Application using Type-4 connection to retrieve multiple segments from multiple database records. 

Problem: Network latency puts type 4 applications at a disadvantage when asking for IMS segments in the traditional way:   1 call = 1 answer.      

Solution:  change the pattern to 1 call = collection of answers 

Get multiple segments types from an IMS DB record.  
Get segments types from multiple DB records using a list of root keys. 

DEDB is multiple Positioning by Default.   It is TSYS’s opinion that FF databases should turn on multiple Positioning to use the “bulk response” calls described in this document. 

When the answer is a Collection of Segments, there needs to be ways query the Collection and extract data in an orderly fashion. 
There should be methods to get, add, remove, update, and to query for meta information such a concatenated key, relative location within the collection hierarchy, number and existence of segment types. 

A collection backed by key value pairs might be an option where the key is segment name and occurrence number. 
	segmentObject = collection.getSegment(“AMSAM01”, 1, 
“AMSAM02’, 1, 
“AMSAM33”, 3)   
Returns the 3rd AM33 under the first AM02 under the first AM01 
  
	int numAM01 = collection.getSegmentOccurances(“AMSAM01”)   
Number of total AM01s in the collection 

int numAM01 = collection.getSegmentOccurances(“AMSAM33, 
								“AMSAM00”, 1,
“AMSAM02”, 1)
 Number of AM33s under the 1st AM00 and the 1st AM02 under it. 

To obtain the concatenated key for a segment retrieved from a collection. 
	keyFBAM01 = segmentObject.getKeyFeedBack()

To obtain the hierarchy within the collection. 
	-hierInfo = segmentObject.getCollectionHierarchy() 
	Return data would be the hierarchy to the segmentOybject. 
		AMSAM00	#1 	key= ??? 	where #1 is occurrence 
		AMSAM02	#1 	key= none
		AMSAM33	#5 	key = ????

segmentObject = collection.getSegment(“AMSAM00”, 1)  

Since the collection contains multiple segments, TSYS does not require these calls to emulate IMS’s concept of a path call if that makes it easier to implement these new methods.      Each call returns a single segment thus: 
segmentObject = collection.getSegment(“AMSAM00”, 2, “AMSAM02”, 1) 
yields the first AMSAM02 segment under Root # 2 in the collection. 

Thus far the design concept has been on code invoking methods to query or extract data from the collection. 

It might be worthwhile to for IBM to provide a visitor pattern for segment Collections.    As each segmentNode in the collection is visited the following attributes can be made available to visiting method 
	Segment Name:	AMSAM33	
Segment Level: 	3 	
SegmentPath: 	[“AMSAM00”, “AMSAM02”, “AMSAM33”]
segmentDataObject     (aka the path object for the current segment)
IsRoot:  		false		
Concatenated-Key:     123400000000012300<AM33-key>	   
Note: AM02 does not have a key. 	
Hierarchy Occurrence:   [2, 1, 5] 	
Note:  	2nd root.    
1st AM02 under the 2nd root.    
5th AM33 under the current (1st) AM02 

Example  # 1:   getUniqueDBRecords      1 root    
Qualifications: 
SSA = Root-key
List of the segments to be returned from each root.    It would be awesome to be able to provide addition qualifications to filter the children segments.  

Return:   
	Collection of Segments 
TSYS is not sure that a normal IMS Status Code should be returned.  If a child segment types are not found, the call is stilled deemed successful. 
At best a “GE” when the root is not found would be considered an exception. 
It might be better to provide a method to ask for the number of occurrences or existence of segments 
int numSegments = collection.numSegments()   // all segments
int numAM00 = collection.numSegments(“AMSAM00”) 
boolean hasData = collection.hasSegment()   // false if nothing in the collection. 
boolean hasAM04 = collection.hasSegment(“AMSAM04”) 
isEmpty 

ssaAM00 = pcb.getSSAList(“AMSAM00”)
ssaAM00.addInitialQualifcation(“AMSAM00”, “AMFAM00K”,  …)

ssaAM01 = pcb.getSSAList(“AMSAM01”) 
ssaAM01.addInitialQuafication(“AMSAM01”, “RELSTAT”,
SSAList.EQUALS, “ ”)   
ssaAM01.appendQuafication(“AMSAM01”, “RELSTAT”,
SSAList.EQUALS, “A”)   

GetUniqueDBRecord   with
	[String: segment, String: parent, String: ssa, integer: limit, …] 
		Where 0 for “limit” means all

List of desired segments and qualifications: 
getUniqueDBRecord(
[“AMSAM00”, “”, ssaAM00,  1,
	“AMSAM02”, “AMSAM00”, “”, 1,     
	“AMSAM33”, “AMSAM02”, “”, 0,	// all AM33s 	
	“AMSAM0F”, “AMSAM00”, “”, 1, 
	“AMSAM01”, “AMSAM00”, ssaAM01, 0]    // all active AM01 segments  
	)
The SSA on children are used to filter the result set rather than controlling the scope.  The default is to treat each hierarchic leg as if FIRST had been coded. 
Return: collection-object

Opinion:  Root key  with SSAList.EQUALS should be a required to avoid scanning		

Expected IMS call pattern done by ODBM to IMS for Example # 1. 
Status code of Spaces and “FW” is okay. 
EXEC DLI GU  
SEGMENT(AMSAM00) 
		WHERE (AMFAM00K = ‘123400000007654300’ ) 
		INTO (buffered-io-area) 
END-EXEC 
Position is on root   Parentage is on root. 

EXEC DLI GNP     Loop until GE or limit reached 
SEGMENT(AMSAM0F) 
		INTO (buffered-io-area) 
END-EXEC 

EXEC DLI GNP     Loop until GE         (limit is all) 
SEGMENT(AMSAM01) 
		INTO (buffered-io-area) 
		WHERE (RELSTAT =’ ‘  OR RELSTAT = ‘A’) 
END-EXEC 

Children that also have children requires that OBDM have knowledge of that.   That knowledge could be passed into the call.  Thus the “child of” is not just a comment but required information to make the call work. 
		AMSAM33:       	child of AMSAM02

FYI: this is the following loops demo a COBOL processing pattern used to avoid skipping Children that can be parents but do not have kids

getAM02
LOOP   UNTIL “GE”  or limit reached // handle am02 segments
	saveAM02Info
	getAM33
	LOOP UNTIL “GE”    (limit is ALL)	// handle AM33 segments
		saveAM33Info
		getAM33 
	END-LOOP 			// AM33 loop
	getAM02
END-LOOP 				// AM02 loop 

getAM33      “method / paragraph”
EXEC DLI GNP 
	CURRENT SEGMENT(AMSAM02)     (SSAList.CC_U) 
	SEGMENT(AMSAM33) 
		INTO ( ) 	
END-EXEC 
Exit.

The current command code can use used to limit the scope of the GNP call to the current AMSAM02 segment. 

getAM02      “method / paragraph”
EXEC DLI GNP 
	SEGMENT(AMSAM02)  
		INTO ( ) 	
END-EXEC 
Exit.

Example 2   Reading Multiple Roots. 

ssaAM00 = pcb.getSSAList(“AMSAM00”)
PreparedValue pvAM00 = ssaAM00.createPreparedValue(“AMFAM00K”)

ssaAM00.addInitialQualifcation(“AMSAM00”, “AMFAM00K”, SSAList.EQUALS, pvAM00)

ArrayList<PreparedValue> keyListAM00  = new ArraryList<PreparedValue>
keyListAM00.add(ssaAM00.setValue(“222000000000001500”) ); 
keyListAM00.add(ssaAM00.setValue(“222000000000001600”) ); 
keyListAM00.add(ssaAM00.setValue(“222000000000007500”) ); 

getUniqueDBRecord(
[“AMSAM00”, “”, ssaAM00,  1,
	“AMSAM02”, “AMSAM00”, “”, 1,     
	“AMSAM33”, “AMSAM02”, “”, 0,	// all AM33s 	
	“AMSAM0F”, “AMSAM00”, “”, 1, 
	“AMSAM01”, “AMSAM00”, ssaAM01, 0],     // all active AM01 segments  
	keyListAM00)   // list with 3 root keys to get. 

Notes:  
•	Designed for inquiry transactions ideally the PCBs use PROCOPT=GOx. 
•	Specific to the examples in this document:  Children segments are not read in DB sequence or PSB sequence.  
•	Multiple Position is required for the calls to work. 
•	An unqualified GNP call reading all children was not used because the PSB might contain segments that are not needed on the initial read. 
•	Reading a list of roots can not be done using a PSB that allows UOW processing via PROCOPT H or P for FasthPath.    Status code of GC results in an abort of the getBunchOfSegments command.  
•	If the PSB allows update, this call should only be used at the beginning of a logical unit of work or at the beginning of transaction.   
•	Long synonym chains without a limit can result performance issues. 

These notes are specific to CICS threads
•	Can cause performance issues if too many segments are read and the FastPath NBA buffers run short, triggering excessive buffer stealing.   
•	Reading too many roots in different RAP can exhaust the number of buffers