From 3a17bd3545a4a82a1daa00bcb0baf21676a6f242 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Fri, 31 May 2024 00:03:58 -0400 Subject: [PATCH] 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 Tested-by: Commit checker robot --- headers/private/file_systems/QueryParser.h | 39 ++++++++++++------- .../file_systems/packagefs/indices/Query.cpp | 27 +++++++++---- .../kernel/file_systems/ramfs/Query.cpp | 28 +++++++++---- src/add-ons/kernel/file_systems/ramfs/Query.h | 4 +- 4 files changed, 68 insertions(+), 30 deletions(-) diff --git a/headers/private/file_systems/QueryParser.h b/headers/private/file_systems/QueryParser.h index 4f7f5ef5a7..b372202760 100644 --- a/headers/private/file_systems/QueryParser.h +++ b/headers/private/file_systems/QueryParser.h @@ -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::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 value; uint8* buffer = (uint8*)&value; const size_t bufferSize = sizeof(value); @@ -729,8 +733,7 @@ Equation::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::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::GetNextMatching(Context* context, IndexIterator* iterator, struct dirent* dirent, size_t bufferSize) { while (true) { + NodeHolder nodeHolder; union value 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::GetNextMatching(Context* context, || (Term::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::_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, diff --git a/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp b/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp index b8c777959c..7f7c71e04d 100644 --- a/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/indices/Query.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/ramfs/Query.cpp b/src/add-ons/kernel/file_systems/ramfs/Query.cpp index 41b62460be..5d126a6ee0 100644 --- a/src/add-ons/kernel/file_systems/ramfs/Query.cpp +++ b/src/add-ons/kernel/file_systems/ramfs/Query.cpp @@ -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); diff --git a/src/add-ons/kernel/file_systems/ramfs/Query.h b/src/add-ons/kernel/file_systems/ramfs/Query.h index 2215e2c860..547d1cee88 100644 --- a/src/add-ons/kernel/file_systems/ramfs/Query.h +++ b/src/add-ons/kernel/file_systems/ramfs/Query.h @@ -11,6 +11,7 @@ #include #include +#include #include @@ -26,9 +27,6 @@ class Node; class Volume; -#define B_QUERY_NON_INDEXED 0x00000002 - - class Query : public DoublyLinkedListLinkImpl { public: ~Query();