× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.


  • Subject: Re: User Index APIs
  • From: "Simon Coulter" <shc@xxxxxxxxxxxxxxxxx>
  • Date: Tue, 03 Feb 98 20:54:02 +1100




//--- forwarded letter -------------------------------------------------------
> X-Mailer: Novell GroupWise 4.1
> Date: Mon, 02 Feb 98 14:34:31 -0700
> From: "David Morris" <dmorris@plumcreek.com>
> To: MIDRANGE-L@midrange.com
> Reply-To: MIDRANGE-L@midrange.com
> Subject: User Index APIs

> 
> We have several procedures that use the user index APIs.  They are used to 
>create and store 
variable length keyed information.  They work correctly but the API that 
retrieves entries seems to 
pass back conflicting length and offset information.  IE:  Place 12 bytes of 
information with an 
offset of 0 on the user index.  The key is 8 bytes, and the data is 4 bytes.  
Retrieve the entry by 
equal key and the bytes available and returned are both 16.  The offset and 
length returned are 8 
and 12.   The four byte entry is in positions 17-20.  What are the available 
and returned saying?  
By ignoring the available and returned parameters it seems to work as expected. 
 I cannot find any 
example to see where we have misinterpreted the parameters.
> 
> Does anyone have an example which uses a variable length user index?  I 
>remember an article a few 
years back in one of the magazines that used user indexes to print a sorted 
report.  I don't 
remember if it used fixed or variable length entries.  The code we are using 
was based on trial and 
error testing.  It works for the 8 user indexes that we have but it would be 
nice to understand what 
is going on.
> 
> This application used to use data queues but there was a noticeable impact on 
>performance when the 
length of the information varied by more than about 50%.  Variable length 
fields in a database 
probably would have worked fine but we decided that the user index would 
require the least 
conversion.  After spending a day trying to understand the returned parameters 
it probably would 
have been a wash.
> 
> Thanks for any input,
> 
> David Morris
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>                                                                               
>             

Without seeing your code it is a little difficult to tell however I think you 
are just 
misinterpreting the data.

There are two sets of BytesAvailable and BytesReturned; one set is in the 
IDXE0100 format which 
comes back in your receiver variable (RcvVar), the other set is in the Entry 
Lengths and Offsets 
structure (EntOff).

The two sets are necessary because you provide two related but separate storage 
areas to the API. 
One for the actual index entries and one for the offsets and lengths (or 
description) of the 
entries.

For the first set BytesAvailable is the size of the index entry multipied by 
the number of entries 
returned.  BytesReturned is how much the API could give you.  This should be 
equal to or less than 
the value of the second parameter (RcvVarLen).  If BytesReturned is less than 
the value of RcvVarLen 
then BytesAvailable should be equal to BytesReturned; this is how you know you 
have received all the 
data.  If BytesAvailable is greater than BytesReturned then you know the space 
you provided was too 
small.

For the second set BytesAvailable is the amount of data describing the entries 
which could be 
returned if you provided enough space.  (This is always a multiple of 8).  
BytesReturned is the 
amount actually provided.  This will be less than or equal to the value of the 
fourth parameter 
(EntOffLen).  If BytesReturned is less than or equal to the value of 
BytesAvailable you know you 
have descriptions for all the entries in RcvVar.

The ideal situation is to ensure that you provide enough space in EntOff to 
describe all the entries 
in RcvVar.  However, because the entries themselves are variable in length it 
is impossible to 
formulate a relationship between the sizes of theses areas.  That is why both 
areas have their own 
available and returned values.

Your code is supposed to check both sets of values to:
A) know whether all the entries were returned
and
B) whether what was returned is described -- if you have no length/offset value 
for an entry you 
can't get to it.

So for your situation I think you will find that the BytesAvailable and 
BytesReturned values of 16 
refer to the length/offset space which has the following structure:
        1 EntOff
                2 BytesAvailable bin(4)
                2 BytesReturned bin(4)
                2 FirstEntryLength bin(4)
                2 FirstEntryOffset bin(4)
for a total of 16-bytes.

