JX Application Framework
Loading...
Searching...
No Matches
Public Member Functions | Protected Member Functions | Static Protected Member Functions | List of all members
JConstHashCursor< V > Class Template Reference

#include <JConstHashCursor.h>

Inheritance diagram for JConstHashCursor< V >:
[legend]

Public Member Functions

 JConstHashCursor (const JHashTable< V > *table)
 
 JConstHashCursor (const JHashTable< V > *table, const JHashValue hash)
 
virtual ~JConstHashCursor ()
 
bool Next ()
 
bool Next (bool(*NextRecordType)(const JHashRecord< V > &), const bool stopOnEmpty)
 
bool NextFull ()
 
bool NextOpen ()
 
bool NextHash (const bool allowEmpty=false)
 
bool NextHashOrOpen ()
 
bool NextKey (const bool allowEmpty=false)
 
bool NextKeyOrOpen ()
 
bool NextMapInsertHash ()
 
bool NextMapInsertKey ()
 
void Reset (const bool clear=false)
 
void ResetHash (const JHashValue hash)
 
void ResetKey (const V &value)
 
JHashValue GetCursorHashValue () const
 
const JHashRecord< V > & GetRecord () const
 
JHashRecordT::State GetState () const
 
bool IsEmpty () const
 
bool IsDeleted () const
 
bool IsFull () const
 
JHashValue GetHashValue () const
 
const V & GetValue () const
 

Protected Member Functions

const JHashTable< V > * GetTable () const
 
JSize GetIndex () const
 
void Step ()
 

Static Protected Member Functions

static JDualHashValue DualHash (const JHashValue hash)
 

Constructor & Destructor Documentation

◆ JConstHashCursor() [1/2]

template<class V >
JConstHashCursor< V >::JConstHashCursor ( const JHashTable< V > *  table)
JConstHashCursor is the basic cursor for JHashTable, providing the ability
to step through the hash table appropriately and read entries.  As the name
implies, it cannot modify the table; however, it can be used on a const
table.  Its subclass JHashCursor can modify its table but may not be used
on a const table.

Usage

A JCore cursor behaves like a JCore iterator, except it isn't safe; if one
cursor modifies a table while another is examining it the second cursor may
well be left in an invalid state.  In that regard it is more like a simple
array index.  Cursor usage generally fits the following stereotype:

(1) Create a cursor attached to the desired table (or reset an existing one
already attached), (2) call one of its Next... functions in a while loop,
(3) examine each record found in the loop body for some property, and
possibly (4) modify a record and then exit the loop.

For example, to examine all records with a given hash value to find one
to delete:

    JHashTable<V> table;
        ...
    JHashCursor<V> cursor(&table, hash);
    while ( cursor.NextHash() )
    {
        V value = cursor.GetValue();
        if (value == theRightValue)
        {
            cursor.Remove();
            break;
        }
    }

The break is important; after modifying the table the cursor might not
be in a valid state and must be reset before using again.  This is true
whenever the table is modified for all cursors then attached to it.

Note that the hash value was passed in--presumably the client called the
hash function or already had it on hand.  Used as shown, the table calls
neither the hash function nor the comparison function pointers at all and
is an example of purely manual use.

Topics to add:

Need example of use with hash and comparison functions

Allows passing in hash values even when key is also there for efficiency;
don't screw it up.

NextMapInsertHash, NextMapInsertKey backup is dangerous.

    Warning about moving records from one table to another with a different
hash function.





Base code generated by Codemill v0.1.0

The version without a hash value or key parameter iterates through the entire table, obviously in no perceptible order. Those which take a hash value or key pointer iterate over all records containing the given hash value or key, and if a key pointer was specified the key to which it points must exist while the cursor is being used (though it need not exist when the cursor is destructed, because the destructor will not reference the pointer).

◆ JConstHashCursor() [2/2]

template<class V >
JConstHashCursor< V >::JConstHashCursor ( const JHashTable< V > *  table,
const JHashValue  hash 
)

◆ ~JConstHashCursor()

template<class V >
JConstHashCursor< V >::~JConstHashCursor ( )
virtual

Member Function Documentation

◆ DualHash()

template<class V >
JDualHashValue JConstHashCursor< V >::DualHash ( const JHashValue  hashValue)
inlinestaticprotected

The secondary hash function which allows double-hashing.

◆ GetCursorHashValue()

template<class V >
JHashValue JConstHashCursor< V >::GetCursorHashValue ( ) const
inline

Returns the hash value that the cursor is currently using. This can be useful for avoiding extra calls to the hash function.

◆ GetHashValue()

template<class V >
JHashValue JConstHashCursor< V >::GetHashValue ( ) const
inline

◆ GetIndex()

template<class V >
JSize JConstHashCursor< V >::GetIndex ( ) const
inlineprotected

◆ GetRecord()

template<class V >
const JHashRecord< V > & JConstHashCursor< V >::GetRecord ( ) const
inline

◆ GetState()

template<class V >
JHashRecordT::State JConstHashCursor< V >::GetState ( ) const
inline

◆ GetTable()

template<class V >
const JHashTable< V > * JConstHashCursor< V >::GetTable ( ) const
inlineprotected

◆ GetValue()

template<class V >
const V & JConstHashCursor< V >::GetValue ( ) const
inline

◆ IsDeleted()

template<class V >
bool JConstHashCursor< V >::IsDeleted ( ) const
inline

◆ IsEmpty()

template<class V >
bool JConstHashCursor< V >::IsEmpty ( ) const
inline

◆ IsFull()

template<class V >
bool JConstHashCursor< V >::IsFull ( ) const
inline

◆ Next() [1/2]

template<class V >
bool JConstHashCursor< V >::Next ( )

