Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/graph equal optim #153

Draft
wants to merge 2 commits into
base: version/4.5
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/hash/fiftyone.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ MAP_TYPE(GraphTraceNode)
#define GraphTraceFree fiftyoneDegreesGraphTraceFree /**< Synonym for #fiftyoneDegreesGraphTraceFree function. */
#define GraphTraceAppend fiftyoneDegreesGraphTraceAppend /**< Synonym for #fiftyoneDegreesGraphTraceAppend function. */
#define GraphTraceGet fiftyoneDegreesGraphTraceGet /**< Synonym for #fiftyoneDegreesGraphTraceGet function. */
#define GraphGetMatchingHashFromListNodeSequential fiftyoneDegreesGraphGetMatchingHashFromListNodeSequential /**< Synonym for #fiftyoneDegreesGraphGetMatchingHashFromListNodeSequential function. */
/**
* @}
*/
Expand Down
78 changes: 56 additions & 22 deletions src/hash/graph.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,17 @@
*/
#define RK_PRIME 997

/**
* Array of powers for the RK_PRIME.
*/
/**
* Used to compare specific elements in an array.
*/
#define GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(i) \
if (nodeHashes[i].hashCode == hash) { \
return &nodeHashes[i]; \
}

/**
* Array of powers for the RK_PRIME.
*/
#ifndef FIFTYONE_DEGREES_POWERS
#define FIFTYONE_DEGREES_POWERS
static unsigned int POWERS[129] = {
Expand Down Expand Up @@ -118,13 +126,12 @@ fiftyoneDegreesGraphNodeHash*
fiftyoneDegreesGraphGetMatchingHashFromListNodeTable(
fiftyoneDegreesGraphNode *node,
uint32_t hash) {
fiftyoneDegreesGraphNodeHash *foundHash = NULL;
fiftyoneDegreesGraphNodeHash *nodeHashes = (GraphNodeHash*)(node + 1);
GraphNodeHash *nodeHashes = (GraphNodeHash*)(node + 1);
int index = hash % node->modulo;
fiftyoneDegreesGraphNodeHash *nodeHash = &nodeHashes[index];
GraphNodeHash *nodeHash = &nodeHashes[index];
if (hash == nodeHash->hashCode) {
// There is a single record at this index and it matched, so return it.
foundHash = nodeHash;
return nodeHash;
}
else if (nodeHash->hashCode == 0 && nodeHash->nodeOffset > 0) {
// There are multiple records at this index, so go through them to find
Expand All @@ -133,54 +140,81 @@ fiftyoneDegreesGraphGetMatchingHashFromListNodeTable(
while (nodeHash->hashCode != 0) {
if (hash == nodeHash->hashCode) {
// There was a match, so stop looking.
foundHash = nodeHash;
break;
return nodeHash;
}
nodeHash++;
}
}
return foundHash;
return NULL;
}

fiftyoneDegreesGraphNodeHash*
fiftyoneDegreesGraphGetMatchingHashFromListNodeSearch(
fiftyoneDegreesGraphNode *node,
uint32_t hash) {
GraphNodeHash* foundHash = NULL;
GraphNodeHash* nodeHashes = (GraphNodeHash*)(node + 1);
int32_t lower = 0, upper = node->hashesCount - 1, middle;
uint32_t current;
while (lower <= upper) {
middle = lower + (upper - lower) / 2;
if (nodeHashes[middle].hashCode == hash) {
foundHash = &nodeHashes[middle];
break;
current = nodeHashes[middle].hashCode;
if (current == hash) {
return &nodeHashes[middle];
}
else if (nodeHashes[middle].hashCode > hash) {
else if (current > hash) {
upper = middle - 1;
}
else {
lower = middle + 1;
}
}
return foundHash;
return NULL;
}

fiftyoneDegreesGraphNodeHash*
fiftyoneDegreesGraphGetMatchingHashFromListNode(
fiftyoneDegreesGraphNode *node,
uint32_t hash) {
fiftyoneDegreesGraphNodeHash *foundHash;
GraphNodeHash* nodeHashes;
if (node->modulo == 0) {
foundHash = GraphGetMatchingHashFromListNodeSearch(
node,
hash);
if (node->hashesCount == 2) {
nodeHashes = (GraphNodeHash*)(node + 1);
GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(0)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(1)
}
else if (node->hashesCount == 3) {
nodeHashes = (GraphNodeHash*)(node + 1);
GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(0)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(1)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(2)
}
else if (node->hashesCount == 4) {
nodeHashes = (GraphNodeHash*)(node + 1);
GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(0)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(1)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(2)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(3)
}
else if (node->hashesCount == 5) {
nodeHashes = (GraphNodeHash*)(node + 1);
GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(0)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(1)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(2)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(3)
else GRAPH_GET_MATCHING_HASH_FROM_LIST_NODE_MATCH(4)
}
else {
return GraphGetMatchingHashFromListNodeSearch(
node,
hash);
}
}
else {
foundHash = GraphGetMatchingHashFromListNodeTable(
return GraphGetMatchingHashFromListNodeTable(
node,
hash);
}
return foundHash;
return NULL;
}

fiftyoneDegreesGraphNodeHash*
Expand Down
27 changes: 14 additions & 13 deletions src/hash/graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@
/** Hash record structure to compare to a substring hash. */
#pragma pack(push, 4)
typedef struct fiftyoneDegrees_graph_node_hash_t {
uint32_t hashCode; /**< Hash code to compare. */
int32_t nodeOffset; /**< Offset of the node to use if this hash code is a
match. */
uint32_t const hashCode; /**< Hash code to compare. */
int32_t const nodeOffset; /**< Offset of the node to use if this hash code
is a match. */
} fiftyoneDegreesGraphNodeHash;
#pragma pack(pop)

Expand Down Expand Up @@ -163,16 +163,17 @@ typedef struct fiftyoneDegrees_graph_trace_node_t {
*/
#pragma pack(push, 1)
typedef struct fiftyoneDegrees_graph_node_t {
int32_t unmatchedNodeOffset; /**< Offset of the node to use if there is no
matching hash record. */
byte flags; /**< Flags available for future implementation. */
int16_t firstIndex; /**< First character index to search for a matching
hash code. */
int16_t lastIndex; /**< Last character index to search for a matching hash
code. */
byte length; /**< Length of the substring to hash. */
int32_t hashesCount; /**< Number of hash records in the node. */
int32_t modulo; /**< Modulo to use when the hashes are a hash table. */
int32_t const unmatchedNodeOffset; /**< Offset of the node to use if there
is no matching hash record. */
byte const flags; /**< Flags available for future implementation. */
int16_t const firstIndex; /**< First character index to search for a
matching hash code. */
int16_t const lastIndex; /**< Last character index to search for a matching
hash code. */
byte const length; /**< Length of the substring to hash. */
int32_t const hashesCount; /**< Number of hash records in the node. */
int32_t const modulo; /**< Modulo to use when the hashes are a hash
table. */
} fiftyoneDegreesGraphNode;
#pragma pack(pop)

Expand Down