static struct _upnode* get_node(struct upTree* ut, long long key) { struct _upnode** out = (struct _upnode**) hs_get(ut->hs, key); if(out == NULL) { struct _upnode* new_node = malloc(sizeof(struct _upnode)); new_node->i = key; new_node->up = NULL; hs_put(ut->hs, key, new_node); out = (struct _upnode**) hs_get(ut->hs, key); assert(*out != NULL); } return *out; }
int64_t hs_incr(HStore *store, char *key, int64_t value) { if (!store || !key || key[0] == '@') return 0; if (store->before > 0) return 0; pthread_mutex_t *lock = get_mutex(store, key); pthread_mutex_lock(lock); int64_t result = 0; int rlen = 0, flag = INCR_FLAG; char buf[25]; char *body = hs_get(store, key, &rlen, &flag); if (body != NULL) { if (flag != INCR_FLAG || rlen > 22) { fprintf(stderr, "try to incr %s but flag=0x%x, len=%d", key, flag, rlen); goto INCR_END; } result = strtoll(body, NULL, 10); if (result == 0 && errno == EINVAL) { fprintf(stderr, "incr %s failed: %s\n", key, buf); goto INCR_END; } } result += value; if (result < 0) result = 0; rlen = sprintf(buf, "%lld", (long long int) result); if (!hs_set(store, key, buf, rlen, INCR_FLAG, 0)) { // use timestamp later result = 0; // set failed } INCR_END: pthread_mutex_unlock(lock); if (body != NULL) free(body); return result; }
bool hs_append(HStore *store, char *key, char* value, int vlen) { if (!store || !key || key[0] == '@') return false; if (store->before > 0) return false; pthread_mutex_t *lock = get_mutex(store, key); pthread_mutex_lock(lock); int suc = false; int rlen = 0, flag = APPEND_FLAG; char *body = hs_get(store, key, &rlen, &flag); if (body != NULL && flag != APPEND_FLAG) { fprintf(stderr, "try to append %s with flag=%x\n", key, flag); goto APPEND_END; } body = realloc(body, rlen + vlen); memcpy(body + rlen, value, vlen); suc = hs_set(store, key, body, rlen + vlen, flag, 0); // TODO: use timestamp APPEND_END: if (body != NULL) free(body); pthread_mutex_unlock(lock); return suc; }