Ejemplo n.º 1
0
/* The occupancy of the table after the call will be about 50% */
static UA_StatusCode expand(UA_NodeStore *ns) {
    UA_UInt32 osize = ns->size;
    UA_UInt32 count = ns->count;
    /* Resize only when table after removal of unused elements is either too full or too empty  */
    if(count * 2 < osize && (count * 8 > osize || osize <= UA_NODESTORE_MINSIZE))
        return UA_STATUSCODE_GOOD;

    UA_NodeStoreEntry **oentries = ns->entries;
    UA_UInt32 nindex = higher_prime_index(count * 2);
    UA_UInt32 nsize = primes[nindex];
    UA_NodeStoreEntry **nentries;
    if(!(nentries = UA_calloc(nsize, sizeof(UA_NodeStoreEntry*))))
        return UA_STATUSCODE_BADOUTOFMEMORY;

    ns->entries = nentries;
    ns->size = nsize;
    ns->sizePrimeIndex = nindex;

    /* recompute the position of every entry and insert the pointer */
    for(size_t i = 0, j = 0; i < osize && j < count; i++) {
        if(!oentries[i])
            continue;
        UA_NodeStoreEntry **e;
        containsNodeId(ns, &oentries[i]->node.nodeId, &e);  /* We know this returns an empty entry here */
        *e = oentries[i];
        j++;
    }

    UA_free(oentries);
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 2
0
UA_StatusCode UA_NodeStore_remove(UA_NodeStore *ns, const UA_NodeId *nodeid) {
    UA_NodeStoreEntry *slot;
    if(!containsNodeId(ns, nodeid, &slot))
        return UA_STATUSCODE_BADNODEIDUNKNOWN;
    deleteEntry(slot);
    ns->count--;
    /* Downsize the hashmap if it is very empty */
    if(ns->count * 8 < ns->size && ns->size > 32)
        expand(ns); // this can fail. we just continue with the bigger hashmap.
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 3
0
UA_StatusCode
UA_NodeStore_replace(UA_NodeStore *ns, UA_Node *oldNode,
                     UA_Node *node, UA_Node **inserted) {
    UA_NodeStoreEntry *slot;
    if(!containsNodeId(ns, &node->nodeId, &slot))
        return UA_STATUSCODE_BADNODEIDUNKNOWN;
    /* that is not the node you are looking for */
    if(&slot->node.node != oldNode)
        return UA_STATUSCODE_BADINTERNALERROR;
    deleteEntry(slot);
    fillEntry(slot, node);
    if(inserted)
        *inserted = &slot->node.node;
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 4
0
UA_StatusCode UA_NodeStore_insert(UA_NodeStore *ns, UA_Node *node, UA_Node **inserted) {
    if(ns->size * 3 <= ns->count * 4) {
        if(expand(ns) != UA_STATUSCODE_GOOD)
            return UA_STATUSCODE_BADINTERNALERROR;
    }

    UA_NodeStoreEntry *entry;
    UA_NodeId tempNodeid;
    tempNodeid = node->nodeId;
    tempNodeid.namespaceIndex = 0;
    if(UA_NodeId_isNull(&tempNodeid)) {
        /* find a free nodeid */
        if(node->nodeId.namespaceIndex == 0) //original request for ns=0 should yield ns=1
            node->nodeId.namespaceIndex = 1;
        UA_Int32 identifier = ns->count+1; // start value
        UA_Int32 size = ns->size;
        hash_t increase = mod2(identifier, size);
        while(UA_TRUE) {
            node->nodeId.identifier.numeric = identifier;
            if(!containsNodeId(ns, &node->nodeId, &entry))
                break;
            identifier += increase;
            if(identifier >= size)
                identifier -= size;
        }
    } else {
        if(containsNodeId(ns, &node->nodeId, &entry))
            return UA_STATUSCODE_BADNODEIDEXISTS;
    }

    fillEntry(entry, node);
    ns->count++;
    if(inserted)
        *inserted = &entry->node.node;
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 5
0
UA_Node * UA_NodeStore_get(const UA_NodeStore *ns, const UA_NodeId *nodeid) {
    UA_NodeStoreEntry *slot;
    if(!containsNodeId(ns, nodeid, &slot))
        return NULL;
    return &slot->node.node;
}