-
Notifications
You must be signed in to change notification settings - Fork 96
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2955977
commit 2f8bf24
Showing
12 changed files
with
255 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#pragma once | ||
|
||
#include <functional> | ||
|
||
#include "common/vector/value_vector.h" | ||
#include "function/hash/hash_functions.h" | ||
|
||
namespace kuzu { | ||
namespace function { | ||
|
||
static bool isAllInternalIDDistinct(common::ValueVector* dataVector, common::offset_t startOffset, | ||
uint64_t size, std::unordered_set<common::internalID_t, InternalIDHasher>& internalIDSet) { | ||
internalIDSet.clear(); | ||
for (auto i = 0; i < size; ++i) { | ||
auto& internalID = dataVector->getValue<common::internalID_t>(startOffset + i); | ||
if (internalIDSet.contains(internalID)) { | ||
return false; | ||
} | ||
internalIDSet.insert(internalID); | ||
} | ||
return true; | ||
} | ||
|
||
// Note: this executor is only used for isTrail and isAcyclic. So we add some ad-hoc optimization | ||
// into executor, e.g. internalIDSet. A more general implementation can be done once needed. But | ||
// pay attention to the performance drop. Depends on how bad it becomes, we may want to implement | ||
// customized executors. | ||
struct UnaryPathExecutor { | ||
static void executeNodeIDs(common::ValueVector& input, common::ValueVector& result) { | ||
auto nodesFieldIdx = 0; | ||
assert(nodesFieldIdx == | ||
common::StructType::getFieldIdx(&input.dataType, common::InternalKeyword::NODES)); | ||
auto nodesVector = common::StructVector::getFieldVector(&input, nodesFieldIdx).get(); | ||
auto internalIDFieldIdx = 0; | ||
execute(*input.state->selVector, *nodesVector, internalIDFieldIdx, result); | ||
} | ||
|
||
static void executeRelIDs(common::ValueVector& input, common::ValueVector& result) { | ||
auto relsFieldIdx = 1; | ||
assert(relsFieldIdx == | ||
common::StructType::getFieldIdx(&input.dataType, common::InternalKeyword::RELS)); | ||
auto relsVector = common::StructVector::getFieldVector(&input, relsFieldIdx).get(); | ||
auto internalIDFieldIdx = 3; | ||
execute(*input.state->selVector, *relsVector, internalIDFieldIdx, result); | ||
} | ||
|
||
static bool selectNodeIDs( | ||
common::ValueVector& input, common::SelectionVector& selectionVector) { | ||
auto nodesFieldIdx = 0; | ||
assert(nodesFieldIdx == | ||
common::StructType::getFieldIdx(&input.dataType, common::InternalKeyword::NODES)); | ||
auto nodesVector = common::StructVector::getFieldVector(&input, nodesFieldIdx).get(); | ||
auto internalIDFieldIdx = 0; | ||
return select(*input.state->selVector, *nodesVector, internalIDFieldIdx, selectionVector); | ||
} | ||
|
||
static bool selectRelIDs(common::ValueVector& input, common::SelectionVector& selectionVector) { | ||
auto relsFieldIdx = 1; | ||
assert(relsFieldIdx == | ||
common::StructType::getFieldIdx(&input.dataType, common::InternalKeyword::RELS)); | ||
auto relsVector = common::StructVector::getFieldVector(&input, relsFieldIdx).get(); | ||
auto internalIDFieldIdx = 3; | ||
return select(*input.state->selVector, *relsVector, internalIDFieldIdx, selectionVector); | ||
} | ||
|
||
private: | ||
static void execute(const common::SelectionVector& inputSelVector, | ||
common::ValueVector& listVector, common::struct_field_idx_t fieldIdx, | ||
common::ValueVector& result) { | ||
auto listDataVector = common::ListVector::getDataVector(&listVector); | ||
assert(fieldIdx == common::StructType::getFieldIdx( | ||
&listDataVector->dataType, common::InternalKeyword::ID)); | ||
auto internalIDsVector = | ||
common::StructVector::getFieldVector(listDataVector, fieldIdx).get(); | ||
std::unordered_set<common::nodeID_t, InternalIDHasher> internalIDSet; | ||
if (inputSelVector.isUnfiltered()) { | ||
for (auto i = 0; i < inputSelVector.selectedSize; ++i) { | ||
auto& listEntry = listVector.getValue<common::list_entry_t>(i); | ||
bool isTrail = isAllInternalIDDistinct( | ||
internalIDsVector, listEntry.offset, listEntry.size, internalIDSet); | ||
result.setValue<bool>(i, isTrail); | ||
} | ||
} else { | ||
for (auto i = 0; i < inputSelVector.selectedSize; ++i) { | ||
auto pos = inputSelVector.selectedPositions[i]; | ||
auto& listEntry = listVector.getValue<common::list_entry_t>(pos); | ||
bool isTrail = isAllInternalIDDistinct( | ||
internalIDsVector, listEntry.offset, listEntry.size, internalIDSet); | ||
result.setValue<bool>(pos, isTrail); | ||
} | ||
} | ||
} | ||
|
||
static bool select(const common::SelectionVector& inputSelVector, | ||
common::ValueVector& listVector, common::struct_field_idx_t fieldIdx, | ||
common::SelectionVector& selectionVector) { | ||
auto listDataVector = common::ListVector::getDataVector(&listVector); | ||
assert(fieldIdx == common::StructType::getFieldIdx( | ||
&listDataVector->dataType, common::InternalKeyword::ID)); | ||
auto internalIDsVector = | ||
common::StructVector::getFieldVector(listDataVector, fieldIdx).get(); | ||
std::unordered_set<common::nodeID_t, InternalIDHasher> internalIDSet; | ||
auto numSelectedValues = 0u; | ||
auto buffer = selectionVector.getSelectedPositionsBuffer(); | ||
if (inputSelVector.isUnfiltered()) { | ||
for (auto i = 0; i < inputSelVector.selectedSize; ++i) { | ||
auto& listEntry = listVector.getValue<common::list_entry_t>(i); | ||
bool isTrail = isAllInternalIDDistinct( | ||
internalIDsVector, listEntry.offset, listEntry.size, internalIDSet); | ||
buffer[numSelectedValues] = i; | ||
numSelectedValues += isTrail; | ||
} | ||
} else { | ||
for (auto i = 0; i < inputSelVector.selectedSize; ++i) { | ||
auto pos = inputSelVector.selectedPositions[i]; | ||
auto& listEntry = listVector.getValue<common::list_entry_t>(pos); | ||
bool isTrail = isAllInternalIDDistinct( | ||
internalIDsVector, listEntry.offset, listEntry.size, internalIDSet); | ||
buffer[numSelectedValues] = pos; | ||
numSelectedValues += isTrail; | ||
} | ||
} | ||
selectionVector.selectedSize = numSelectedValues; | ||
return numSelectedValues > 0; | ||
} | ||
}; | ||
|
||
} // namespace function | ||
} // namespace kuzu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
-GROUP TinySnbReadTest | ||
-DATASET CSV tinysnb | ||
|
||
-- | ||
|
||
-CASE FunctionPath | ||
|
||
-LOG PathFun1 | ||
-STATEMENT MATCH p = (a:person)-[:knows]->(b:person)-[:knows]->(c:person) WHERE a.ID = 0 AND b.ID = 2 RETURN a.ID, b.ID, c.ID, is_acyclic(p) | ||
---- 3 | ||
0|2|0|False | ||
0|2|3|True | ||
0|2|5|True | ||
|
||
-LOG PathFun2 | ||
-STATEMENT MATCH p = (a:person)-[e:knows*2..2]->(b:person) WHERE is_acyclic(p) RETURN COUNT(*) | ||
---- 1 | ||
24 | ||
|
||
-LOG PathFun3 | ||
-STATEMENT MATCH p = (a:person)-[e1:knows]->(b:person)-[e2:knows]-(c:person) WHERE a.ID = 0 AND b.ID = 2 AND is_trail(p) RETURN COUNT(*) | ||
---- 1 | ||
5 | ||
|
||
-LOG PathFun4 | ||
-STATEMENT MATCH p = (a)-[e:knows|:studyAt|:workAt*1..2]-(b) WHERE a.ID=7 RETURN properties(nodes(p), 'ID'), is_acyclic(p) | ||
---- 8 | ||
[7,6,5]|True | ||
[7,6,7]|False | ||
[7,6]|True | ||
[7,8,1]|True | ||
[7,8,7]|False | ||
[7,8]|True | ||
[7,9,7]|False | ||
[7,9]|True | ||
|
||
-LOG PathFun5 | ||
-STATEMENT MATCH p = (a)-[e:knows*1..2]-(b) WHERE a.ID=7 RETURN properties(rels(p), '_id'), is_trail(p) | ||
---- 4 | ||
[3:12,3:12]|False | ||
[3:12]|True | ||
[3:13,3:13]|False | ||
[3:13]|True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters