mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 15:28:58 +01:00
file_systems/QueryParser: Coerce types up front, and handle B_TIME_TYPE better.
* If we coerce types inside the switch(), then the "type already converted" check at the beginning will fail every time, causing us to reconvert, which is surely bad for performance. * B_TIME_TYPE should be INT32 or INT64 depending on what its size is. May help with #19080.
This commit is contained in:
parent
783b77b14f
commit
cc9ea55c59
@ -267,7 +267,7 @@ private:
|
|||||||
Equation& operator=(const Equation& other);
|
Equation& operator=(const Equation& other);
|
||||||
// no implementation
|
// no implementation
|
||||||
|
|
||||||
status_t ConvertValue(type_code type);
|
status_t ConvertValue(type_code type, uint32 size);
|
||||||
bool CompareTo(const uint8* value, size_t size);
|
bool CompareTo(const uint8* value, size_t size);
|
||||||
uint8* Value() const { return (uint8*)&fValue; }
|
uint8* Value() const { return (uint8*)&fValue; }
|
||||||
|
|
||||||
@ -275,7 +275,7 @@ private:
|
|||||||
char* fString;
|
char* fString;
|
||||||
union value<QueryPolicy> fValue;
|
union value<QueryPolicy> fValue;
|
||||||
type_code fType;
|
type_code fType;
|
||||||
size_t fSize;
|
uint32 fSize;
|
||||||
bool fIsPattern;
|
bool fIsPattern;
|
||||||
|
|
||||||
int32 fScore;
|
int32 fScore;
|
||||||
@ -585,8 +585,14 @@ Equation<QueryPolicy>::_IsOperatorChar(char c) const
|
|||||||
|
|
||||||
template<typename QueryPolicy>
|
template<typename QueryPolicy>
|
||||||
status_t
|
status_t
|
||||||
Equation<QueryPolicy>::ConvertValue(type_code type)
|
Equation<QueryPolicy>::ConvertValue(type_code type, uint32 size)
|
||||||
{
|
{
|
||||||
|
// Perform type coercion up-front, so we don't re-convert every time.
|
||||||
|
if (type == B_MIME_STRING_TYPE)
|
||||||
|
type = B_STRING_TYPE;
|
||||||
|
else if (type == B_TIME_TYPE)
|
||||||
|
type = (size == 4) ? B_INT32_TYPE : B_INT64_TYPE;
|
||||||
|
|
||||||
// Has the type already been converted?
|
// Has the type already been converted?
|
||||||
if (type == fType)
|
if (type == fType)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -594,9 +600,6 @@ Equation<QueryPolicy>::ConvertValue(type_code type)
|
|||||||
char* string = fString;
|
char* string = fString;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case B_MIME_STRING_TYPE:
|
|
||||||
type = B_STRING_TYPE;
|
|
||||||
// supposed to fall through
|
|
||||||
case B_STRING_TYPE:
|
case B_STRING_TYPE:
|
||||||
strncpy(fValue.String, string, QueryPolicy::kMaxFileNameLength);
|
strncpy(fValue.String, string, QueryPolicy::kMaxFileNameLength);
|
||||||
fValue.String[QueryPolicy::kMaxFileNameLength - 1] = '\0';
|
fValue.String[QueryPolicy::kMaxFileNameLength - 1] = '\0';
|
||||||
@ -610,9 +613,6 @@ Equation<QueryPolicy>::ConvertValue(type_code type)
|
|||||||
fValue.Int32 = strtoul(string, &string, 0);
|
fValue.Int32 = strtoul(string, &string, 0);
|
||||||
fSize = sizeof(uint32);
|
fSize = sizeof(uint32);
|
||||||
break;
|
break;
|
||||||
case B_TIME_TYPE:
|
|
||||||
type = B_INT64_TYPE;
|
|
||||||
// supposed to fall through
|
|
||||||
case B_INT64_TYPE:
|
case B_INT64_TYPE:
|
||||||
fValue.Int64 = strtoll(string, &string, 0);
|
fValue.Int64 = strtoll(string, &string, 0);
|
||||||
fSize = sizeof(int64);
|
fSize = sizeof(int64);
|
||||||
@ -744,7 +744,7 @@ Equation<QueryPolicy>::Match(Entry* entry, Node* node,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// prepare own value for use, if it is possible to convert it
|
// prepare own value for use, if it is possible to convert it
|
||||||
status_t status = ConvertValue(type);
|
status_t status = ConvertValue(type, size);
|
||||||
if (status == B_OK)
|
if (status == B_OK)
|
||||||
status = CompareTo(buffer, size) ? MATCH_OK : NO_MATCH;
|
status = CompareTo(buffer, size) ? MATCH_OK : NO_MATCH;
|
||||||
|
|
||||||
@ -821,7 +821,8 @@ Equation<QueryPolicy>::PrepareQuery(Context* /*context*/, Index& index,
|
|||||||
type = QueryPolicy::IndexGetType(index);
|
type = QueryPolicy::IndexGetType(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConvertValue(type) < B_OK)
|
int32 keySize = QueryPolicy::IndexGetKeySize(index);
|
||||||
|
if (ConvertValue(type, keySize) < B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
*iterator = QueryPolicy::IndexCreateIterator(index);
|
*iterator = QueryPolicy::IndexCreateIterator(index);
|
||||||
@ -834,8 +835,6 @@ Equation<QueryPolicy>::PrepareQuery(Context* /*context*/, Index& index,
|
|||||||
&& fHasIndex) {
|
&& fHasIndex) {
|
||||||
// set iterator to the exact position
|
// set iterator to the exact position
|
||||||
|
|
||||||
int32 keySize = QueryPolicy::IndexGetKeySize(index);
|
|
||||||
|
|
||||||
// At this point, fIsPattern is only true if it's a string type, and fOp
|
// At this point, fIsPattern is only true if it's a string type, and fOp
|
||||||
// is either OP_EQUAL or OP_UNEQUAL
|
// is either OP_EQUAL or OP_UNEQUAL
|
||||||
if (fIsPattern) {
|
if (fIsPattern) {
|
||||||
|
Loading…
Reference in New Issue
Block a user