Skip to content

Commit

Permalink
Store node attributes as floats or strings
Browse files Browse the repository at this point in the history
Store node attributes as floats or strings
  • Loading branch information
cadop authored Jan 14, 2025
2 parents d1d5132 + c398791 commit 7587a53
Show file tree
Hide file tree
Showing 8 changed files with 1,155 additions and 121 deletions.
86 changes: 83 additions & 3 deletions src/Cinterface/spatialstructures_C.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,38 @@ C_INTERFACE AddNodeAttributes(
return OK;
}

C_INTERFACE AddNodeAttributesFloat(
Graph* g,
const int* ids,
const char* attribute,
const float* scores,
int num_nodes
)
{
// It is easy to convert raw pointers that are known to point to buffers/arrays
// to a std::vector.

// ids is the base address, and ids + num_nodes is one-past the last address allocated for ids.
std::vector<int> v_ids(ids, ids + num_nodes);

// scores is the base address, and scores + num_nodes is one-past the last address allocated for scores.
std::vector<float> v_scores(scores, scores + num_nodes);

// If it turns out that v_ids and v_scores have different sizes,
// AddNodeAttributes will discover this.
try {
g->AddNodeAttributesFloat(v_ids, std::string(attribute), v_scores);
}
catch (std::logic_error) {
//return HF_STATUS::OUT_OF_RANGE;
assert(false); // This is purely due to programmer error. The top of this function should
// ONLY read num_nodes elements from either array, and this exception will
// only throw if the length of scores and ids is different
}

return OK;
}

