static VAttrList VGraphEncodeAttrMethod (VPointer value, size_t *lengthp) { VGraph graph = value; VAttrList list; size_t len, nadj; int i, slong, sfloat, spriv, nnodes; VNode n; VAdjacency adj; /* Compute the file space needed for the Graph's binary data: */ len = 0; slong = VRepnPrecision (VLongRepn) / 8; sfloat = VRepnPrecision (VFloatRepn) / 8; spriv = graph->nfields * VRepnPrecision (graph->node_repn) / 8; nnodes = 0; for (i = 1; i <= graph->size; i++) { n = VGraphGetNode(graph, i); if (n == 0) continue; ++nnodes; /* Count the number of adjacencies : */ for (adj = n->base.head, nadj = 0; adj; adj = adj->next) nadj++; /* each node contains: * an index and the number of adjacencies * the private data area * the list of adjacencies * optionally reserve space for weights */ len += 2 * slong + nadj * slong + spriv; if (graph->useWeights) len += (nadj+1) * sfloat; }; *lengthp = len; assert(nnodes == graph->nnodes); /* for debugging */ graph->nnodes = nnodes; /* just to be safe for now... */ /* Temporarily prepend several attributes to the graph's list: */ if ((list = VGraphAttrList (graph)) == NULL) list = VGraphAttrList (graph) = VCreateAttrList (); VPrependAttr (list, VRepnAttr, VNumericRepnDict, VLongRepn, (VLong) graph->node_repn); VPrependAttr (list, VNNodeFieldsAttr, NULL, VLongRepn, (VLong) graph->nfields); VPrependAttr (list, VNGraphSizeAttr, NULL, VLongRepn, (VLong) graph->size); VPrependAttr (list, VNNodeWeightsAttr, NULL, VLongRepn, (VLong) graph->useWeights); return list; }
static VNode VCopyNodeDeep(VGraph graph, VNode src) { VNode dst; VAdjacency o, n; int cnt; if (src == 0) return 0; /* allocate and copy base part */ dst = VCalloc(1, VNodeSize(graph)); dst->base.hops = src->base.hops; dst->base.visited = src->base.visited; dst->base.weight = src->base.weight; dst->base.head = 0; /* copy all adjacencies */ for (o = src->base.head; o; o = o->next) { n = VMalloc(sizeof(VAdjRec)); n->id = o->id; n->weight = o->weight; n->next = dst->base.head; dst->base.head = n; }; /* copy private area */ cnt = (graph->nfields * VRepnPrecision(graph->node_repn)) / 8; memcpy(dst->data, src->data, cnt); return dst; }
VBoolean VUnpackData (VRepnKind repn, size_t nels, VPointer packed, VPackOrder packed_order, size_t *length, VPointer *unpacked, VBoolean *alloced) { VPackOrder unpacked_order; size_t unpacked_elsize = VRepnSize (repn) * CHAR_BIT; size_t packed_elsize = VRepnPrecision (repn); size_t unpacked_length = nels * VRepnSize (repn); /* If a space for the unpacked data was supplied, ensure there's enough of it: */ if (! alloced && unpacked_length > *length) { VWarning ("VUnpackData: Insufficient space for unpacked data"); return FALSE; } *length = unpacked_length; /* Determine the present machine's internal byte order: */ unpacked_order = MachineByteOrder (); /* If the desired byte order matches that of the present machine's, and the unpacked and packed data element sizes are identical, just return the packed data: */ if (unpacked_order == packed_order && unpacked_elsize == packed_elsize) { if (alloced) { *unpacked = packed; *alloced = FALSE; } else if (packed != *unpacked) memcpy (*unpacked, packed, unpacked_length); return TRUE; } /* Unpack data elements into the buffer: */ if (packed_elsize == unpacked_elsize) { /* If the packed and unpacked are the same size, do a straight copy: */ if (packed != *unpacked) memcpy (*unpacked, packed, unpacked_length); /* Swap bytes if necessary: */ if (packed_order != unpacked_order && packed_elsize > 8) SwapBytes (nels, packed_elsize / 8, (char *) *unpacked); } else if (packed_elsize == 1) { /* If the elements are VBits, this unpacks them: */ VUnpackBits (nels, packed_order, (char *) packed, (char *) *unpacked); } else /* Unpacking multi-byte integers or floats is currently not supported: */ VError ("VUnpackData: " "Unpacking %s from %d to %d bits is not supported", VRepnName (repn), packed_elsize, unpacked_elsize); return TRUE; }
int VGraphLookupNode (VGraph graph, VNode node) { int n = (graph->nfields * VRepnPrecision(graph->node_repn)) / 8; int i; for (i = 1; i <= graph->lastUsed; i++) { if (VGraphNodeIsFree(graph, i)) continue; if (memcmp(node->data, VGraphGetNode(graph, i)->data, n) == 0) return i; }; return 0; }
int VGraphResizeFields (VGraph graph, int newfields) { VNode o, n; int i; int nsize = sizeof(VNodeBaseRec) + (newfields * VRepnPrecision(graph->node_repn)) / 8; int osize = VNodeSize(graph); if (newfields <= graph->nfields) return TRUE; for (i = 1; i <= graph->lastUsed; i++) { if (VGraphNodeIsFree(graph, i)) continue; o = VGraphGetNode(graph, i); n = VCalloc(1, nsize); memcpy(n, o, osize); VGraphGetNode(graph, i) = n; VFree(o); }; graph->nfields = newfields; return TRUE; }