file_systems: Adjustments to QueryParser in preparation for BFS using it.

Should not result in functional changes to packagefs and ramfs
queries behavior.

Change-Id: If361ca65de99d255e67f929c3442e0c20e39cdf4
Reviewed-on: https://review.haiku-os.org/c/haiku/+/7703
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Augustin Cavalier
2024-06-24 19:40:08 +00:00
committed by waddlesplash
parent 1f2b4425c4
commit 3a17bd3545
4 changed files with 68 additions and 30 deletions
+26 -13
View File
@@ -124,6 +124,7 @@ public:
typedef typename QueryPolicy::Index Index;
typedef typename QueryPolicy::IndexIterator IndexIterator;
typedef typename QueryPolicy::Node Node;
typedef typename QueryPolicy::NodeHolder NodeHolder;
typedef typename QueryPolicy::Context Context;
public:
@@ -184,6 +185,7 @@ public:
typedef typename QueryPolicy::Index Index;
typedef typename QueryPolicy::IndexIterator IndexIterator;
typedef typename QueryPolicy::Node Node;
typedef typename QueryPolicy::NodeHolder NodeHolder;
typedef typename QueryPolicy::Context Context;
public:
@@ -236,6 +238,7 @@ public:
typedef typename QueryPolicy::Index Index;
typedef typename QueryPolicy::IndexIterator IndexIterator;
typedef typename QueryPolicy::Node Node;
typedef typename QueryPolicy::NodeHolder NodeHolder;
typedef typename QueryPolicy::Context Context;
public:
@@ -712,6 +715,7 @@ Equation<QueryPolicy>::Match(Entry* entry, Node* node,
const char* attributeName, int32 type, const uint8* key, size_t size)
{
// get a pointer to the attribute in question
NodeHolder nodeHolder;
union value<QueryPolicy> value;
uint8* buffer = (uint8*)&value;
const size_t bufferSize = sizeof(value);
@@ -729,8 +733,7 @@ Equation<QueryPolicy>::Match(Entry* entry, Node* node,
// if not, check for "fake" attributes ("name", "size", "last_modified")
if (entry == NULL)
return B_ERROR;
buffer = (uint8*)QueryPolicy::EntryGetNameNoCopy(entry, buffer,
sizeof(value));
buffer = (uint8*)QueryPolicy::EntryGetNameNoCopy(nodeHolder, entry);
if (buffer == NULL)
return B_ERROR;
@@ -740,13 +743,13 @@ Equation<QueryPolicy>::Match(Entry* entry, Node* node,
value.Int64 = QueryPolicy::NodeGetSize(node);
type = B_INT64_TYPE;
} else if (!strcmp(fAttribute, "last_modified")) {
value.Int32 = QueryPolicy::NodeGetLastModifiedTime(node);
type = B_INT32_TYPE;
value.Int64 = QueryPolicy::NodeGetLastModifiedTime(node);
type = B_INT64_TYPE;
} else {
// then for attributes
size = bufferSize;
if (QueryPolicy::NodeGetAttribute(node, fAttribute, buffer, &size,
&type) != B_OK) {
if (QueryPolicy::NodeGetAttribute(nodeHolder, node,
fAttribute, buffer, &size, &type) != B_OK) {
return MatchEmptyString();
}
}
@@ -887,18 +890,19 @@ Equation<QueryPolicy>::GetNextMatching(Context* context,
IndexIterator* iterator, struct dirent* dirent, size_t bufferSize)
{
while (true) {
NodeHolder nodeHolder;
union value<QueryPolicy> indexValue;
size_t keyLength;
Entry* entry = NULL;
size_t duplicate = 0;
status_t status = QueryPolicy::IndexIteratorGetNextEntry(iterator,
&indexValue, &keyLength, (size_t)sizeof(indexValue), &entry);
status_t status = QueryPolicy::IndexIteratorFetchNextEntry(iterator,
&indexValue, &keyLength, (size_t)sizeof(indexValue), &duplicate);
if (status != B_OK)
return status;
// only compare against the index entry when this is the correct
// index for the equation
if (fHasIndex && !CompareTo((uint8*)&indexValue, keyLength)) {
if (fHasIndex && duplicate < 2 && !CompareTo((uint8*)&indexValue, keyLength)) {
// They aren't equal? Let the operation decide what to do. Since
// we always start at the beginning of the index (or the correct
// position), only some needs to be stopped if the entry doesn't
@@ -908,6 +912,16 @@ Equation<QueryPolicy>::GetNextMatching(Context* context,
|| (Term<QueryPolicy>::fOp == OP_EQUAL && !fIsPattern))
return B_ENTRY_NOT_FOUND;
if (duplicate > 0)
QueryPolicy::IndexIteratorSkipDuplicates(iterator);
continue;
}
Entry* entry = NULL;
status = QueryPolicy::IndexIteratorGetEntry(context, iterator,
nodeHolder, &entry);
if (status != B_OK) {
// try with next
continue;
}
@@ -1596,9 +1610,8 @@ void
Query<QueryPolicy>::_SendEntryNotification(Entry* entry,
status_t (*notify)(port_id, int32, dev_t, ino_t, const char*, ino_t))
{
char nameBuffer[QueryPolicy::kMaxFileNameLength];
const char* name = QueryPolicy::EntryGetNameNoCopy(entry, nameBuffer,
sizeof(nameBuffer));
NodeHolder nodeHolder;
const char* name = QueryPolicy::EntryGetNameNoCopy(nodeHolder, entry);
if (name != NULL) {
notify(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
QueryPolicy::EntryGetParentID(entry), name,
@@ -22,6 +22,7 @@ struct Query::QueryPolicy {
typedef Query Context;
typedef ::Node Entry;
typedef ::Node Node;
typedef void* NodeHolder;
struct Index {
Query* query;
@@ -36,6 +37,7 @@ struct Query::QueryPolicy {
struct IndexIterator : ::IndexIterator {
::Index* index;
Entry* entry;
IndexIterator(::Index* index)
:
@@ -74,8 +76,7 @@ struct Query::QueryPolicy {
return nameLength + 1;
}
static const char* EntryGetNameNoCopy(Entry* entry, void* buffer,
size_t bufferSize)
static const char* EntryGetNameNoCopy(NodeHolder& holder, Entry* entry)
{
return entry->Name();
}
@@ -142,17 +143,29 @@ struct Query::QueryPolicy {
return B_OK;
}
static status_t IndexIteratorGetNextEntry(IndexIterator* indexIterator,
void* value, size_t* _valueLength, size_t bufferSize, Entry** _entry)
static status_t IndexIteratorFetchNextEntry(IndexIterator* indexIterator,
void* value, size_t* _valueLength, size_t bufferSize, size_t* duplicate)
{
Node* node = indexIterator->Next(value, _valueLength);
if (node == NULL)
return B_ENTRY_NOT_FOUND;
*_entry = node;
indexIterator->entry = node;
return B_OK;
}
static status_t IndexIteratorGetEntry(Context* context, IndexIterator* indexIterator,
NodeHolder& holder, Entry** _entry)
{
*_entry = indexIterator->entry;
return B_OK;
}
static void IndexIteratorSkipDuplicates(IndexIterator* indexIterator)
{
// Nothing to do.
}
static void IndexIteratorSuspend(IndexIterator* indexIterator)
{
indexIterator->Suspend();
@@ -175,8 +188,8 @@ struct Query::QueryPolicy {
return node->ModifiedTime().tv_sec;
}
static status_t NodeGetAttribute(Node* node, const char* attribute,
void* buffer, size_t* _size, int32* _type)
static status_t NodeGetAttribute(NodeHolder& nodeHolder, Node* node,
const char* attribute, void* buffer, size_t* _size, int32* _type)
{
// TODO: Creating a cookie is quite a bit of overhead.
AttributeCookie* cookie;
@@ -104,6 +104,7 @@ struct Query::QueryPolicy {
typedef Query Context;
typedef ::Entry Entry;
typedef ::Node Node;
typedef void* NodeHolder;
struct Index {
Query* query;
@@ -117,6 +118,8 @@ struct Query::QueryPolicy {
};
struct IndexIterator : ::IndexIterator {
Entry* entry;
IndexIterator(::Index* index)
:
::IndexIterator(index)
@@ -154,8 +157,7 @@ struct Query::QueryPolicy {
return nameLength + 1;
}
static const char* EntryGetNameNoCopy(Entry* entry, void* buffer,
size_t bufferSize)
static const char* EntryGetNameNoCopy(NodeHolder& holder, Entry* entry)
{
return entry->GetName();
}
@@ -214,10 +216,22 @@ struct Query::QueryPolicy {
return indexIterator->Find((const uint8*)value, size);
}
static status_t IndexIteratorGetNextEntry(IndexIterator* indexIterator,
void* value, size_t* _valueLength, size_t bufferSize, Entry** _entry)
static status_t IndexIteratorFetchNextEntry(IndexIterator* indexIterator,
void* value, size_t* _valueLength, size_t bufferSize, size_t* duplicate)
{
return indexIterator->GetNextEntry((uint8*)value, _valueLength, _entry);
return indexIterator->GetNextEntry((uint8*)value, _valueLength, &indexIterator->entry);
}
static status_t IndexIteratorGetEntry(Context* context, IndexIterator* indexIterator,
NodeHolder& holder, Entry** _entry)
{
*_entry = indexIterator->entry;
return B_OK;
}
static void IndexIteratorSkipDuplicates(IndexIterator* indexIterator)
{
// Nothing to do.
}
static void IndexIteratorSuspend(IndexIterator* indexIterator)
@@ -242,8 +256,8 @@ struct Query::QueryPolicy {
return node->GetMTime();
}
static status_t NodeGetAttribute(Node* node, const char* attribute,
void* buffer, size_t* _size, int32* _type)
static status_t NodeGetAttribute(NodeHolder& nodeHolder, Node* node,
const char* attribute, void* buffer, size_t* _size, int32* _type)
{
Attribute* attr = NULL;
status_t error = node->FindAttribute(attribute, &attr);
@@ -11,6 +11,7 @@
#include <OS.h>
#include <SupportDefs.h>
#include <fs_query.h>
#include <util/DoublyLinkedList.h>
@@ -26,9 +27,6 @@ class Node;
class Volume;
#define B_QUERY_NON_INDEXED 0x00000002
class Query : public DoublyLinkedListLinkImpl<Query> {
public:
~Query();