Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Btree.Read reads a node of an indexed file (a ! or bang file) into a dimensioned array. It can be called in the Char event of a window to return an entry in the ! file (such as the next entry starting with a character of group of characters) without having to perform an index read, as a Btree.Extract call would. See the example below.

...

Caution: Both of these techniques could result in your program missing records or in your program processing the same record twice.

See also

Btree.ExtractExtract_SI_KeysIXLOOKUP eventUpdate_IndexCollect.IXVals()

Example: Traversing the Index

Code Block
/* This program searches the CUSTOMER_NAME_XREF index using BTREE.READ 
and returns all records that have an indexed value between "CASH" and "THOMPSON". */
DECLARE SUBROUTINE BTREE.READ, FSMSG
EQU TRUE$ TO 1
EQU FALSE$ TO 0
EQU NULL$ TO ""
DIM I_RECORD(5)
MAT I_RECORD = NULL$
I = NULL$
SEP = NULL$
FOUND = NULL$
I_FILEVAR = NULL$
FIELD = "CUSTOMER_NAME_XREF"
VALUE = "CASH"
MAX_VALUE = "THOMPSON"
/* Get the sort information from the index.*/
SORT_METHOD = XLATE("!CUSTOMERS", FIELD, 1, "X")
  OPEN "!CUSTOMERS" TO INDEX_FILE ELSE
  FSMSG()
return 1
END
OPEN "CUSTOMERS" TO CUSTOMER_FILE ELSE
  FSMSG()
  RETURN 2
END
LOCKED = FALSE$
LOOP
  LOCK INDEX_FILE, FIELD:"*ROOT" THEN
  LOCKED = TRUE$
END
  UNTIL LOCKED
REPEAT

BTREE.READ(INDEX_FILE,FIELD,VALUE,SORT_METHOD,MAT I_RECORD,I,SEP,FOUND)

/* Find the starting position in the key list in element five of the index leaf record. */
IF I > 1 THEN
  POS = INDEX(I_RECORD(5), @VM, I-1) + 1
END ELSE
  POS = 1
END

FLAG = NULL$
DONE = FALSE$
LOOP
/* Get the next key to process */
  REMOVE @ID FROM I_RECORD(5) AT POS SETTING FLAG
  READ @RECORD FROM CUSTOMER_FILE, @ID THEN
    GOSUB PROCESS_RECORD
  END
  IF FLAG = 3 THEN
  /* REMOVE sets FLAG to 3 when a value mark is found. 
	Finding a value mark indicates the indexed value has changed. */
    IF I_RECORD(4)<1,I> > MAX_VALUE THEN
  /* No more valid values to process. */
      DONE = TRUE$
    END
  END ELSE
    IF FLAG ELSE
   /* If flag = 0 then we have reached the end of the current leaf record 
	and it is time to read the next record or stop. */
      IF I_RECORD(2) THEN
   /* There is a pointer to another record. */
         MATREAD I_RECORD FROM INDEX_FILE, I_RECORD(2) THEN
    /* Start at the beginning of the list of keys in the new record.*/
            POS = 1
            I = 1
         END ELSE
     /* Recovery logic goes here if you're not locking the index. */
           DONE = TRUE$
        END
      END ELSE
   /* There are no more index records. */
        DONE = TRUE$
      END
   END
END
UNTIL DONE
REPEAT
UNLOCK INDEX_FILE, FIELD:"*ROOT" ELSE
  FSMSG()
  return 4
END
return 0

PROCESS_RECORD:
/* Logic to process records goes here. */
RETURN
 
RETURN 0

 

 

Example: In the Char Event

Code Block
/* The following code, in the Char event of an edit control called CITY, 
returns the name of the city closest to the letter entered by the user, in the CITY control. 
The program assumes that the CITY column in the CUSTOMERStable has a BTree index.*/
declare subroutine btree.read , set_property
dim node(5)
column = 'CITY'
entered_data = get_property( @window : '.CITY','TEXT')
open '!CUSTOMERS' TO vBangCustomers Then
    ReadV SortOrder from vBangCustomers, column, 1 Then
        pos = 0
        separator = ''
        found = 0
        call btree.read(vBangCustomers, column, entered_data, sortOrder, mat Node, Pos, separator, found)
        returned_data = node(4)<0,pos>
        returned_keys = node(5)<0,pos>
        set_property( @window : '.CITY', 'TEXT', returned_data)
    end
end
RETURN 0

...