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:
committed by
waddlesplash
parent
1f2b4425c4
commit
3a17bd3545
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user