/* * For each UINT key in arguments create or increment counter in * box.space.test space. */ int multi_inc(box_function_ctx_t *ctx, const char *args, const char *args_end) { static const char *SPACE_NAME = "test"; static const char *INDEX_NAME = "primary"; uint32_t space_id = box_space_id_by_name(SPACE_NAME, strlen(SPACE_NAME)); uint32_t index_id = box_index_id_by_name(space_id, INDEX_NAME, strlen(INDEX_NAME)); if (space_id == BOX_ID_NIL || index_id == BOX_ID_NIL) { return box_error_raise(ER_PROC_C, "Can't find index %s in space %s", INDEX_NAME, SPACE_NAME); } say_debug("space_id = %u, index_id = %u", space_id, index_id); uint32_t arg_count = mp_decode_array(&args); box_txn_begin(); for (uint32_t i = 0; i < arg_count; i++) { /* Decode next argument */ if (mp_typeof(*args) != MP_UINT) return box_error_raise(ER_PROC_C, "Expected uint keys"); uint32_t key = mp_decode_uint(&args); (void) key; /* Prepare MsgPack key for search */ char key_buf[16]; char *key_end = key_buf; key_end = mp_encode_array(key_end, 1); key_end = mp_encode_uint(key_end, key); assert(key_end < key_buf + sizeof(key_buf)); /* Get current value from space */ uint64_t counter = 0; box_tuple_t *tuple; if (box_index_get(space_id, index_id, key_buf, key_end, &tuple) != 0) { return -1; /* error */ } else if (tuple != NULL) { const char *field = box_tuple_field(tuple, 1); if (field == NULL || mp_typeof(*field) != MP_UINT) return box_error_raise(ER_PROC_LUA, "Invalid tuple"); counter = mp_decode_uint(&field) + 1; } /* Replace value */ char tuple_buf[16]; char *tuple_end = tuple_buf; tuple_end = mp_encode_array(tuple_end, 2); tuple_end = mp_encode_uint(tuple_end, key); /* key */ tuple_end = mp_encode_uint(tuple_end, counter); /* counter */ assert(tuple_end <= tuple_buf + sizeof(tuple_buf)); if (box_replace(space_id, tuple_buf, tuple_end, NULL) != 0) return -1; } box_txn_commit(); return 0; }
memcached_binary_header_dump(struct memcached_hdr *hdr) { if (!hdr) return; say_debug("memcached package"); say_debug("magic: 0x%" PRIX8, hdr->magic); say_debug("cmd: 0x%" PRIX8, hdr->cmd); if (hdr->key_len > 0) say_debug("key_len: %" PRIu16, mp_bswap_u16(hdr->key_len)); if (hdr->ext_len > 0) say_debug("ext_len: %" PRIu8, hdr->ext_len); say_debug("tot_len: %" PRIu32, mp_bswap_u32(hdr->tot_len)); say_debug("opaque: 0x%" PRIX32, mp_bswap_u32(hdr->opaque)); say_debug("cas: %" PRIu64, mp_bswap_u64(hdr->cas)); }
/** open file. The same as fopen but receives additional open (2) flags */ FILE * fiob_open(const char *path, const char *mode) { int omode = 0666; int flags = 0; int save_errno; int fd = -1; FILE *file = NULL; #if defined (FIOB_DIRECT) struct fiob *f = NULL; #endif /* defined(FIOB_DIRECT) */ int um = umask(0722); umask(um); omode &= ~um; if (strchr(mode, 'r')) { if (strchr(mode, '+')) flags |= O_RDWR; else flags |= O_RDONLY; } else if (strchr(mode, 'w')) { flags |= O_TRUNC | O_CREAT; if (strchr(mode, '+')) flags |= O_RDWR; else flags |= O_WRONLY; } else if (strchr(mode, 'a')) { flags |= O_CREAT | O_APPEND; if (strchr(mode, '+')) flags |= O_RDWR; else flags |= O_WRONLY; } else { errno = EINVAL; return NULL; } /* O_EXCL */ #ifdef O_EXCL if (strchr(mode, 'x')) flags |= O_EXCL; #endif /* O_SYNC */ if (strchr(mode, 's')) { flags |= WAL_SYNC_FLAG; } fd = open(path, flags, omode); if (fd < 0) goto error; #if defined(FIOB_DIRECT) if (strchr(mode, 'd') == NULL) goto fdopen; /* Try to enable O_DIRECT */ flags = fcntl(fd, F_GETFL); if (flags != -1 && fcntl(fd, F_SETFL, flags | O_DIRECT) != -1) { say_debug("using O_DIRECT for %s", path); } else { #if defined(NDEBUG) /* Don't use opencookie in release mode without O_DIRECT */ goto fdopen; #endif /* defined(NDEBUG) */ } f = (struct fiob *)calloc(1, sizeof(struct fiob)); if (!f) goto error; f->fd = fd; f->bsize = FIOB_BSIZE; if (posix_memalign(&f->buf, FIOB_ALIGN, f->bsize)) goto error; /* for valgrind */ memset(f->buf, 0, f->bsize); f->path = strdup(path); if (!f->path) goto error; f->io.read = fiob_read; f->io.write = fiob_write; f->io.seek = fiob_seek; f->io.close = fiob_close; #ifdef HAVE_FUNOPEN file = funopen(f, f->io.read, f->io.write, f->io.seek, f->io.close); #else file = fopencookie(f, mode, f->io); #endif if (!file) goto error; #ifdef TARGET_OS_LINUX file->_fileno = f->fd; #else file->_file = f->fd; #endif return file; fdopen: #endif /* defined(FIOB_DIRECT) */ /* Fallback to libc implementation */ file = fdopen(fd, mode); if (!file) goto error; return file; error: save_errno = errno; say_syserror("Can't open '%s'", path); if (fd >= 0) close(fd); #if defined(FIOB_DIRECT) if (f) { free(f->buf); free(f->path); free(f); } #endif /* FIOB_DIRECT */ errno = save_errno; return NULL; }