QueryParser: Explicitly suspend/resume iterators
Extended policy by IndexIteratorSuspend() and IndexIteratorResume() methods that are invoked for the index iterator by Query::GetNextEntry() after entering respectively before exiting.
This commit is contained in:
@@ -150,7 +150,7 @@ public:
|
|||||||
Query<QueryPolicy>*& _query);
|
Query<QueryPolicy>*& _query);
|
||||||
|
|
||||||
status_t Rewind();
|
status_t Rewind();
|
||||||
status_t GetNextEntry(struct dirent* , size_t size);
|
inline status_t GetNextEntry(struct dirent* dirent, size_t size);
|
||||||
|
|
||||||
void LiveUpdate(Entry* entry, Node* node,
|
void LiveUpdate(Entry* entry, Node* node,
|
||||||
const char* attribute, int32 type,
|
const char* attribute, int32 type,
|
||||||
@@ -168,6 +168,7 @@ public:
|
|||||||
{ return fFlags; }
|
{ return fFlags; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
status_t _GetNextEntry(struct dirent* dirent, size_t size);
|
||||||
void _SendEntryNotification(Entry* entry,
|
void _SendEntryNotification(Entry* entry,
|
||||||
status_t (*notify)(port_id, int32, dev_t, ino_t,
|
status_t (*notify)(port_id, int32, dev_t, ino_t,
|
||||||
const char*, ino_t));
|
const char*, ino_t));
|
||||||
@@ -1755,38 +1756,15 @@ template<typename QueryPolicy>
|
|||||||
status_t
|
status_t
|
||||||
Query<QueryPolicy>::GetNextEntry(struct dirent* dirent, size_t size)
|
Query<QueryPolicy>::GetNextEntry(struct dirent* dirent, size_t size)
|
||||||
{
|
{
|
||||||
// If we don't have an equation to use yet/anymore, get a new one
|
if (fIterator != NULL)
|
||||||
// from the stack
|
QueryPolicy::IndexIteratorResume(fIterator);
|
||||||
while (true) {
|
|
||||||
if (fIterator == NULL) {
|
|
||||||
if (!fStack.Pop(&fCurrent)
|
|
||||||
|| fCurrent == NULL)
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
|
|
||||||
status_t status = fCurrent->PrepareQuery(fContext, fIndex,
|
status_t error = _GetNextEntry(dirent, size);
|
||||||
&fIterator, fFlags & B_QUERY_NON_INDEXED);
|
|
||||||
if (status == B_ENTRY_NOT_FOUND) {
|
|
||||||
// try next equation
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != B_OK)
|
if (fIterator != NULL)
|
||||||
return status;
|
QueryPolicy::IndexIteratorSuspend(fIterator);
|
||||||
}
|
|
||||||
if (fCurrent == NULL)
|
|
||||||
QUERY_RETURN_ERROR(B_ERROR);
|
|
||||||
|
|
||||||
status_t status = fCurrent->GetNextMatching(fContext, fIterator, dirent,
|
return error;
|
||||||
size);
|
|
||||||
if (status != B_OK) {
|
|
||||||
QueryPolicy::IndexIteratorDelete(fIterator);
|
|
||||||
fIterator = NULL;
|
|
||||||
fCurrent = NULL;
|
|
||||||
} else {
|
|
||||||
// only return if we have another entry
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1897,6 +1875,45 @@ Query<QueryPolicy>::LiveUpdateRenameMove(Entry* entry, Node* node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<typename QueryPolicy>
|
||||||
|
status_t
|
||||||
|
Query<QueryPolicy>::_GetNextEntry(struct dirent* dirent, size_t size)
|
||||||
|
{
|
||||||
|
// If we don't have an equation to use yet/anymore, get a new one
|
||||||
|
// from the stack
|
||||||
|
while (true) {
|
||||||
|
if (fIterator == NULL) {
|
||||||
|
if (!fStack.Pop(&fCurrent)
|
||||||
|
|| fCurrent == NULL)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
|
status_t status = fCurrent->PrepareQuery(fContext, fIndex,
|
||||||
|
&fIterator, fFlags & B_QUERY_NON_INDEXED);
|
||||||
|
if (status == B_ENTRY_NOT_FOUND) {
|
||||||
|
// try next equation
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK)
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
if (fCurrent == NULL)
|
||||||
|
QUERY_RETURN_ERROR(B_ERROR);
|
||||||
|
|
||||||
|
status_t status = fCurrent->GetNextMatching(fContext, fIterator, dirent,
|
||||||
|
size);
|
||||||
|
if (status != B_OK) {
|
||||||
|
QueryPolicy::IndexIteratorDelete(fIterator);
|
||||||
|
fIterator = NULL;
|
||||||
|
fCurrent = NULL;
|
||||||
|
} else {
|
||||||
|
// only return if we have another entry
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename QueryPolicy>
|
template<typename QueryPolicy>
|
||||||
void
|
void
|
||||||
Query<QueryPolicy>::_SendEntryNotification(Entry* entry,
|
Query<QueryPolicy>::_SendEntryNotification(Entry* entry,
|
||||||
|
|||||||
@@ -154,6 +154,16 @@ struct Query::QueryPolicy {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void IndexIteratorSuspend(IndexIterator* indexIterator)
|
||||||
|
{
|
||||||
|
indexIterator->Suspend();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void IndexIteratorResume(IndexIterator* indexIterator)
|
||||||
|
{
|
||||||
|
indexIterator->Resume();
|
||||||
|
}
|
||||||
|
|
||||||
// Node interface
|
// Node interface
|
||||||
|
|
||||||
static const off_t NodeGetSize(Node* node)
|
static const off_t NodeGetSize(Node* node)
|
||||||
|
|||||||
Reference in New Issue
Block a user