C语言读取redis lrange 实现


/*
 * Get the range of items in a list from 'start' to 'end'.
 * This function allocates memory. An array of pointers and all the strings pointed to by it
 * are dynamically allocated. redis_free_array_results() has to be called to free this
 * allocated memory by the caller.
 * */

int redis_list_get_range(char *key, int start, int end, char ***items, int *items_count) {
    /*
     *  The Redis protocol is elegantly simple. The following is a response for an array
     *  that has 3 elements (strings):
     *  Example response:
     *  *3\r\n$5\r\nHello\r\n$6\r\nLovely\r\n\$5\r\nWorld\r\n
     *
     *  What it means:
     *  *3      -> Array with 3 items
     *  $5      -> string with 5 characters
     *  Hello   -> actual string
     *  $6      -> string with 6 characters
     *  Lovely  -> actual string
     *  $5      -> string with 5 characters
     *  World   -> actual string
     *
     *  A '\r\n' (carriage return + line feed) sequence is used as the delimiter.
     *  Now, you should be able to understand why we're doing what we're doing in this function
     * */

    char cmd_buf[1024]="", start_str[16], end_str[16];
    sprintf(start_str, "%d", start);
    sprintf(end_str, "%d", end);
    sprintf(cmd_buf, "*4\r\n$6\r\nLRANGE\r\n$%ld\r\n%s\r\n$%ld\r\n%s\r\n$%ld\r\n%s\r\n", strlen(key), key, strlen(start_str), start_str, strlen(end_str), end_str);
    write(redis_socket_fd, cmd_buf, strlen(cmd_buf));

    /* Find out the length of the array */
    char ch;
    read(redis_socket_fd, &ch, 1);
    if (ch != '*')
        return -1;

    int returned_items = 0;
    while (1) {
        read(redis_socket_fd, &ch, 1);
        if (ch == '\r') {
            /* Read the next '\n' character */
            read(redis_socket_fd, &ch, 1);
            break;
        }
        returned_items = (returned_items * 10) + (ch - '0');
    }
    /* Allocate the array that will hold a pointer each for
     * every element in the returned list */
    *items_count = returned_items;
    char **items_holder = malloc(sizeof(char *) * returned_items);
    *items = items_holder;

    /*
     * We now know the length of the array. Let's loop that many iterations
     * and grab those strings, allocating a new chunk of memory for each one.
     * */
    for (int i = 0; i < returned_items; i++) {
        /* read the first '$' */
        read(redis_socket_fd, &ch, 1);
        int str_size = 0;
        while (1) {
            read(redis_socket_fd, &ch, 1);
            if (ch == '\r') {
                /* Read the next '\n' character */
                read(redis_socket_fd, &ch, 1);
                break;
            }
            str_size = (str_size * 10) + (ch - '0');
        }
        char *str = malloc(sizeof(char) * str_size + 1);
        items_holder[i] = str;
        read(redis_socket_fd, str, str_size);
        str[str_size] = '\0';
        /* Read the '\r\n' chars */
        read(redis_socket_fd, &ch, 1);
        read(redis_socket_fd, &ch, 1);
    }
}

上一篇:队列实现(Python)


下一篇:Minecraft 1.16.5模组开发(三十) 自定义成就系统(advancements)