%Library.FunctionalIndexabstract index class %Library.FunctionalIndex
An index is a structure maintained by a persistent class that is intended to be used to optimize certain queries and other functions. Cache Objects supports three primary types of indexes - regular, bitmap and key structures. The index type is defined by two index keywords, TYPE and EXTENT. It is also possible to declare a type class for an index. This index type class is expected to implement the index type class interface as defined by this class. The classtype of the index type class is expected to be INDEX.
Functional Indexing is the feature in Cache Objects that allows a user to implement a class that maintains an index structure and a function that can be used by SQL to resolve certain SQL query operators. A Functional Index class must implement two interfaces. The first interface is the index filing interface, the second is the query interface used by SQL.
Index Filing Interface
The Index Filing Interface consists of six methods. The three methods that implement instance filing, InsertIndex, UpdateIndex, and DeleteIndex accept a formal argument corresponding to the ID of the object (ROWID of the row) being filed and a variable number of arguments corresponding to the indexed properties and clustered data properties. The UpdateIndex method accepts two sets of indexed properties as arguments, the first set corresponds to the new indexed property values and the second the existing set of indexed property values. All arguments other than the ID are accessed using the formal argument pArg with a subscript corresponding to the actual argument's position. For example, the following index:
index x1F on (Name, DOB, Home_City) as User.MyIndexClass [ data=(Name,BirthPlace)];
The Query Interface consists of at least one method that is projected to SQL as a function. Arguments of this function should be limited to the set of index properties.
Index Dictionary Metadata
When implementing a functional index class it is sometimes necessary to access the compiled class dictionary metadata. The class compiler will not have generated a specific global location for the functional index. That is the responsibility of the functional index class. When you need a global location for a functional index the convention is to use the defined global location values from the storage definition but the details of exactly what global location will be used by the index are left to the functional index class.
Subvalue IndexingSubvalue indexing occurs when an index property specification includes either (ELEMENTS) or (KEYS). These references trigger the filers to determine the set of subvalues, either by the fact that the property involved is a collection or there is a user-implemented BuildValueArray method. The filers then iterate over the subvalues and file the index. In the case of an update, the set of existing subvalues are first deleted from the index and the set of new subvalues is filed.
Functional Indexes continue with this behavior with the index filing method simply performing the work needed to place one subvalue into the index. The Objects and SQL filers will continue to determine the set of subvalues, both existing and new, and call the Functional Index interface iteratively.
When the index structure includes subvalues but there is no declaration in the index property specifications then it is entirely up to the Functional Index implementation to determine the set of subvalues and to provide the necessary subvalue iterators. The Objects and SQL filers will invoke the Functional Index filer with existing and new values as if the index is on the entire property value.
This method is invoked when an existing instance of a class is deleted. classmethod Find(pSearch As %Binary) as %Library.Binary [ SQLProc = ]
classmethod InsertIndex(pID As %CacheString, pArg... As %Binary)
This method is invoked when a new instance of a class is inserted into the database. classmethod PurgeIndex()
classmethod SegmentFinalize(ByRef pIndexBuffer As %CacheString, pStartID As %CacheString, pEndID As %CacheString)
This method is called when the index builder is finalizing a segment. Use this method to implement any segment cleanup work or to complete the filing of the segment. Parallel index builds typically construct segments of the index in memory and this method is a good place to copy temporary structures to the permanent index structure. classmethod SegmentInitialize(ByRef pIndexBuffer As %CacheString, pStartID As %CacheString, pEndID As %CacheString)
This method is called by the parallel index build to initialize an index segment when constructing index entries for one segment of the extent. Parallel index builds typically construct indexes in memory for segments of 64k instances/rows. classmethod SegmentInsert(ByRef pIndexBuffer As %CacheString, pID As %CacheString, pArg... As %Binary)
classmethod SortEndIndex(pCommit As %Integer = 1)
classmethod UpdateIndex(pID As %CacheString, pArg... As %Binary)
This method is invoked when an existing instance of a class is updated.