You should also find that the BytesAvaliable and BytesReturned in the RcvVar 
structure reflect the 
proper values i.e., BytesAvailable = 20 and BytesReturned = 20
        1 RcvVar
                2 BytesAvailable bin(4)
                2 BytesReturned bin(4)
                2 FirstEntry char(12)
                        3 FirstEntryKey char(8)
                        3 FirstEntryValue char(4)

Perhaps a diagram will help (excuse the poor graphics):

Assume a key of 'ABCDEFGH' -- 8 bytes; and a value of 1234 -- 4 bytes.  The 
receiver variable and 
entry offset structure will contain the following values:

RcvVar : | 20 | 20 | ABCDEFGH | 1234 |

EntOff : | 16 | 16 | 8 | 12 |

The code checks that we have all the entries by comparing RcvVar.BytesAvailable 
with 
RcvVar.BytesReturned.  It also checks that we can access all the entries via 
there offsets by 
comparing EntOff.BytesAvailable with EntOff.BytesReturned.  If these values are 
OK (Note that you 
can do partial processing based on the returned length/offset values and then 
fetch the rest) then 
we start processing the RcvVar entries. See how the value of 
EntOff.FirstEntryOffset is the number 
of bytes from the start of RcvVar to the FirstEntry subfield? The value of 
EntOff.FirstEntryLength 
is the number of bytes used by the FirstEntry subfield.

Now, in the normal course of events you would not use static structures as 
above.  You would use a 
based structure and increment the pointer (on which the structure is based) by 
the offset and 
extract the data according to the length.  That way you are not tied to the 
structure of the data.

DCL 1 RcvVar CHAR(2567),
        2 BytesAvailable BIN(4),
        2 BytesReturned BIN(4)
        2 Start CHAR(1);

DCL 1 EntOff CHAR(64),  /* Should be multiple of 8 -- here room for 7 
descriptions */
        2 BytesAvailable BIN(4),
        2 BytesReturned BIN(4),
        2 Start CHAR(1);

DCL SPP @PtrToRcvVar:
DCL SPP @PtrToEntry;
DCL SPP @PtrToOffset;

DCL 1 EntryStruct CHAR(256) BASED(@PtrToEntry),  /* Assuming 256-bytes is the 
largest entry */
        2 IdxEntryKey CHAR(8), /* Note that the key portion is always a fixed 
size */
        2 IdxEntry CHAR(248);  /* Enough room for the largest data entry - not 
really required */

DCL 1 OffsetStruct BASED(@PtrToOffset),
        2 EntryLen BIN(4),
        2 EntryOffset BIN(4);

/* Check that we have enough descriptions and entries */
IF RcvVar.BytesAvailable <> RcvVar.BytesReturned
  /* do something about it */
END;

IF EntOff.BytesAvailable <> EntOffBytesReturned
  /* do something about it */
END;

@PtrToRcvVar = ADDR(RcvVar); /* Point to start of the receiver variable */
@PtrToOffset = ADDR(EntOff.Start); /* Point to the start of the len/off values 
*/

DO NbrEntries; /* Returned by the API */

@PtrToEntry = @PtrToRcvVar + EntOff.EntryOffset;
/* First time through EntryStruct is providing a view of the first entry */

/* do something with the data: EntryStruct.IdxEntryKey references the key value 
*/
/*                             EntryStruct.IdxEntry references the entry value 
*/
/*                             OffsetStruct.EntryLen is the total size of the 
entry */

@PtrToOffset = @PtrToOffset + SIZEOF(OffsetStruct); /* Point to next entry 
description */
/* Next time through loop we get the next entry */
ENDDO;

Clear as mud, eh?

Regards,
Simon Coulter.

//----------------------------------------------------------
// FlyByNight Software         AS/400 Technical Specialists
// Phone: +61 3 9419 0175      Mobile: +61 3 0411 091 400
// Fax:   +61 3 9419 0175      E-mail: shc@flybynight.com.au
// 
// Windoze should not be open at Warp speed.
 

+---
| This is the Midrange System Mailing List!
| To submit a new message, send your mail to "MIDRANGE-L@midrange.com".
| To unsubscribe from this list send email to MIDRANGE-L-UNSUB@midrange.com.
| Questions should be directed to the list owner/operator: david@midrange.com
+---


As an Amazon Associate we earn from qualifying purchases.

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.