C_INTERFACE GetNodeAttributes(const HF::SpatialStructures::Graph* g, const char* attribute,
char** out_scores, int* out_score_size) {
// get all node attributes from the graph
Expand Down Expand Up @@ -352,9 +384,7 @@ C_INTERFACE GetNodeAttributes(const HF::SpatialStructures::Graph* g, const char*
C_INTERFACE GetNodeAttributesByID(const HF::SpatialStructures::Graph* g, const int* ids, const char* attribute, int num_nodes,
char** out_scores, int* out_score_size) {

// If IDs are specified, create vector to use
// (std::vector<int>, std::string) defintion of GetNodeAttributes
// ids is base address, ids + num_nodes is end address
// If IDs are specified, create vector for them
vector<int> v_ids(ids, ids + num_nodes);
vector<string> v_attrs = g->GetNodeAttributesByID(v_ids, std::string(attribute));

Expand Down Expand Up @@ -384,6 +414,56 @@ C_INTERFACE GetNodeAttributesByID(const HF::SpatialStructures::Graph* g, const i
return OK;
}

C_INTERFACE GetNodeAttributesFloat(const HF::SpatialStructures::Graph* g, const char* attribute,
float* out_scores, int* out_score_size) {
// get all node attributes from the graph
vector<float> v_attrs = g->GetNodeAttributesFloat(std::string(attribute));

// Iterate through each returned value and copy it into
// the output array
for (int i = 0; i < v_attrs.size(); i++) {
// Copy the contents of v_attrs into the output array
std::memcpy(&out_scores[i], &v_attrs[i], sizeof(float));
}

// Update the *out_score_size value, which corresponds to v_attrs.size().
// (it also corresponds to i, but this notation using v_attrs.size() is easier to understand)
*out_score_size = v_attrs.size();

// If v_attrs.size() == 0, do we want to throw an exception,
// which would mean that attribute does not exist as a attribute type?
return OK;
}

C_INTERFACE GetNodeAttributesByIDFloat(const HF::SpatialStructures::Graph* g, const int* ids, const char* attribute, int num_nodes,
float* out_scores, int* out_score_size) {

// If IDs are specified, create vector for them
vector<int> v_ids(ids, ids + num_nodes);
vector<float> v_attrs = g->GetNodeAttributesByIDFloat(v_ids, std::string(attribute));

// Iterate through each returned value and copy it into
// the output array
for (int i = 0; i < v_attrs.size(); i++)
{
// Copy the contents of v_attrs into the output array
std::memcpy(&out_scores[i], &v_attrs[i], sizeof(float));
}

// Update the *out_score_size value, which corresponds to v_attrs.size().
// (it also corresponds to i, but this notation using v_attrs.size() is easier to understand)
*out_score_size = v_attrs.size();

// If v_attrs.size() == 0, do we want to throw an exception,
// which would mean that attribute does not exist as a attribute type?
return OK;
}

C_INTERFACE IsFloatAttribute(const HF::SpatialStructures::Graph* g, const char* attribute)
{
return g->IsFloatAttribute(std::string(attribute));
}

C_INTERFACE DeleteScoreArray(char** scores_to_delete, int num_char_arrays) {
// If it's null, then just ignore it
if (scores_to_delete) {
Expand Down
163 changes: 159 additions & 4 deletions src/Cinterface/spatialstructures_C.h
Original file line number Diff line number Diff line change
Expand Up @@ -756,6 +756,8 @@ C_INTERFACE CalculateAndStoreEnergyExpenditure(HF::SpatialStructures::Graph* g);
\see \ref graph_setup (how to create a graph)
\see \ref graph_add_edge_from_nodes (how to add edges to a graph using nodes)
\see \ref graph_add_edge_from_node_ids (how to add edges to a graph using node IDs)
\see \link GetNodeAttributes \endlink (how to get string node attributes)
\see \link GetNodeAttributesByID \endlink (how to get string node attributes by node ID)
\see \ref graph_compress (how to compress a graph after adding/removing edges)
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
\see \ref graph_teardown (how to destroy a graph)
Expand All @@ -780,6 +782,56 @@ C_INTERFACE AddNodeAttributes(
int num_nodes
);

/*!
\brief Add a new float node attribute in the graph for the nodes at ids.
\param g Graph to add attributes to
\param ids IDs of nodes to add attributes to
\param attribute The name of the attribute to add the scores to.
\param scores An ordered array of floats
that correspond to the score of the ID in ids at the same index.
\param num_nodes Length of both the ids and scores arrays
\returns \link HF_STATUS::OK \endlink on completion.
Note that this does not guarantee that some
or all of the node attributes have been added
\details
For any id in ids, if said ID doesn't already exist in the graph, then it and its cost will
silently be ignored without error.
\pre ids and scores arrays must be the same length
\see \ref graph_setup (how to create a graph)
\see \ref graph_add_edge_from_nodes (how to add edges to a graph using nodes)
\see \ref graph_add_edge_from_node_ids (how to add edges to a graph using node IDs)
\see \link GetNodeAttributesFloat \endlink (how to get float node attributes)
\see \link GetNodeAttributesByIDFloat \endlink (how to get float node attributes by node ID)
\see \ref graph_compress (how to compress a graph after adding/removing edges)
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
\see \ref graph_teardown (how to destroy a graph)
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
You may add edges to the graph using nodes (\ref graph_add_edge_from_nodes)<br>
or alternative, you may provide node IDs (\ref graph_add_edge_from_node_IDs).<br>
Be sure to compress the graph (\ref graph_compress) every time you add/remove edges.<br>
\snippet tests\src\spatialstructures_C_cinterface.cpp snippet_spatialstructuresC_AddNodeAttributesFloat
Finally, when you are finished with the graph,<br>
it must be destroyed. (\ref graph_teardown)
*/
C_INTERFACE AddNodeAttributesFloat(
HF::SpatialStructures::Graph* g,
const int* ids,
const char* attribute,
const float* scores,
int num_nodes
);
/*!
\brief Retrieve node attribute values from *g
Expand All @@ -791,6 +843,8 @@ C_INTERFACE AddNodeAttributes(
\param out_score_size Keeps track of the size of out_scores buffer,
updated as required
\pre `attribute` is a string attribute. That is, at least one string value has been added to this attribute.
\returns \link HF_STATUS::OK \endlink on completion.
\details Memory shall be allocated in *out_scores to hold the char arrays.
Expand All @@ -802,8 +856,8 @@ C_INTERFACE AddNodeAttributes(
\see \ref graph_setup (how to create a graph)
\see \ref graph_compress (how to compress a graph after adding/removing edges)
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
\see \link AddNodeAttributes \endlink (how to add node attributes)
\see \link GetNodeAttributesByID \endlink (how to get node attributes by node ID)
\see \link AddNodeAttributes \endlink (how to add string node attributes)
\see \link GetNodeAttributesByID \endlink (how to get string node attributes by node ID)
\see \ref graph_teardown (how to destroy a graph)
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
Expand Down Expand Up @@ -835,6 +889,7 @@ C_INTERFACE GetNodeAttributes(
\pre All node IDs in `ids` must exist in graph `g`.
\pre If `ids` is not NULL, `num_nodes` must be equal to the length of `ids`.
\pre `attribute` is a string attribute. That is, at least one string value has been added to this attribute.
\returns \link HF_STATUS::OK \endlink on completion.
\details For the ID at `ids[i]`, `out_scores[i]` is the value of the attribute for the
Expand All @@ -852,8 +907,8 @@ C_INTERFACE GetNodeAttributes(
\see \ref graph_setup (how to create a graph)
\see \ref graph_compress (how to compress a graph after adding/removing edges)
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
\see \link AddNodeAttributes \endlink (how to add node attributes)
\see \link GetNodeAttributes \endlink (how to get node attributes)
\see \link AddNodeAttributes \endlink (how to add string node attributes)
\see \link GetNodeAttributes \endlink (how to get string node attributes)
\see \ref graph_teardown (how to destroy a graph)
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
Expand All @@ -871,6 +926,106 @@ C_INTERFACE GetNodeAttributesByID(
char** out_scores,
int* out_score_size
);
/*!
\brief Retrieve float node attribute values from *g
\param g The graph that will be used to retrieve
node attribute values from
\param attribute The node attribute type to retrieve from *g
\param out_scores Pointer to array of float, allocated by the caller
\param out_score_size Keeps track of the size of out_scores buffer,
updated as required
\pre `attribute` is a float attribute. That is, only float values have been added to this attribute.
\returns \link HF_STATUS::OK \endlink on completion.
\details The caller must deallocate the memory addressed by out_scores.
\see \ref graph_setup (how to create a graph)
\see \ref graph_compress (how to compress a graph after adding/removing edges)
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
\see \link AddNodeAttributesFloat \endlink (how to add float node attributes)
\see \link GetNodeAttributesByIDFloat \endlink (how to get float node attributes by node ID)
\see \ref graph_teardown (how to destroy a graph)
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
\snippet tests\src\spatialstructures_C_cinterface.cpp snippet_spatialstructuresC_GetNodeAttributesFloat
Finally, when you are finished with the graph,<br>
it must be destroyed. (\ref graph_teardown)
*/
C_INTERFACE GetNodeAttributesFloat(
const HF::SpatialStructures::Graph* g,
const char* attribute,
float* out_scores,
int* out_score_size
);

/*!
\brief Retrieve float node attribute values from *g
\param g The graph that will be used to retrieve
node attribute values from
\param ids The list of node IDs to get attributes for.
If NULL, returns attributes for all nodes.
\param attribute The node attribute type to retrieve from *g
\param num_nodes The length of the ids array
\param out_scores Pointer to array of floats, allocated by the caller
\param out_score_size Keeps track of the size of out_scores buffer,
updated as required
\pre All node IDs in `ids` must exist in graph `g`.
\pre If `ids` is not NULL, `num_nodes` must be equal to the length of `ids`.
\pre `attribute` is a float attribute. That is, only float values have been added to this attribute.
\returns \link HF_STATUS::OK \endlink on completion.
\details For the ID at `ids[i]`, `out_scores[i]` is the value of the attribute for the
node associated with that ID.
If `ids` is NULL, `out_scores` is an array holding the value of the attribute for
all nodes, sorted in ascending order by ID.
The caller must deallocate the memory addressed by out_scores.
\see \ref graph_setup (how to create a graph)
\see \ref graph_compress (how to compress a graph after adding/removing edges)
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
\see \link AddNodeAttributesFloat \endlink (how to add float node attributes)
\see \link GetNodeAttributesFloat \endlink (how to get float node attributes)
\see \ref graph_teardown (how to destroy a graph)
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
\snippet tests\src\spatialstructures_C_cinterface.cpp snippet_spatialstructuresC_GetNodeAttributesByIDFloat
Finally, when you are finished with the graph,<br>
it must be destroyed. (\ref graph_teardown)
*/
C_INTERFACE GetNodeAttributesByIDFloat(
const HF::SpatialStructures::Graph* g,
const int* ids,
const char* attribute,
int num_nodes,
float* out_scores,
int* out_score_size
);

/*!
\brief Check whether or not an attribute is stored with float values in a graph.
\param g The pointer of the graph to check
\param attribute The attribute to check
\returns 1 if the attribute exists in the graph and contains only float values.
0 otherwise.
*/
C_INTERFACE IsFloatAttribute(
const HF::SpatialStructures::Graph* g,
const char* attribute
);

/*!
\brief Free the memory of every (char *) in scores_to_delete.
Expand Down
Loading

0 comments on commit 7587a53

Please sign in to comment.