/* * Return the number of nodes in the hashtable. */ unsigned long lttng_ht_get_count(struct lttng_ht *ht) { long scb, sca; unsigned long count; assert(ht); assert(ht->ht); /* RCU read lock protects from ABA and allows RCU traversal. */ rcu_read_lock(); cds_lfht_count_nodes(ht->ht, &scb, &count, &sca); rcu_read_unlock(); return count; }
UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, UA_Node *node, const UA_Node **inserted) { size_t nodesize; /* Copy the node into the entry. Then reset the original node. It shall no longer be used. */ switch(node->nodeClass) { case UA_NODECLASS_OBJECT: nodesize = sizeof(UA_ObjectNode); break; case UA_NODECLASS_VARIABLE: nodesize = sizeof(UA_VariableNode); break; case UA_NODECLASS_METHOD: nodesize = sizeof(UA_MethodNode); break; case UA_NODECLASS_OBJECTTYPE: nodesize = sizeof(UA_ObjectTypeNode); break; case UA_NODECLASS_VARIABLETYPE: nodesize = sizeof(UA_VariableTypeNode); break; case UA_NODECLASS_REFERENCETYPE: nodesize = sizeof(UA_ReferenceTypeNode); break; case UA_NODECLASS_DATATYPE: nodesize = sizeof(UA_DataTypeNode); break; case UA_NODECLASS_VIEW: nodesize = sizeof(UA_ViewNode); break; default: return UA_STATUSCODE_BADINTERNALERROR; } struct nodeEntry *entry; if(!(entry = UA_malloc(sizeof(struct nodeEntry) - sizeof(UA_Node) + nodesize))) return UA_STATUSCODE_BADOUTOFMEMORY; memcpy((void*)&entry->node, node, nodesize); cds_lfht_node_init(&entry->htn); entry->refcount = ALIVE_BIT; if(inserted) // increase the counter before adding the node entry->refcount++; struct cds_lfht_node *result; //FIXME: a bit dirty workaround of preserving namespace //namespace index is assumed to be valid UA_NodeId tempNodeid; UA_NodeId_copy(&node->nodeId, &tempNodeid); tempNodeid.namespaceIndex = 0; if(!UA_NodeId_isNull(&tempNodeid)) { hash_t h = hash(&node->nodeId); rcu_read_lock(); result = cds_lfht_add_unique(ns->ht, h, compare, &entry->node.nodeId, &entry->htn); rcu_read_unlock(); /* If the nodeid exists already */ if(result != &entry->htn) { UA_free(entry); return UA_STATUSCODE_BADNODEIDEXISTS; } } else { /* create a unique nodeid */ ((UA_Node *)&entry->node)->nodeId.identifierType = UA_NODEIDTYPE_NUMERIC; if(((UA_Node *)&entry->node)->nodeId.namespaceIndex == 0) //original request for ns=0 should yield ns=1 ((UA_Node *)&entry->node)->nodeId.namespaceIndex = 1; if(((UA_Node *)&entry->node)->nodeClass==UA_NODECLASS_VARIABLE){ //set namespaceIndex in browseName in case id is generated ((UA_VariableNode*)&entry->node)->browseName.namespaceIndex=((UA_Node *)&entry->node)->nodeId.namespaceIndex; } unsigned long identifier; long before, after; rcu_read_lock(); cds_lfht_count_nodes(ns->ht, &before, &identifier, &after); // current amount of nodes stored identifier++; ((UA_Node *)&entry->node)->nodeId.identifier.numeric = identifier; while(UA_TRUE) { hash_t nhash = hash(&entry->node.nodeId); result = cds_lfht_add_unique(ns->ht, nhash, compare, &entry->node.nodeId, &entry->htn); if(result == &entry->htn) break; ((UA_Node *)&entry->node)->nodeId.identifier.numeric += (identifier * 2654435761); } rcu_read_unlock(); } UA_NodeId_deleteMembers(&tempNodeid); UA_free(node); if(inserted) *inserted = &entry->node; return UA_STATUSCODE_GOOD; }