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::Index Index;
|
||||||
typedef typename QueryPolicy::IndexIterator IndexIterator;
|
typedef typename QueryPolicy::IndexIterator IndexIterator;
|
||||||
typedef typename QueryPolicy::Node Node;
|
typedef typename QueryPolicy::Node Node;
|
||||||
|
typedef typename QueryPolicy::NodeHolder NodeHolder;
|
||||||
typedef typename QueryPolicy::Context Context;
|
typedef typename QueryPolicy::Context Context;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -184,6 +185,7 @@ public:
|
|||||||
typedef typename QueryPolicy::Index Index;
|
typedef typename QueryPolicy::Index Index;
|
||||||
typedef typename QueryPolicy::IndexIterator IndexIterator;
|
typedef typename QueryPolicy::IndexIterator IndexIterator;
|
||||||
typedef typename QueryPolicy::Node Node;
|
typedef typename QueryPolicy::Node Node;
|
||||||
|
typedef typename QueryPolicy::NodeHolder NodeHolder;
|
||||||
typedef typename QueryPolicy::Context Context;
|
typedef typename QueryPolicy::Context Context;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -236,6 +238,7 @@ public:
|
|||||||
typedef typename QueryPolicy::Index Index;
|
typedef typename QueryPolicy::Index Index;
|
||||||
typedef typename QueryPolicy::IndexIterator IndexIterator;
|
typedef typename QueryPolicy::IndexIterator IndexIterator;
|
||||||
typedef typename QueryPolicy::Node Node;
|
typedef typename QueryPolicy::Node Node;
|
||||||
|
typedef typename QueryPolicy::NodeHolder NodeHolder;
|
||||||
typedef typename QueryPolicy::Context Context;
|
typedef typename QueryPolicy::Context Context;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -712,6 +715,7 @@ Equation<QueryPolicy>::Match(Entry* entry, Node* node,
|
|||||||
const char* attributeName, int32 type, const uint8* key, size_t size)
|
const char* attributeName, int32 type, const uint8* key, size_t size)
|
||||||
{
|
{
|
||||||
// get a pointer to the attribute in question
|
// get a pointer to the attribute in question
|
||||||
|
NodeHolder nodeHolder;
|
||||||
union value<QueryPolicy> value;
|
union value<QueryPolicy> value;
|
||||||
uint8* buffer = (uint8*)&value;
|
uint8* buffer = (uint8*)&value;
|
||||||
const size_t bufferSize = sizeof(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 not, check for "fake" attributes ("name", "size", "last_modified")
|
||||||
if (entry == NULL)
|
if (entry == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
buffer = (uint8*)QueryPolicy::EntryGetNameNoCopy(entry, buffer,
|
buffer = (uint8*)QueryPolicy::EntryGetNameNoCopy(nodeHolder, entry);
|
||||||
sizeof(value));
|
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -740,13 +743,13 @@ Equation<QueryPolicy>::Match(Entry* entry, Node* node,
|
|||||||
value.Int64 = QueryPolicy::NodeGetSize(node);
|
value.Int64 = QueryPolicy::NodeGetSize(node);
|
||||||
type = B_INT64_TYPE;
|
type = B_INT64_TYPE;
|
||||||
} else if (!strcmp(fAttribute, "last_modified")) {
|
} else if (!strcmp(fAttribute, "last_modified")) {
|
||||||
value.Int32 = QueryPolicy::NodeGetLastModifiedTime(node);
|
value.Int64 = QueryPolicy::NodeGetLastModifiedTime(node);
|
||||||
type = B_INT32_TYPE;
|
type = B_INT64_TYPE;
|
||||||
} else {
|
} else {
|
||||||
// then for attributes
|
// then for attributes
|
||||||
size = bufferSize;
|
size = bufferSize;
|
||||||
if (QueryPolicy::NodeGetAttribute(node, fAttribute, buffer, &size,
|
if (QueryPolicy::NodeGetAttribute(nodeHolder, node,
|
||||||
&type) != B_OK) {
|
fAttribute, buffer, &size, &type) != B_OK) {
|
||||||
return MatchEmptyString();
|
return MatchEmptyString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -887,18 +890,19 @@ Equation<QueryPolicy>::GetNextMatching(Context* context,
|
|||||||
IndexIterator* iterator, struct dirent* dirent, size_t bufferSize)
|
IndexIterator* iterator, struct dirent* dirent, size_t bufferSize)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
|
NodeHolder nodeHolder;
|
||||||
union value<QueryPolicy> indexValue;
|
union value<QueryPolicy> indexValue;
|
||||||
size_t keyLength;
|
size_t keyLength;
|
||||||
Entry* entry = NULL;
|
size_t duplicate = 0;
|
||||||
|
|
||||||
status_t status = QueryPolicy::IndexIteratorGetNextEntry(iterator,
|
status_t status = QueryPolicy::IndexIteratorFetchNextEntry(iterator,
|
||||||
&indexValue, &keyLength, (size_t)sizeof(indexValue), &entry);
|
&indexValue, &keyLength, (size_t)sizeof(indexValue), &duplicate);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// only compare against the index entry when this is the correct
|
// only compare against the index entry when this is the correct
|
||||||
// index for the equation
|
// 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
|
// They aren't equal? Let the operation decide what to do. Since
|
||||||
// we always start at the beginning of the index (or the correct
|
// we always start at the beginning of the index (or the correct
|
||||||
// position), only some needs to be stopped if the entry doesn't
|
// 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))
|
|| (Term<QueryPolicy>::fOp == OP_EQUAL && !fIsPattern))
|
||||||
return B_ENTRY_NOT_FOUND;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1596,9 +1610,8 @@ void
|
|||||||
Query<QueryPolicy>::_SendEntryNotification(Entry* entry,
|
Query<QueryPolicy>::_SendEntryNotification(Entry* entry,
|
||||||
status_t (*notify)(port_id, int32, dev_t, ino_t, const char*, ino_t))
|
status_t (*notify)(port_id, int32, dev_t, ino_t, const char*, ino_t))
|
||||||
{
|
{
|
||||||
char nameBuffer[QueryPolicy::kMaxFileNameLength];
|
NodeHolder nodeHolder;
|
||||||
const char* name = QueryPolicy::EntryGetNameNoCopy(entry, nameBuffer,
|
const char* name = QueryPolicy::EntryGetNameNoCopy(nodeHolder, entry);
|
||||||
sizeof(nameBuffer));
|
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
notify(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
notify(fPort, fToken, QueryPolicy::ContextGetVolumeID(fContext),
|
||||||
QueryPolicy::EntryGetParentID(entry), name,
|
QueryPolicy::EntryGetParentID(entry), name,
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ struct Query::QueryPolicy {
|
|||||||
typedef Query Context;
|
typedef Query Context;
|
||||||
typedef ::Node Entry;
|
typedef ::Node Entry;
|
||||||
typedef ::Node Node;
|
typedef ::Node Node;
|
||||||
|
typedef void* NodeHolder;
|
||||||
|
|
||||||
struct Index {
|
struct Index {
|
||||||
Query* query;
|
Query* query;
|
||||||
@@ -36,6 +37,7 @@ struct Query::QueryPolicy {
|
|||||||
|
|
||||||
struct IndexIterator : ::IndexIterator {
|
struct IndexIterator : ::IndexIterator {
|
||||||
::Index* index;
|
::Index* index;
|
||||||
|
Entry* entry;
|
||||||
|
|
||||||
IndexIterator(::Index* index)
|
IndexIterator(::Index* index)
|
||||||
:
|
:
|
||||||
@@ -74,8 +76,7 @@ struct Query::QueryPolicy {
|
|||||||
return nameLength + 1;
|
return nameLength + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* EntryGetNameNoCopy(Entry* entry, void* buffer,
|
static const char* EntryGetNameNoCopy(NodeHolder& holder, Entry* entry)
|
||||||
size_t bufferSize)
|
|
||||||
{
|
{
|
||||||
return entry->Name();
|
return entry->Name();
|
||||||
}
|
}
|
||||||
@@ -142,17 +143,29 @@ struct Query::QueryPolicy {
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t IndexIteratorGetNextEntry(IndexIterator* indexIterator,
|
static status_t IndexIteratorFetchNextEntry(IndexIterator* indexIterator,
|
||||||
void* value, size_t* _valueLength, size_t bufferSize, Entry** _entry)
|
void* value, size_t* _valueLength, size_t bufferSize, size_t* duplicate)
|
||||||
{
|
{
|
||||||
Node* node = indexIterator->Next(value, _valueLength);
|
Node* node = indexIterator->Next(value, _valueLength);
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
*_entry = node;
|
indexIterator->entry = node;
|
||||||
return B_OK;
|
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)
|
static void IndexIteratorSuspend(IndexIterator* indexIterator)
|
||||||
{
|
{
|
||||||
indexIterator->Suspend();
|
indexIterator->Suspend();
|
||||||
@@ -175,8 +188,8 @@ struct Query::QueryPolicy {
|
|||||||
return node->ModifiedTime().tv_sec;
|
return node->ModifiedTime().tv_sec;
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t NodeGetAttribute(Node* node, const char* attribute,
|
static status_t NodeGetAttribute(NodeHolder& nodeHolder, Node* node,
|
||||||
void* buffer, size_t* _size, int32* _type)
|
const char* attribute, void* buffer, size_t* _size, int32* _type)
|
||||||
{
|
{
|
||||||
// TODO: Creating a cookie is quite a bit of overhead.
|
// TODO: Creating a cookie is quite a bit of overhead.
|
||||||
AttributeCookie* cookie;
|
AttributeCookie* cookie;
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ struct Query::QueryPolicy {
|
|||||||
typedef Query Context;
|
typedef Query Context;
|
||||||
typedef ::Entry Entry;
|
typedef ::Entry Entry;
|
||||||
typedef ::Node Node;
|
typedef ::Node Node;
|
||||||
|
typedef void* NodeHolder;
|
||||||
|
|
||||||
struct Index {
|
struct Index {
|
||||||
Query* query;
|
Query* query;
|
||||||
@@ -117,6 +118,8 @@ struct Query::QueryPolicy {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct IndexIterator : ::IndexIterator {
|
struct IndexIterator : ::IndexIterator {
|
||||||
|
Entry* entry;
|
||||||
|
|
||||||
IndexIterator(::Index* index)
|
IndexIterator(::Index* index)
|
||||||
:
|
:
|
||||||
::IndexIterator(index)
|
::IndexIterator(index)
|
||||||
@@ -154,8 +157,7 @@ struct Query::QueryPolicy {
|
|||||||
return nameLength + 1;
|
return nameLength + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* EntryGetNameNoCopy(Entry* entry, void* buffer,
|
static const char* EntryGetNameNoCopy(NodeHolder& holder, Entry* entry)
|
||||||
size_t bufferSize)
|
|
||||||
{
|
{
|
||||||
return entry->GetName();
|
return entry->GetName();
|
||||||
}
|
}
|
||||||
@@ -214,10 +216,22 @@ struct Query::QueryPolicy {
|
|||||||
return indexIterator->Find((const uint8*)value, size);
|
return indexIterator->Find((const uint8*)value, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t IndexIteratorGetNextEntry(IndexIterator* indexIterator,
|
static status_t IndexIteratorFetchNextEntry(IndexIterator* indexIterator,
|
||||||
void* value, size_t* _valueLength, size_t bufferSize, Entry** _entry)
|
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)
|
static void IndexIteratorSuspend(IndexIterator* indexIterator)
|
||||||
@@ -242,8 +256,8 @@ struct Query::QueryPolicy {
|
|||||||
return node->GetMTime();
|
return node->GetMTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t NodeGetAttribute(Node* node, const char* attribute,
|
static status_t NodeGetAttribute(NodeHolder& nodeHolder, Node* node,
|
||||||
void* buffer, size_t* _size, int32* _type)
|
const char* attribute, void* buffer, size_t* _size, int32* _type)
|
||||||
{
|
{
|
||||||
Attribute* attr = NULL;
|
Attribute* attr = NULL;
|
||||||
status_t error = node->FindAttribute(attribute, &attr);
|
status_t error = node->FindAttribute(attribute, &attr);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
#include <fs_query.h>
|
||||||
|
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
|
|
||||||
@@ -26,9 +27,6 @@ class Node;
|
|||||||
class Volume;
|
class Volume;
|
||||||
|
|
||||||
|
|
||||||
#define B_QUERY_NON_INDEXED 0x00000002
|
|
||||||
|
|
||||||
|
|
||||||
class Query : public DoublyLinkedListLinkImpl<Query> {
|
class Query : public DoublyLinkedListLinkImpl<Query> {
|
||||||
public:
|
public:
|
||||||
~Query();
|
~Query();
|
||||||
|
|||||||
Reference in New Issue
Block a user