Copyright ©1995 by NeXT Computer, Inc. All Rights Reserved.
IXRecordManager |
Inherits From: | Object | |
Conforms To: | IXBlockAndStoreAccess IXNameAndFileAccess IXRecordWriting IXTransientAccess IXTransientMessaging | |
Declared In: | indexing/IXRecordManager.h |
Class Description |
IXRecordManager is a record manager based on the Objective C run-time system; it stores objects in an IXStore, and maintains indexes on programmer-defined attributes. Attributes are defined in terms of the return values of messages sent to the stored objects. The stored objects can be retrieved by persistent identifiers, by their attribute values, or by posing a question with IXAttributeQuery, a class that defines a declarative query language for IXRecordManager and other Indexing Kit classes.
Storing Records IXRecordManager archives, or passivates, an object by writing its data into an IXBTree record. Two archiving mechanisms are provided: Objective C archiving, as performed by the standard read: and write: methods, and serialization, a very fast transcription mechanism that writes or reads an object's instance variables directly into or out of storage. An object will be serialized instead of archived if it conforms to the IXRecordTranscription protocol. For the purpose of serialization, a data type can be serialized if its length can be unambiguously determined from its type declaration and its physical representation; this includes all scalar ANSI C data types, pointers to character strings (which are assumed to be null-terminated), and fixed length arrays of the preceding kinds of data types. IXRecordManager defines a mechanism for storing and retrieving amorphous data items, called blobs, that aren't susceptible to structural serialization due to unknown length or complexity. Some examples of blobs are compressed sounds, serialized graph structures, and relocatable code modules. Before serializing an object that conforms to the IXRecordTranscription protocol, IXRecordManager sends it a source:willWriteRecord: message, giving the object an opportunity to prepare itself for passivation, or to request the IXRecordManager to write its unserializable data as blobs. When a record is deserialized, or activated, the IXRecordManager sends source:didReadRecord: to it. Blobs are identified by name and record handle. This provides a means of maintaining lists of named properties on behalf of transcribed records. There is no way of iterating over the property names or of getting a list of all blob names for an object, so objects should store their own such lists in a well-known blob if the list membership can't be determined statically. The IXRecordManager interface allows a record to be added, discarded, removed, or replaced by another record. Discarded records are treated as though they don't exist--they can't be read, for example. They will either be physically removed when the repository is cleaned, or explicitly reclaimed by the caller. The facility for discarding records is designed to support lazy index maintenance; references to discarded records may safely be allowed to remain in the inversions until the repository is cleaned. Record discarding also provides a form of disaster recovery when add and discard operations are used instead of replacement.
Indexing Records IXRecordManager allows attributes to be defined by name and method, such as "EmployeeName" with the method given by @selector(empName). The value of an attribute for a given record is the value returned when the attribute's message is sent to that record. If a record doesn't respond to the message, then the attribute isn't defined for that record. By default, an attribute is defined for every record that responds to its message; its scope may be further restricted to those records that are instances of a specific class or subclasses of that class. Here's an example of setting up an attribute for employees by full name (with a method empName that returns a character string), and restricting it to instances of MyEmployeeRecord and its subclasses: |
[recordManager addAttributeNamed:"EmployeeName"
forSelector:@selector(empName)];
[recordManager setTargetClass:[MyEmployeeRecord class]
forAttributeNamed:"EmployeeName"];
IXRecordManager maintains an index for each of its attributes; the index is an inversion of the attribute's value over all of the records for which it's defined. An attribute index is an IXBTree managed by an IXPostingCursor; IXRecordManager determines the comparator for the IXBTree by examining the return type of the attribute's selector. The default comparator can be overridden (as would be necessary for methods that returned structures or unions) with the setComparator:andContext:forAttributeNamed: or setComparisonFormat:andContext:forAttributeNamed: methods. In the example given above, the default comparator would be IXCompareStrings, since empName is defined as returning a string. For more information on comparators, see the IXComparatorSetting and IXComparisonSetting protocol specifications.
The IXAttributeParser class can be used to index string-valued attributes under each of the separate lexemes (words or other useful units of text) in a string, instead of using the entire string as the value. The setParser:forAttributeNamed: message assigns a parser that will break the selector's return value into its constituent words. If the attribute in the example above were based on a method that returns a text string containing unstructured, miscellaneous notes, then assigning a parser might be appropriate. Using the default parser configuration for English, an employee record with the note "Has three kids named Bobby, Judy and Sam" would be recorded in the index under the values "Has," "three," "kid," "named," "Bobby," "Judy," and "Sam." Note that "and," being considered a noise word in English, isn't included, and that the plural "kids" was reduced to "kid." See the IXAttributeParser and IXAttributeReader class specifications for more information on parsers.
Retrieving Records References to records are stored as postings in the attribute indexes. A posting is a reference identifier plus its weight (a measure of its frequency or importance in the index). Any index can be examined through an IXPostingCursor returned by cursorForAttributeNamed:. A new copy of the cursor is returned for each invocation of this method, so the sender should free each copy when it's no longer needed. The basic cursoring techniques described in the IXCursorPositioning protocol specification can be used to locate references to all of the records having a given value for the attribute, or to iterate over the set of existing values for the attribute. As described in the IXPostingSet class specification, an IXPostingSet can be used to retrieve sets of postings directly from the IXPostingCursor, and can combine those sets in various ways. References to records for a range of attribute values can be collected using one IXPostingCursor and one IXPostingSet. See the IXPostingSet class specification for an example. IXPostingSets built against different attributes can be combined to resolve multi-attribute queries. For example, all employees with a last name of "Draper" and a salary of at least $60,000 could be found by collecting the appropriate postings from the EmployeeName and Salary attributes into two separate IXPostingSets, and intersecting the results. Another Indexing Kit class, IXAttributeQuery, resolves declarative queries expressed in a functional language against instances of IXRecordManager and other classes using these techniques. |
Instance Variables |
None declared in this class. |
Adopted Protocols |
IXBlockAndStoreAccess | initInStore: |
initFromBlock:inStore: freeFromStore + freeFromBlock:inStore: getBlock:andStore: |
IXNameAndFileAccess | initWithName:inFile: |
initFromName:inFile: freeFromStore + freeFromName:inFile: getName:andFile: |
IXRecordWriting | addRecord: |
removeRecord: replaceRecord:with: empty count readRecord:fromZone: |
IXTransientAccess | getOpaqueValue:ofIvar:forRecord: |
getIntValue:ofIvar:forRecord: getFloatValue:ofIvar:forRecord: getDoubleValue:ofIvar:forRecord: getStringValue:ofIvar:forRecord: getStringValue:inLength:ofIvar:forRecord: getObjectValue:ofIvar:forRecord: |
IXTransientMessaging | getOpaqueValue:ofMessage:forRecord: |
getIntValue:ofMessage:forRecord: getFloatValue:ofMessage:forRecord: getDoubleValue:ofMessage:forRecord: getStringValue:ofMessage:forRecord: getStringValue:inMessage:ofIvar:forRecord: getObjectValue:ofMessage:forRecord: |
Method Types |
Adding and removing attributes | addAttributeNamed:forSelector: |
hasAttributeNamed: removeAttributeNamed: attributeCount |
Key comparison | setComparisonFormat:forAttributeNamed: |
comparisonFormatForAttributeNamed: setComparator:andContext:forAttributeNamed: getComparator:andContext:forAttributeNamed: |
Setting attribute targets | setTargetClass:forAttributeNamed: |
getTargetName:andVersion:forAttributeNamed: |
Accessing attributes | cursorForAttributeNamed: | |
Getting attribute information | selectorForAttributeNamed: |
attributeNames |
Accessing classes | classNames |
attributeNamesForClass: recordsForClass: |
Discarding records | discardRecord: |
reclaimRecord: discards clean |
Setting attribute descriptions | setDescription:forAttributeNamed: |
getDescription:forAttributeNamed: |
Setting parsers | setParser:forAttributeNamed: |
parserForAttributeNamed: |
Writing blobs | setValue:andLength:ofBlob:forRecord: |
getValue:andLength:ofBlob:forRecord: |
Instance Methods |
addAttributeNamed:forSelector: |
addAttributeNamed:(const char *)aName forSelector:(SEL)aSelector |
Creates an attribute for records that respond to aSelector, associates it with name aName, and builds an index for that attribute. Note that records already passivated by the IXRecordManager that respond to aSelector are not added to the new index automatically. This may change in a future release. If an attribute already exists with name aName, returns nil; otherwise returns non-nil.
See also: removeAttributeNamed:, selectorForAttributeNamed: |
attributeCount |
(unsigned int)attributeCount |
Returns the number attributes defined for the IXRecordManager.
See also: count |
attributeNames |
(char *)attributeNames |
Returns a newline-separated list of the names of all attributes in the IXRecordManager. The sender of this message is responsible for freeing the string returned.
See also: addAttributeNamed:forSelector: |
attributeNamesForClass: |
(char *)attributeNamesForClass:aClass |
Returns a newline-separated list of the names of all of the attributes maintained by the IXRecordManager that are defined for instances of aClass. This includes all of the attributes whose selectors are recognized by instances of aClass, and whose target class is aClass or one of its superclasses. The sender of this message is responsible for freeing the string returned.
See also: setTargetClass:forAttributeNamed: |
classNames |
(char *)classNames |
Returns a newline-separated list of the names of all the classes that have instances stored in the IXRecordManager. The sender of this message is responsible for freeing the string returned. |
clean |
clean |
Removes all discarded records from the receiver. Those records will no longer be reclaimable. Returns self.
See also: discardRecord:, reclaimRecord:, empty (IXRecordReading protocol) |
comparisonFormatForAttributeNamed: |
(const char *)comparisonFormatForAttributeNamed:(const char *)aName |
Returns a string defining the comparison format of keys in the index named aName, or NULL if one hasn't been set. This is a string encoding the Objective C data types that comprise the key; for example, "[3i]" describes an array of 3 integers. An IXBTree uses this format to determine how to compare keys. For more information on comparison formats, see the IXComparisonSetting protocol specification.
See also: setComparisonFormat:forAttributeNamed:, getComparator:andContext:forAttributeNamed: |
count |
(unsigned int)count |
Returns the number of records stored in the IXRecordManager, plus the number of attributes defined. To get just the number of records, subtract the return value of attributeCount from the return value of this method.
See also: attributeCount, count (IXRecordWriting protocol) |
cursorForAttributeNamed: |
(IXPostingCursor *)cursorForAttributeNamed:(const char *)aName |
Returns an IXPostingCursor that addresses the index for the attribute named aName. This cursor can be used to find references to records having a given value for the attribute. For more information on using cursors, see the IXCursorPositioning protocol specification, and the IXPostingCursor class specification.
This method returns a copy of a private cursor each time it's invoked, so your code should free the copy when it's no longer needed. |
discardRecord: |
discardRecord:(unsigned int)aHandle |
Discards the record identified by aHandle, so that the record can't be read, removed or replaced. reclaimRecord: retrieves discarded records, and clean removes all discarded records. Returns self.
See also: reclaimRecord:, clean, discards, removeRecord: (IXRecordWriting) |
discards |
(IXPostingList *)discards |
Returns an IXPostingList containing all records that have been discarded (by sending discardRecord: to the IXRecordManager). This IXPostingList can be used to reclaim the discarded records with reclaimRecord:.
If the IXRecordManager is asked to read a discarded record (with the IXRecordReading protocol's readRecord:FromZone: method), the result will be nil; for most purposes the record no longer exists. However, discarded records will still have references in the IXRecordManager's attribute indexes. If your code doesn't deal gracefully with nil records, you can filter posting sets before using them by subtracting the discards from them. See also: discardRecord:, reclaimRecord:, clean |
getComparator:andContext:forAttributeNamed: |
getComparator:(IXComparator **)aComparator |
andContext:(const void **)aContext forAttributeNamed:(const char *)aName |
Returns by reference the function used to compare attribute values, and the context associated with that function, for the attribute named aName. If the attribute has a comparison format set instead, the comparator and context will be NULL. A comparator function takes two data items and returns an answer indicating whether the first is less than, equal to, or greater than the second. The context is arbitrary data for use by that function. Returns self.
For more information on comparators, see the IXComparatorSetting protocol specification and the IXBTree class specification. See also: setComparator:andContext:forAttributeNamed:, comparisonFormat:forAttributeNamed: |
getDescription:forAttributeNamed: |
getDescription:(char **)aDescription forAttributeNamed:(const char *)aName |
Returns by reference the description for the attribute named aName. The description can be used to record extra information pertaining to the attribute. Returns self.
See also: setDescription:forAttributeNamed:, addAttributeNamed:forSelector: |
getTargetName:andVersion:forAttributeNamed: |
getTargetName:(const char **)aName |
andVersion:(unsigned int *)targetVersion forAttributeNamed:(const char *)aName |
Returns by reference the name and version of the class that the attribute named aName is defined for, or NULL and 0 if none has been set. If an attribute has a target class set, it will be defined only for records of that class or a subclass. Returns self.
See also: setTargetClass:forAttributeNamed: |
getValue:andLength:ofBlob:forRecord: |
(BOOL)getValue:(void **)aValue |
andLength:(unsigned int *)aLength ofBlob:(const char *)blobName forRecord:(unsigned int)aHandle |
Returns by reference the value and length of blobName for the record identified by aHandle. Returns YES if the blob is successfully retrieved, NO if it isn't.
Note: Your application should use the NXSwapBigTypeToHost() function to convert the byte-order of the retrieved blob data to that of the machine it's running on. See also: setValue:andLength:ofBlob:forRecord: |
hasAttributeNamed: |
(BOOL)hasAttributeNamed:(const char *)aName |
Returns YES if the IXRecordManager has an attribute named aName, NO if it doesn't. |
parserForAttributeNamed: |
(IXAttributeParser *)parserForAttributeNamed:(const char *)aName |
Returns the parser, if any, assigned to the attribute named aName. The parser will break the return value of the attribute's selector into separate words when the attribute is evaluated.
See also: setParser:forAttributeNamed: |
reclaimRecord: |
reclaimRecord:(unsigned int)aHandle |
Reclaims a record previously discarded with discardRecord:. aHandle is the identifier of the discarded record. A discarded record must be reclaimed in order to access it or remove it completely from the archive (although clean removes all discarded records at once). Returns self.
See also: discardRecord:, discards, clean |
recordsForClass: |
(IXPostingList *)recordsForClass:aClass |
Returns an IXPostingList containing all of the records in the IXRecordManager that are direct instances of aClass (and not of any subclasses of aClass). |
removeAttributeNamed: |
removeAttributeNamed:(const char *)aName |
Removes the attribute named aName from the IXRecordManager. Records referenced by the attribute's index aren't affected. Returns self.
See also: addAttributeNamed:forSelector: |
selectorForAttributeNamed: |
(SEL)selectorForAttributeNamed:(const char *)aName |
Returns the selector for the message that defines the attribute named aName. Unless the attribute is restricted to a specific class, this message is sent to any record that responds to it in order to evaluate the attribute. Otherwise it's only sent to records of the attribute's target class (or a subclass of the target class).
See also: addAttributeNamed:forSelector: |
setComparator:andContext:forAttributeNamed: |
setComparator:(IXComparator *)aComparator |
andContext:(const void *)aContext forAttributeNamed:(const char *)aName |
Sets the function used to compare attribute values, and the context associated with that function, for the attribute named aName. A comparator function should accept two data items and return an answer indicating whether the first is less than, equal to, or greater than the second. The context is arbitrary data for use by that function. Returns self.
For more information on comparators, see the IXComparatorSetting protocol specification and the IXBTree class specification. See also: getComparator:andContext:forAttributeNamed:, setComparisonFormat:forAttributeNamed: |
setComparisonFormat:forAttributeNamed: |
setComparisonFormat:(const char *)aFormat forAttributeNamed:(const char *)aName |
Installs a string defining the comparison format of keys in the index named aName. This is a string encoding the Objective C data types that comprise the key; for example, "[3i]" describes an array of 3 integers (although the length is currently ignored). An IXBTree uses this format to determine how to compare keys. For more information on comparison formats, see the IXComparisonSetting protocol specification.
See also: comparisonFormat:forAttributeNamed:, setComparator:andContext:forAttributeNamed: |
setDescription:forAttributeNamed: |
setDescription:(const char *)aDescription forAttributeNamed:(const char *)aName |
Sets the description for the attribute named aName to aDescription. The description can be used to record extra information pertaining to the attribute. Returns self.
See also: getDescription:forAttributeNamed: |
setParser:forAttributeNamed: |
setParser:(IXAttributeParser *)aParser forAttributeNamed:(const char *)aName |
Assigns the parser aParser to the attribute named aName. The parser will break the return value of the attribute's selector into separate words when the attribute is evaluated. Returns self.
See also: parserForAttributeNamed: |
setTargetClass:forAttributeNamed: |
setTargetClass:aClass forAttributeNamed:(const char *)aName |
Sets the target class for the attribute named aName to aClass. The attribute will be defined only for instances of class aClass or any of its subclasses. Your code should set the target class before any records have been added to the IXRecordManager; otherwise, the index for the named attribute may collect references to instances of other classes before the restriction is imposed. This behavior may change in a future release, so that records that aren't of aClass are removed from the index when the target class is set. Returns self.
See also: getTargetName:andVersion:forAttributeNamed: |
setValue:andLength:ofBlob:forRecord: |
(BOOL)setValue:(const void *)aValue |
andLength:(unsigned int)aLength ofBlob:(const char *)blobName forRecord:(unsigned int)aHandle |
Stores the value and length of a blob for the record identified by aHandle, associating it with the name blobName. Returns YES if the blob is successfully stored, NO if it wasn't.
If aLength is 0, the blob won't be stored, and this method will return NO. Note: Your application should use the NXSwapHostTypeToBig() function before invoking this method, to convert the byte-order of the key to big-endian (the standard byte-order for the Indexing Kit). See also: getValue:andLength:ofBlob:forRecord: |