Skip to content

Commit 7587a53

Browse files
authored
Store node attributes as floats or strings
Store node attributes as floats or strings
2 parents d1d5132 + c398791 commit 7587a53

File tree

8 files changed

+1155
-121
lines changed

8 files changed

+1155
-121
lines changed

src/Cinterface/spatialstructures_C.cpp

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,38 @@ C_INTERFACE AddNodeAttributes(
319319
return OK;
320320
}
321321

322+
C_INTERFACE AddNodeAttributesFloat(
323+
Graph* g,
324+
const int* ids,
325+
const char* attribute,
326+
const float* scores,
327+
int num_nodes
328+
)
329+
{
330+
// It is easy to convert raw pointers that are known to point to buffers/arrays
331+
// to a std::vector.
332+
333+
// ids is the base address, and ids + num_nodes is one-past the last address allocated for ids.
334+
std::vector<int> v_ids(ids, ids + num_nodes);
335+
336+
// scores is the base address, and scores + num_nodes is one-past the last address allocated for scores.
337+
std::vector<float> v_scores(scores, scores + num_nodes);
338+
339+
// If it turns out that v_ids and v_scores have different sizes,
340+
// AddNodeAttributes will discover this.
341+
try {
342+
g->AddNodeAttributesFloat(v_ids, std::string(attribute), v_scores);
343+
}
344+
catch (std::logic_error) {
345+
//return HF_STATUS::OUT_OF_RANGE;
346+
assert(false); // This is purely due to programmer error. The top of this function should
347+
// ONLY read num_nodes elements from either array, and this exception will
348+
// only throw if the length of scores and ids is different
349+
}
350+
351+
return OK;
352+
}
353+
322354
C_INTERFACE GetNodeAttributes(const HF::SpatialStructures::Graph* g, const char* attribute,
323355
char** out_scores, int* out_score_size) {
324356
// get all node attributes from the graph
@@ -352,9 +384,7 @@ C_INTERFACE GetNodeAttributes(const HF::SpatialStructures::Graph* g, const char*
352384
C_INTERFACE GetNodeAttributesByID(const HF::SpatialStructures::Graph* g, const int* ids, const char* attribute, int num_nodes,
353385
char** out_scores, int* out_score_size) {
354386

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

@@ -384,6 +414,56 @@ C_INTERFACE GetNodeAttributesByID(const HF::SpatialStructures::Graph* g, const i
384414
return OK;
385415
}
386416

417+
C_INTERFACE GetNodeAttributesFloat(const HF::SpatialStructures::Graph* g, const char* attribute,
418+
float* out_scores, int* out_score_size) {
419+
// get all node attributes from the graph
420+
vector<float> v_attrs = g->GetNodeAttributesFloat(std::string(attribute));
421+
422+
// Iterate through each returned value and copy it into
423+
// the output array
424+
for (int i = 0; i < v_attrs.size(); i++) {
425+
// Copy the contents of v_attrs into the output array
426+
std::memcpy(&out_scores[i], &v_attrs[i], sizeof(float));
427+
}
428+
429+
// Update the *out_score_size value, which corresponds to v_attrs.size().
430+
// (it also corresponds to i, but this notation using v_attrs.size() is easier to understand)
431+
*out_score_size = v_attrs.size();
432+
433+
// If v_attrs.size() == 0, do we want to throw an exception,
434+
// which would mean that attribute does not exist as a attribute type?
435+
return OK;
436+
}
437+
438+
C_INTERFACE GetNodeAttributesByIDFloat(const HF::SpatialStructures::Graph* g, const int* ids, const char* attribute, int num_nodes,
439+
float* out_scores, int* out_score_size) {
440+
441+
// If IDs are specified, create vector for them
442+
vector<int> v_ids(ids, ids + num_nodes);
443+
vector<float> v_attrs = g->GetNodeAttributesByIDFloat(v_ids, std::string(attribute));
444+
445+
// Iterate through each returned value and copy it into
446+
// the output array
447+
for (int i = 0; i < v_attrs.size(); i++)
448+
{
449+
// Copy the contents of v_attrs into the output array
450+
std::memcpy(&out_scores[i], &v_attrs[i], sizeof(float));
451+
}
452+
453+
// Update the *out_score_size value, which corresponds to v_attrs.size().
454+
// (it also corresponds to i, but this notation using v_attrs.size() is easier to understand)
455+
*out_score_size = v_attrs.size();
456+
457+
// If v_attrs.size() == 0, do we want to throw an exception,
458+
// which would mean that attribute does not exist as a attribute type?
459+
return OK;
460+
}
461+
462+
C_INTERFACE IsFloatAttribute(const HF::SpatialStructures::Graph* g, const char* attribute)
463+
{
464+
return g->IsFloatAttribute(std::string(attribute));
465+
}
466+
387467
C_INTERFACE DeleteScoreArray(char** scores_to_delete, int num_char_arrays) {
388468
// If it's null, then just ignore it
389469
if (scores_to_delete) {

src/Cinterface/spatialstructures_C.h

Lines changed: 159 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,8 @@ C_INTERFACE CalculateAndStoreEnergyExpenditure(HF::SpatialStructures::Graph* g);
756756
\see \ref graph_setup (how to create a graph)
757757
\see \ref graph_add_edge_from_nodes (how to add edges to a graph using nodes)
758758
\see \ref graph_add_edge_from_node_ids (how to add edges to a graph using node IDs)
759+
\see \link GetNodeAttributes \endlink (how to get string node attributes)
760+
\see \link GetNodeAttributesByID \endlink (how to get string node attributes by node ID)
759761
\see \ref graph_compress (how to compress a graph after adding/removing edges)
760762
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
761763
\see \ref graph_teardown (how to destroy a graph)
@@ -780,6 +782,56 @@ C_INTERFACE AddNodeAttributes(
780782
int num_nodes
781783
);
782784

785+
/*!
786+
\brief Add a new float node attribute in the graph for the nodes at ids.
787+
788+
\param g Graph to add attributes to
789+
\param ids IDs of nodes to add attributes to
790+
\param attribute The name of the attribute to add the scores to.
791+
792+
\param scores An ordered array of floats
793+
that correspond to the score of the ID in ids at the same index.
794+
795+
\param num_nodes Length of both the ids and scores arrays
796+
797+
\returns \link HF_STATUS::OK \endlink on completion.
798+
Note that this does not guarantee that some
799+
or all of the node attributes have been added
800+
801+
\details
802+
For any id in ids, if said ID doesn't already exist in the graph, then it and its cost will
803+
silently be ignored without error.
804+
805+
\pre ids and scores arrays must be the same length
806+
807+
\see \ref graph_setup (how to create a graph)
808+
\see \ref graph_add_edge_from_nodes (how to add edges to a graph using nodes)
809+
\see \ref graph_add_edge_from_node_ids (how to add edges to a graph using node IDs)
810+
\see \link GetNodeAttributesFloat \endlink (how to get float node attributes)
811+
\see \link GetNodeAttributesByIDFloat \endlink (how to get float node attributes by node ID)
812+
\see \ref graph_compress (how to compress a graph after adding/removing edges)
813+
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
814+
\see \ref graph_teardown (how to destroy a graph)
815+
816+
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
817+
818+
You may add edges to the graph using nodes (\ref graph_add_edge_from_nodes)<br>
819+
or alternative, you may provide node IDs (\ref graph_add_edge_from_node_IDs).<br>
820+
821+
Be sure to compress the graph (\ref graph_compress) every time you add/remove edges.<br>
822+
823+
\snippet tests\src\spatialstructures_C_cinterface.cpp snippet_spatialstructuresC_AddNodeAttributesFloat
824+
825+
Finally, when you are finished with the graph,<br>
826+
it must be destroyed. (\ref graph_teardown)
827+
*/
828+
C_INTERFACE AddNodeAttributesFloat(
829+
HF::SpatialStructures::Graph* g,
830+
const int* ids,
831+
const char* attribute,
832+
const float* scores,
833+
int num_nodes
834+
);
783835
/*!
784836
\brief Retrieve node attribute values from *g
785837
@@ -791,6 +843,8 @@ C_INTERFACE AddNodeAttributes(
791843
\param out_score_size Keeps track of the size of out_scores buffer,
792844
updated as required
793845
846+
\pre `attribute` is a string attribute. That is, at least one string value has been added to this attribute.
847+
794848
\returns \link HF_STATUS::OK \endlink on completion.
795849
796850
\details Memory shall be allocated in *out_scores to hold the char arrays.
@@ -802,8 +856,8 @@ C_INTERFACE AddNodeAttributes(
802856
\see \ref graph_setup (how to create a graph)
803857
\see \ref graph_compress (how to compress a graph after adding/removing edges)
804858
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
805-
\see \link AddNodeAttributes \endlink (how to add node attributes)
806-
\see \link GetNodeAttributesByID \endlink (how to get node attributes by node ID)
859+
\see \link AddNodeAttributes \endlink (how to add string node attributes)
860+
\see \link GetNodeAttributesByID \endlink (how to get string node attributes by node ID)
807861
\see \ref graph_teardown (how to destroy a graph)
808862
809863
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
@@ -835,6 +889,7 @@ C_INTERFACE GetNodeAttributes(
835889
836890
\pre All node IDs in `ids` must exist in graph `g`.
837891
\pre If `ids` is not NULL, `num_nodes` must be equal to the length of `ids`.
892+
\pre `attribute` is a string attribute. That is, at least one string value has been added to this attribute.
838893
\returns \link HF_STATUS::OK \endlink on completion.
839894
840895
\details For the ID at `ids[i]`, `out_scores[i]` is the value of the attribute for the
@@ -852,8 +907,8 @@ C_INTERFACE GetNodeAttributes(
852907
\see \ref graph_setup (how to create a graph)
853908
\see \ref graph_compress (how to compress a graph after adding/removing edges)
854909
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
855-
\see \link AddNodeAttributes \endlink (how to add node attributes)
856-
\see \link GetNodeAttributes \endlink (how to get node attributes)
910+
\see \link AddNodeAttributes \endlink (how to add string node attributes)
911+
\see \link GetNodeAttributes \endlink (how to get string node attributes)
857912
\see \ref graph_teardown (how to destroy a graph)
858913
859914
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
@@ -871,6 +926,106 @@ C_INTERFACE GetNodeAttributesByID(
871926
char** out_scores,
872927
int* out_score_size
873928
);
929+
/*!
930+
\brief Retrieve float node attribute values from *g
931+
932+
\param g The graph that will be used to retrieve
933+
node attribute values from
934+
935+
\param attribute The node attribute type to retrieve from *g
936+
\param out_scores Pointer to array of float, allocated by the caller
937+
\param out_score_size Keeps track of the size of out_scores buffer,
938+
updated as required
939+
940+
\pre `attribute` is a float attribute. That is, only float values have been added to this attribute.
941+
942+
\returns \link HF_STATUS::OK \endlink on completion.
943+
944+
\details The caller must deallocate the memory addressed by out_scores.
945+
946+
\see \ref graph_setup (how to create a graph)
947+
\see \ref graph_compress (how to compress a graph after adding/removing edges)
948+
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
949+
\see \link AddNodeAttributesFloat \endlink (how to add float node attributes)
950+
\see \link GetNodeAttributesByIDFloat \endlink (how to get float node attributes by node ID)
951+
\see \ref graph_teardown (how to destroy a graph)
952+
953+
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
954+
955+
\snippet tests\src\spatialstructures_C_cinterface.cpp snippet_spatialstructuresC_GetNodeAttributesFloat
956+
957+
Finally, when you are finished with the graph,<br>
958+
it must be destroyed. (\ref graph_teardown)
959+
*/
960+
C_INTERFACE GetNodeAttributesFloat(
961+
const HF::SpatialStructures::Graph* g,
962+
const char* attribute,
963+
float* out_scores,
964+
int* out_score_size
965+
);
966+
967+
/*!
968+
\brief Retrieve float node attribute values from *g
969+
970+
\param g The graph that will be used to retrieve
971+
node attribute values from
972+
\param ids The list of node IDs to get attributes for.
973+
If NULL, returns attributes for all nodes.
974+
\param attribute The node attribute type to retrieve from *g
975+
\param num_nodes The length of the ids array
976+
\param out_scores Pointer to array of floats, allocated by the caller
977+
\param out_score_size Keeps track of the size of out_scores buffer,
978+
updated as required
979+
980+
\pre All node IDs in `ids` must exist in graph `g`.
981+
\pre If `ids` is not NULL, `num_nodes` must be equal to the length of `ids`.
982+
\pre `attribute` is a float attribute. That is, only float values have been added to this attribute.
983+
984+
\returns \link HF_STATUS::OK \endlink on completion.
985+
986+
\details For the ID at `ids[i]`, `out_scores[i]` is the value of the attribute for the
987+
node associated with that ID.
988+
989+
If `ids` is NULL, `out_scores` is an array holding the value of the attribute for
990+
all nodes, sorted in ascending order by ID.
991+
992+
The caller must deallocate the memory addressed by out_scores.
993+
994+
\see \ref graph_setup (how to create a graph)
995+
\see \ref graph_compress (how to compress a graph after adding/removing edges)
996+
\see \ref graph_get_csr_pointers (how to retrieve a CSR representation of a graph)
997+
\see \link AddNodeAttributesFloat \endlink (how to add float node attributes)
998+
\see \link GetNodeAttributesFloat \endlink (how to get float node attributes)
999+
\see \ref graph_teardown (how to destroy a graph)
1000+
1001+
Begin by reviewing the example at \ref graph_setup to create a graph.<br>
1002+
1003+
\snippet tests\src\spatialstructures_C_cinterface.cpp snippet_spatialstructuresC_GetNodeAttributesByIDFloat
1004+
1005+
Finally, when you are finished with the graph,<br>
1006+
it must be destroyed. (\ref graph_teardown)
1007+
*/
1008+
C_INTERFACE GetNodeAttributesByIDFloat(
1009+
const HF::SpatialStructures::Graph* g,
1010+
const int* ids,
1011+
const char* attribute,
1012+
int num_nodes,
1013+
float* out_scores,
1014+
int* out_score_size
1015+
);
1016+
1017+
/*!
1018+
\brief Check whether or not an attribute is stored with float values in a graph.
1019+
\param g The pointer of the graph to check
1020+
\param attribute The attribute to check
1021+
1022+
\returns 1 if the attribute exists in the graph and contains only float values.
1023+
0 otherwise.
1024+
*/
1025+
C_INTERFACE IsFloatAttribute(
1026+
const HF::SpatialStructures::Graph* g,
1027+
const char* attribute
1028+
);
8741029

8751030
/*!
8761031
\brief Free the memory of every (char *) in scores_to_delete.

0 commit comments

Comments
 (0)