Table::ReadLock
and
Table::WriteLock
, you need this fix,
or you will deadlock under stress.EqualKeys
to
CompareKeys
, which now returns an
int
instead of a bool
. This is
needed for multikeys support.
AddRefRecord
. The
second parameter is now an LK_ADDREF_REASON
,
instead of an int
whose value is
+1
or -1
. The reason code
aids in debugging refcount leaks. If its value is negative, the
refcount should be decremented; otherwise the refcount
should be incremented. Also, AddRefRecord
now returns LONG
instead of
void
: the new value of the reference count.ApplyIf
locking: now
locks one subtable at a time, instead of all
subtables. Can use Table::ReadLock
or
Table::WriteLock
to retain old behavior.void LKRHashTableInit()
and
void LKRHashTableUninit()
, to
BOOL LKR_Initialize(DWORD)
and
void LKR_Terminate()
, respectively.iterator::operator*()
and
iterator::operator->()
.Clear
that left
certain internal state variables in an inconsistent state. If
you later inserted/deleted enough new records, LKRhash would
AV. (The fix in the 2000/03/22 release did not work in all
cases.)WriteLock
(or ReadLock
) on the
table before initializing any iterators, and to call
WriteUnlock
(or ReadUnlock
)
when you are finished.begin()
and
end()
methods. As the compiler isn't quite
smart enough to realize that end()
always
returns a trivial empty iterator, a loop such as
MyTable::iterator iter; for (iter = pTbl->begin(); iter != pTbl->end(); ++iter) ...is more efficiently expressed as
MyTable::iterator iter; MyTable::iterator iterEnd = pTbl->end(); for (iter = pTbl->begin(); iter != iterEnd; ++iter) ...
++iter
and iter++
.
Pre-increment is more efficient than post-increment.Insert
method that returns an iterator,
pointing to the newly inserted record, or end()
on
failure.Find
method that returns an iterator
pointing to the record with the passed-in key, or
end()
on failure.EqualRange
method that returns
two iterators describing the range that contain all the
records whose keys match the passed-in key. Until full
support for multiple, identical keys is added, the range
will contain either zero or one record(s).Erase
method that deletes the
record pointed to by the iterator. Updates the iterator to
point to the next record in the table.Erase
method that takes two
iterators, which will delete all the records in the range
described by the two iterators.CIterator
),
more than one iterator can be active at a time. It is
best not to call the non-iterator insert/delete methods
(InsertRecord
, DeleteRecord
,
DeleteKey
) while iterators are open, as the
non-iterator methods can rebalance bucket chains,
leading to invalid iterators, undercounting, and/or
overcounting. This is true even if the table was
WriteLocked, before the iterators were initialized. It
is best to use the iterator Insert
or
Erase
methods in such a case.!lkrdbg.lkrhash
:
!lkrhash -l[0-2] addr
will dump the
hashtable at addr
at verbosity level
l
(default 0).!lkrhash -g[0-2]
will dump ALL hashtables
at at verbosity level l
(default 0).pszName
parameter
used in the hashtable constructor. You can provide a custom dump
routine for the table (to dump whatever other fields you
might have added), as well as a custom dump routine for
the record class stored by the hashtable. Provided three
examples of customization, based on the samples.#ifdef
IRTLDEBUG
(instead of #ifdef _DEBUG
).
Currently equivalent, but you can control this in
irtldbg.hLKRhash
and HashFn
namespaces by default. See readme.txt.LKR_OLD_SEGMENT
, LKR_SIGS_NODES
,
etc).CSmallSpinLock
, unless
LKR_DEPRECATED_ITERATORS
is defined (off by
default).Clear
that left certain
internal state variables in an inconsistent state. If you
later inserted/deleted enough new records, LKRhash would AV.BucketLock
to CReaderWriterLock3
(recursive MRSW lock) to support certain scenarios, such as
being able to call FindKey
while enumerating
with an old-style iterator. Slightly slower, but the speed
improvements below more than compensate.SAMPLE_LKRHASH_TESTCLASS
.TRACE
macro with
IRTLTRACE
so as not to interfere with other
TRACE
macros (e.g., MFC's).STATIC_ASSERT
macro for compile-time
assertions. The IRTLASSERT
macro is still used
for run-time assertions.LKR_NEWCODE
, LKR_MASK
,
LKR_SUBTABLE
,
LKR_COMPACT_DELETE
, etc).LK_DFLT_MAXLOAD
to 6
(NODES_PER_CLUMP
) to get better memory usage.CSegment
into a concrete base
class. Somewhat hacky but faster.CReaderWriterLock3::IsWriteLocked
.Print
methods.LKR_NO_GLOBAL_LIST
.LK_SMALL_TABLESIZE
Was min(2, #CPUs). Max number
of subtables is now 64.