This chapter describes changes and additions to IAT classes and other information documented in the Apple Information Access Toolkit v.1.0 Programmer's Guide .
As mentioned
in the Apple Information Access Toolkit v.1.0 Programmer's
Guide , you can use the IAMutex
class to coordinate
access to a storage object when using or developing multi-threaded
applications. No thread synchronization or access control (thread
safety) is necessary when reading a storage object. However, only one
thread of a multi-threaded application should be able to write to the
storage at any particular time. Doing so prevents lockouts and
accidental overwriting of data. The IAMutex
class contains
methods that let you create a mutex (a mutual-exclusion handler or
semaphore) that can coordinate write access between multiple threads.
You must create a subclass of
IAMutex
class if you want to prevent multiple-write access. Your
subclass should be able to lock out other threads if one thread is
writing to the storage object, and it should be able to transfer
write access to another thread when necessary. A Subclass of IAMutex shows an example subclass
of IAMutex
. This example uses the Metrowerks
LMutexSemaphore class (provided with PowerPlant) to implement
the IAMutex
protocol, but you may choose another
implementation if desired.
#include "PowerPlantMutex.h" #include <LMutexSemaphore.h> #include <LThread.h> #include <UException.h> #include <UThread.h> class PowerPlantMutex : public IAMutex, public LMutexSemaphore { public: void Lock(); void Unlock(); void Signal(); }; void PowerPlantMutex::Lock() { ThrowIfOSErr_(Wait()); } void PowerPlantMutex::Unlock() { Signal(); } void PowerPlantMutex::Signal() { // code copied from LMutexSemaphor::Signal(), except this version // does not call LThread::Yield() LThread *thread = LThread::GetCurrentThread(); { StCritical critical; // disable preemption within this block if (thread != mOwner) { Throw_(errSemaphoreNotOwner); } else if (mNestedWaits > 0) { --mNestedWaits; } else if (mExcessSignals < 0) { THREAD_ASSERT(mThreads.qHead != NULL); mOwner = UnblockThread(mThreads.qHead, noErr); } else { THREAD_ASSERT(mExcessSignals == 0); mOwner = NULL; ++mExcessSignals; } } //LThread::Yield(); }
The PowerPlantMutex
class
inherits from both the IAMutex
and PowerPlant LMutexSemaphore
classes.
The Lock
method takes one of
two actions:
The Unlock
method calls the
Signal method, which indicates that the current thread is
giving up its semaphore. The semaphore can then pass to a waiting
thread (if any).
After implementing your
IAMutex
subclass, you must register the class with the IAT. This
allows the IAT to create mutex instances as necessary for each
thread.
To register your mutex, you must set the
IANewMutex
variable.
IANewMutex is declared as a pointer to a function with the
following prototype:
IAMutex* myFuncName();
For example, if you wanted to register
the PowerPlantMutex
class in
See A subclass of IAMutex , you would have to cast it as a
function that matches the required IANewMutex
prototype:
IAMutex* NewPowerPlantMutex() { return new PowerPlantMutex(); }
Then, to register
PowerPlantMutex
, you would define IANewMutex
as
follows:
IANewMutex = &NewPowerPlantMutex;
You should register your mutex as part of any global initializations in your application and before you create your index. The IAT can then create and remove mutexes as needed.
Note: For single-threaded applications, the
IANewMutex
variable automatically defaults to the address of
IADefaultMutexConstructor
, which implements a dummy
(no-op) mutex.
The TWVector
class now
contains additional methods.
For more information about TWVectors and the other available methods, see Chapter 6, "Accessor Category," in the Apple Information Access Toolkit v.1.0 Programmer's Guide .
Determines whether the vector has components with negative weight.
bool HasNegativeComponents () const;
method result True if the vector contains components with negative weight.
Returns the size of the vector.
IABlockSize StoreSize () const;
method result The size of the vector, in blocks.
Creates a deep copy of the vector.
TWVEctor* DeepCopy () const;
method result A pointer to the copy of the vector.
Deep copying creates a copy of the vector as well as copies of any objects referenced by the vector.
void Store (IAOutputBlock *output) const;
output A pointer to the output block in which to store the vector.
Restores the vector from a given block.
TWVector* Restore (IAInputBlock *input) const;
input A pointer to the block containing the vector.
method result A pointer to the restored vector.
void SortByTerm ();
void SortByWeight ();
Sorts the vector by the absolute value of the component weight.
void SortByAbsoluteWeight ();
Removes terms with lower weights.
void Truncate (uint32 maxTerms);
maxTerms
The maximum number of
terms to keep. Truncate
removes terms, starting with the
lowest weights, until maxTerms
or less are left.
Removes terms with lower absolute weights.
void TruncateAbsoluteValue (uint32 maxTerms);
maxTerms
The maximum number of
terms to keep. Truncate
removes terms starting with the
lowest absolute weights until maxTerms
or less are left.
Adds a new vector to the current one and returns a vector representing the result.
TWVector* AddIntoAverage ( const TWVector *newVector, uint32 totalVectorCount, bool invertNewVector);
newVector
totalVectorCount
invertNewVector
Adds a new vector to the current one and returns a new vector representing the result.
TWVector* AddWeighted ( const TWVector *vector, float weightFactorCurrent, float weightFactorAdded);
vector
weightFactorCurrent
weightFactorAdded
*vector
). The component weight of the vector is multiplied by
this value.
The weight factors for the vectors are used to ensure that the components in the resulting vector have the same level of importance.
This method does not allow either vector's component weight to be less than zero. If either vector has a negative component weight, you must use the See AddWeightedAllowNegatives method See AddWeightedAllowNegatives instead.
Adds a new vector to the current one and returns a vector representing the result.
TWVector* AddWeightedAllowNegatives ( const TWVector *vector, float weightFactorCurrent, float weightFactorAdded);
vector
A pointer to the new vector.
weightFactorCurrent
The weighting factor for the current vector. The component weight of
the current vector is multiplied by this value.
weightFactorAdded
The weighting factor for vector being passed in (that is,
*vector
). The component weight of the vector is multiplied by
this value.
method result A pointer to the resulting vector.
The weight factors for the vectors are used to ensure that the components in the resulting vector have the same level of importance. This method allows vectors to have negative component weights.
This class now contains a virtual destructor.
For more information about the
IAStruct
class, see Chapter 4, "Common Practices in IAT," in the
Apple Information Access Toolkit v.1.0 Programmer's Guide .
virtual ~IAStruct ();
The IAAccessor
class now
contains additional methods.
For more information about the
IAAccessor
class and the other available methods , see Chapter
6, "Accessor Category," in the Apple Information Access Toolkit
v.1.0 Programmer's Guide .
void Store (IAStorage* storage, IABlockID block);
storage
The storage object to
hold the saved accessor. Pass NULL
to select the default
storage object.
block
The block ID of the
storage object in which to save the accessor. The default ID is 0.
void Update ( IAStorage* storage, IABlockID block);
storage
The storage object to
hold the updated accessor. Pass NULL
to select the default
storage object.
block
The block ID of the
storage object in which to update the accessor. The default ID is 0.
The Update
method allows you
to update a stored accessor to reflect changes in one or more
indexes. For example, if the index has changed since the last time
you stored the accessor, you update the accessor with the changes
without having to reinitialize the entire accessor. However, the
updates are not stored if you do not call the Store
method
before disposing the accessor.
Calling the Update
method on
an empty accessor initializes the accessor.
The HFSIterator
class now has
a constructor that supports callbacks to an application-defined
progress function.
For more information about the
IAAccessor
class and the other available methods, see Chapter 8,
"Corpus Category," in the Apple Information Access Toolkit v.1.0
Programmer's Guide .
HFSIterator
(
short vRefNum,
long rootDirId,
TProgressFn* progressFn,
clock_t progressFreq,
void* appData);
vRefNum
The HFS volume reference number.
rootDirId
The directory ID of the
highest level folder. The default it the volume root.
progressFn
A pointer to an
application-defined progress function. If not NULL
, the
IAT calls this function periodically to give the client application
control.
progressFreq
The wait time
between callbacks, in clock ticks (using the ANSI clocks_per_sec
standard).
appData
A pointer to
application-specific data that is passed to the client application
when the callback occurs.
The callback is invoked during calls to
the GetDirectoryInfo
method.
Ancestors IACorpus -->
HFSCorpus
Header file
HFSTextFolderCorpus.h
The GetDocIterator
method now
supports callbacks to an application-defined progress function.
For more information about the
IACorpus
class and the other available methods, see Chapter 8,
"Corpus Category," in the Apple Information Access Toolkit v.1.0
Programmer's Guide .
Constructs a document iterator.
IADocIterator * GetDocIterator ( TProgressFn* progressFn, clock_t progressFreq, void* appData);
progressFn
A pointer to an
application-defined progress function. If not NULL
, the
IAT calls this function periodically to give the client application
control.
progressFreq
The wait time
between callbacks, in clock ticks (using the ANSI clocks_per_sec
standard).
appData
A pointer to
application-specific data that is passed to the client application
when the callback occurs.
The callback is invoked during calls to
the GetDirectoryInfo
method.