The meaning of copying and assignment of cursors is straightforward; after the the same series of operations with either cursor will have exactly the same behavior and effects as with the other. However, it is easy to get into trouble using cursor copies, since neither cursor knows about the other and changes to and/or by one do not affect the other. For example, after the calls

cursor2 = cursor1;
cursor1.NextFull();

cursor2 still points to the original record, not the new one that cursor1 stepped to. After a subsequent

cursor2.NextFull();

they would again point to the same record. More complex behavior occurs when the table is modified. If the above example continues

cursor1.NextFull();
cursor1.Remove();
cursor2.NextFull();

the cursors would not point to the same record because cursor2 will step over the formerly full record that was deleted by cursor1.

In spite of this hazardous complexity it is occasionally crucial to be able to copy cursors, for example to remember a position and then scan on (an example is in the code to do a Set() for a map or associative array). As always, hide your dangerous operations behind opaque interfaces! These functions are the cursor's reason for being. If an appropriate unvisited element remains, advances to the next one and returns true; otherwise, returns false. They only differ in what kinds of elements they seek and which they skip over. Calls to different Next... functions may be freely intermixed with each other without a Reset. The form with no arguments visits all records, regardless of state or hash value.

◆ Next() [2/2]

template<class V >
bool JConstHashCursor< V >::Next ( bool(*)(const JHashRecord< V > &)  NextRecordType,
const bool  stopOnEmpty 
)

◆ NextFull()

template<class V >
bool JConstHashCursor< V >::NextFull ( )

Only visits full records. Will step past kEmpty records, since it is intended for stepping through all records in the hash table.

◆ NextHash()

template<class V >
bool JConstHashCursor< V >::NextHash ( const bool  allowEmpty = false)

Only visits records with the same hash value as was used to initialize the cursor (and so it better have been initialized with a key or hash value).

If the argument is false (the default) NextHash will return false as soon as it steps to an empty record, so the client code never sees the empty record. If true, it will return true for the last time when it steps to an empty record. In either case all subsequent calls will return false.

◆ NextHashOrOpen()

template<class V >
bool JConstHashCursor< V >::NextHashOrOpen ( )

Visits records which are empty or deleted or that are full and have the same hash value as was used to initialize the cursor (and so it better have been initialized with a key or hash value). This strange behavior is needed to implement maps (associative arrays).

◆ NextKey()

template<class V >
bool JConstHashCursor< V >::NextKey ( const bool  allowEmpty = false)

Only visits records with the same key as was used to initialize the cursor (and so it better have been initialized with a key). Naturally, the key whose address was passed in must still exist.

If the argument is false (the default) NextKey will return false as soon as it steps to an empty record, so the client code never sees the empty record. If true, it will return true for the last time when it steps to an empty record. In either case all subsequent calls will return false.

◆ NextKeyOrOpen()

template<class V >
bool JConstHashCursor< V >::NextKeyOrOpen ( )

Visits records which are empty or deleted or that are full and have the same key as was used to initialize the cursor (and so it better have been initialized with a key or hash value). This strange behavior is needed to implement maps (associative arrays).

◆ NextMapInsertHash()

template<class V >
bool JConstHashCursor< V >::NextMapInsertHash ( )

FindMapInsertHash finds the next location for a map- or array-style insertion, and is mostly useful for implementing associative arrays, or maps. The resulting behavior is intuitive in action precisely because it is designed to mimic a simple array indexed by the key type, but implementing this behavior in a data structure which has no such intrinsic behavior is somewhat complex complex.

Starting from the current position, it returns true positioned at the first slot that has the hash value the cursor was initialized with (so you better have initialized it with a hash value or key). If it finds no such hash value before the scan terminates (at an empty slot or by wrapping over the entire table), it backs up to the first deleted slot it encountered. If there was no deleted slot, it returns true at the empty slot which stopped the scan; in this case the cursor is finished and will return false on all subsequent calls. If there is no empty slot (which means the table is full, so it shouldn't happen normally) it returns false (and of course is also finished).

A key- rather than hash-based search could be implemented by repeated calls to NextMapInsertHash, but NextMapInsertKey() does the job automatically (if you're using the built-in key comparison facilities, of course).

◆ NextMapInsertKey()

template<class V >
bool JConstHashCursor< V >::NextMapInsertKey ( )

Like NextMapInsertHash(), but stops on key matches rather than hash value matches. Obviously, the table has to have a comparison function, and the cursor must have been initialized with a key.

◆ NextOpen()

template<class V >
bool JConstHashCursor< V >::NextOpen ( )

Only visits open (empty or deleted) records.

After stopping on an empty record it will not step further on subsequent calls.

◆ Reset()

template<class V >
void JConstHashCursor< V >::Reset ( const bool  clear = false)

With a boolean argument, true makes the cursor ready for an iteration starting at index zero, stepping by one. If the argument is false (the default) makes ready for a new iteration using the previous parameters (either the same hash value or single-stepping with no hash value).

With a hash value, makes the cursor ready for an iteration starting from the index corresponding to the given hash value, stepping by the dual hash of that hash value.

With a key, the cursor is also ready to use the key-specific functions. However, since it only stores a key reference, the object refered to must exist throughout the entire time the cursor is in use.

The hash and key versions only have different names because C++ can't be trusted to disambiguate pointers and integers.

◆ ResetHash()

template<class V >
void JConstHashCursor< V >::ResetHash ( const JHashValue  hash)

◆ ResetKey()

template<class V >
void JConstHashCursor< V >::ResetKey ( const V &  value)

◆ Step()

template<class V >
void JConstHashCursor< V >::Step ( )
inlineprotected

Advances the index by the increment, wrapping to the tablesize. No safety of any kind.


The documentation for this class was generated from the following files: