Пример #1
0
static void * critbit_delete_inplace(critbit_root *root, const char *key, int keylen) {
    if(!root->head) return NULL;

    const uint8_t *bytes = (void *)key;
    uint8_t *p = root->head;
    void **wherep = &root->head, **whereq = 0;
    critbit_node *q = NULL;
    int dir = 0;

    while(IS_INTERNAL(p)) {
        whereq = wherep;
        q = TO_NODE(p);
        dir = get_direction(q, bytes, keylen);
        wherep = q->child + dir;
        p = *wherep;
    }

    if(strcmp(key, (const char *)p) != 0) {
        return NULL;
    }

    if(!whereq) {
        root->head = NULL;
        return p;
    }

    *whereq = q->child[1 - dir];
    __sync_synchronize();
    return FROM_NODE(q);
}
Пример #2
0
int critbit_delete(critbit_root *root, const char *key) {
    const size_t len = strlen(key);

    // begin critical section
    pthread_mutex_lock(&root->wlock);

    void * p = critbit_delete_inplace(root, key, len);

    pthread_rwlock_t *lock = root->cur_rwlock;
    pthread_rwlock_t *newlock = root->prev_rwlock;

    // swap two locks
    if(!__sync_val_compare_and_swap(&root->cur_rwlock, lock, newlock)) {
        printf("!!!\n");
    }
    if(!__sync_val_compare_and_swap(&root->prev_rwlock, newlock, lock)) {
        printf("!!!\n");
    }

    // wait until all readers are out
    pthread_rwlock_wrlock(lock);
    pthread_rwlock_unlock(lock);

    // end critical section
    pthread_mutex_unlock(&root->wlock);

    if(!p)
        return 1;

    if(!IS_INTERNAL(p)) {
        free_string(p);
    } else {
        critbit_node *node = TO_NODE(p);
        if(!IS_INTERNAL(node->child[0]) && strcmp(key, (const char *)node->child[0]) == 0) {
            free_string(node->child[0]);
            free_node(root, node);
        } else {
            free_string(node->child[1]);
            free_node(root, node);
        }
    }

    return 0;
}
Пример #3
0
static void clear_node(void *p) {
    if(IS_INTERNAL(p)) {
        // Internal node
        critbit_node *node = TO_NODE(p);
        clear_node(node->child[0]);
        clear_node(node->child[1]);
        free(node);
    } else {
        free_string(p);
    }
}
Пример #4
0
const critbit__extnode_t *critbit__lookup(const critbit__node_t *n,
        const void            *key,
        size_t                 keylen)
{
    const unsigned char *ukey    = key;
    const unsigned char *ukeyend = ukey + keylen;
    int                  dir;

    for (; IS_INTERNAL(n); n = n->child[dir])
        dir = GET_DIR(ukey, ukeyend, n->byte, n->otherbits);

    return FROM_STORE(n);
}
Пример #5
0
/* {{{ proto AMQPExchange::setFlags(long bitmask)
Set the exchange parameters */
static PHP_METHOD(amqp_exchange_class, setFlags)
{
	PHP5to7_param_long_type_t flagBitmask;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &flagBitmask) == FAILURE) {
		return;
	}

	/* Set the flags based on the bitmask we were given */
	flagBitmask = flagBitmask ? flagBitmask & PHP_AMQP_EXCHANGE_FLAGS : flagBitmask;

	zend_update_property_bool(this_ce, getThis(), ZEND_STRL("passive"), IS_PASSIVE(flagBitmask) TSRMLS_CC);
	zend_update_property_bool(this_ce, getThis(), ZEND_STRL("durable"), IS_DURABLE(flagBitmask) TSRMLS_CC);
	zend_update_property_bool(this_ce, getThis(), ZEND_STRL("auto_delete"), IS_AUTODELETE(flagBitmask) TSRMLS_CC);
	zend_update_property_bool(this_ce, getThis(), ZEND_STRL("internal"), IS_INTERNAL(flagBitmask) TSRMLS_CC);
}
Пример #6
0
static int critbit_insert_inplace(critbit_root *root,
        const char *key, int keylen, const void* value) {
    const uint8_t *bytes = (void *)key;

    uint8_t *p = root->head;
    if(!p) {
        p = alloc_string(key, keylen, value);
        if(!p)
            return 1;

        root->head = p;
        return 0;
    }

    p = find_nearest(root->head, bytes, keylen);

    uint32_t newbyte;
    uint8_t newotherbits;
    for(newbyte = 0; newbyte < keylen; ++newbyte) {
        if(p[newbyte] != bytes[newbyte]) {
            newotherbits = p[newbyte] ^ bytes[newbyte];
            goto found;
        }
    }
    if(p[newbyte]) {
        newotherbits = p[newbyte];
        goto found;
    }
    return 1;

found:
    while(newotherbits & (newotherbits - 1)) {
        newotherbits &= newotherbits - 1;
    }
    newotherbits ^= 0xFF;
    uint8_t c = p[newbyte];
    int newdirection = (1 + (newotherbits | c)) >> 8;

    struct critbit_node *node = alloc_aligned(sizeof(struct critbit_node));
    if(!node)
        return 1;

    char *x = alloc_string(key, keylen, value);
    if(!x) {
        free(node);
        return 1;
    }

    node->byte = newbyte;
    node->otherbits = newotherbits;
    node->child[1 - newdirection] = x;

    void **wherep = &root->head;
    for(;;) {
        uint8_t *p = *wherep;
        if(!IS_INTERNAL(p))
            break;

        struct critbit_node *q = TO_NODE(p);
        if(q->byte > newbyte)
            break;
        if(q->byte == newbyte && q->otherbits > newotherbits)
            break;

        wherep = q->child + get_direction(q, bytes, keylen);
    }
    node->child[newdirection] = *wherep;
    __sync_synchronize();
    *wherep = FROM_NODE(node);
    __sync_synchronize();

    return 0;
}