Copyright ã1992 by Leland Stanford Jr. University.  All Rights Reserved.

HashFile

Inherits From:	HashTable

Declared In:	HashFile.h

Defined By:	C.D. Lane (lane@sumex-aim.stanford.edu)

Class Description

HashFile implements a bridge between the hashed database library functions, db(3) (used to implement the 'defaults' database and Digital Librarian index files), and the HashTable object.  It can be viewed as an alternate interface to the database library functions or as a type of HashTable that survives program execution.

Except for initial object creation, methods are a superset of those provided by HashTable and a HashFile can be substituted for a HashTable in most code.  In order to maintain this similarity, the database file is closed when the free method is called on the HashFile object, rather than having a separate method.

Database files created using the HashFile object can be manipulated using the utilities dbCatenate, dbCompare, dbDescribe etc. on /usr/lib/database (see dbCatenate(1)).

The HashFile object uses a HashTable object as a buffer to optimize multiple access to keys/values.  Keys and values can be of type id, int, void *, char *, or any other 32-bit quantity that can be described by a type string and handed to NXReadType().  Descriptions must be invariant strings and are restricted to encode 32-bit quantities, typically the following:

	ª@º (id), ª*º (char *), ªiº (int)

Note that the ª!º (other) type that HashTable accepts doesn't really make sense here as it has a different meaning to NXReadType().  Also, when using type id, "@", for keys, objects that have the same content, though still distinct, are still mapped into the same database file entry, thus not making for very useful keys.  For hash files, the printed representations of the keys, not their pointers, are compared for equality.

When the description is ª%º, hashing and equality are same as for ª*º.  On reading, however, the string is uniqued, using the NXUniqueString() function.

HashFiles must generally meet the same restrictions that a HashTable must satisfy.

Since the initFromFile: method will create a database file if one doesn't exist, the factory method isHashFile: can be used to determine if a file exists before opening it.

Instance Variables

Database *db;
Data d;
const char *filename;
BOOL readOnly;

db 	open Database descriptor

d 	Data structure for accessing database file

filename 	Database name

readOnly 	Boolean indicating if database compressed or readonly

Method Types

Initializing and freeing a HashFile
- initFromFile:
- initFromFile:keyDesc:
- initFromFile:KeyDesc:valueDesc:
+ isHashFile
- free
- freeObjects
- freeKeys:values:
- empty

Copying a HashFile	- copyFromZone:

Manipulating table associations	- count
- isKey:
- valueForKey:
- insertKey:value:
- removeKey:

Iterating over all associations	- initState
- nextState:key:value:

Archiving	- read:
- write:

Class Methods

isHashFile:
+ (BOOL) isHashFile:(const char *) classObject

Returns true if database name exists (i.e., if directory and leaf files name.[DL] exist).

Instance Methods

copyFromZone:
- copyFromZone:(NXZone *) zone

Returns a new HashFile.  Memory for the new HashFile is allocated from zone.  Keys nor values are copied.    Not implemented.

count
- (unsigned int) count

Returns the number of objects in the database (>= the HashTable buffer's count).

empty
- empty

Empties the database file and HashTable buffer.

free
- free

Closes the database, closing the directory and leaf files name.[DL] and flushing any unwritten data to disk.  Deallocates the HashTable buffer, but not the objects in it.

freeKeys:values:
- freeKeys:(void (*)(void *)) keyFunc values:(void (*)(void *)) valueFunc

Conditionally deallocates the HashFile's associations but does not deallocate the table itself.  Not implemented.

freeObjects
- freeObjects

Deallocates every object in the HashTable buffer, but not the HashTable itself.  Strings are not recovered.  Has no effect on the database file.  To empty the database file, use the empty method.

initFromFile:
- initFromFile:(const char *) name

Initializes a new HashFile object that maps objects to objects, creating the directory and leaf files name.[DL] if they don't already exist.  Returns self on success and nil on failure.

See also:  - initFromFile:KeyDesc:key:value:

initFromFile:KeyDesc:
- initFromFile:(const char *) name KeyDesc:(const char *) aKeyDesc

Initializes a new HashFile object that maps keys as described with aKeyDesc to objects.  Returns self on success and nil on failure.

See also:  - initFromFile:KeyDesc:key:value:

initFromFile:KeyDesc:valueDesc:
- initFromFile:(const char *) name KeyDesc:(const char *) aKeyDesc valueDesc:(const char *) aValueDesc

Initializes a new HashFile object that maps keys and values as described with aKeyDesc and aValueDesc.  Returns self on success and nil on failure.

initState
- (NXHashState) initState

Returns an NXHashState structure that's required when iterating through the HashFile.  Iterating through all associations of a database file involves setting up an iteration state, conceptually private to HashFile, and then progressing until all entries have been visited.  An example of counting associations in a table follows:

unsigned int count = 0; 
const   void  *key, *value; 
NXHashState  state = [hashfile initState];

while ([hashfile nextState:&state key:&key value:&value]) count++;

initState begins the process of iteration through the database.  You cannot have multiple NXHashState instances active on the same HashFile at the same time.

See also:  - nextState:key:value:

insertKey:value:
- (void *) insertKey:(const void *) aKey value:(void *) aValue

Adds or updates a key and value pair, as specified by aKey and aValue.  If aKey is already in the hash table, it's associated with aValue and its previously associated value is returned.  Otherwise, insertKey:value: returns (void *) nil on failure (eg. if database is read-only).

See also:  - removeKey:

isKey:
- (BOOL) isKey:(const void *) aKey

Returns YES if aKey is in the table, otherwise NO.

See also:  - valueForKey:

nextState:key:value:
- (BOOL) nextState:(NXHashState *) aState
key:(const void **) aKey
value:(void **) aValue

Moves to the next entry in the database and provides the addresses of pointers to its key/value pair.  No count, insertKey: isKey: removeKey: or valueForKey: should be done while iterating.  The order followed is uninteresting, being determined by a hash function.  Returns NO when there are no more entries in the table; otherwise, returns YES.  If there are no more entries, aKey and aValue are set to NULL.  The values and keys are not entered into the HashTable buffer.

See also:  - initState

read:
- read:(NXTypedStream *) stream

Reads the HashFile from the typed stream stream.  Returns self.  Not implemented.

See also:  - write:

removeKey:
- (void *) removeKey:(const void *) aKey

Removes the hash file entry identified by aKey.  Always returns (void *) nil (unfortunately).

See also:  - insertKey:value:

valueForKey:
- (void *) valueForKey:(const void *) aKey

Returns the value mapped to aKey.  Returns nil on failure (eg. if aKey is not in the database).

See also:  - isKey:

write:
- write:(NXTypedStream *)stream

Writes the HashFile to the typed stream stream.  Returns self.  Not implemented.

See also:  - read:

References

This document is derived from the following NeXT documents in /NextLibrary/Documentation:

	NextDev/GeneralRef/03_Common/Classes/HashTable.rtf
	
	ManPages/man3/db.3

	ManPages/man1/dbCatenate.1