ngx-queue.h

libuv のソースを見ていたら、ngx_queue_* という API が出てきてびっくり。どうやら nginx から ngx-queue.h っていうリンクドリストの実装を持ってきているようだ。

include/uv-private/ngx-queue.h at master from joyent/libuv - GitHub

なかなかおもしろい。これ、いろんなところで使えそうなので手元でも試してみた。

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>

#include "ngx-queue.h"

typedef struct {
    ngx_queue_t queue;
    char* data;
} chunk_t;

chunk_t* chunk_init(const char* data, size_t len) {
    chunk_t* c = malloc(sizeof(chunk_t));
    assert(c);

    ngx_queue_init(&c->queue);

    c->data = malloc(len + 1);
    assert(c->data);
    memcpy(c->data, data, len);
    c->data[len] = '\0';

    return c;
}

void chunk_delete(chunk_t* c) {
    ngx_queue_remove(&c->queue);
    free(c->data);
    free(c);
}

int main(int argc, char** argv) {
    ngx_queue_t queue;
    chunk_t* chunk;

    ngx_queue_init(&queue);

    chunk = chunk_init("foo", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("bar", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("buz", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    while (!ngx_queue_empty(&queue)) {
        ngx_queue_t* q = ngx_queue_head(&queue);
        chunk_t* c = ngx_queue_data(q, chunk_t, queue);

        printf("data: %s\n", c->data);

        chunk_delete(c);
    }


    chunk = chunk_init("foo", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("bar", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    chunk = chunk_init("buz", 3);
    ngx_queue_insert_tail(&queue, &chunk->queue);

    while (!ngx_queue_empty(&queue)) {
        ngx_queue_t* q = ngx_queue_last(&queue);
        chunk_t* c = ngx_queue_data(q, chunk_t, queue);

        printf("data: %s\n", c->data);

        chunk_delete(c);
    }

    return 0;
}

出力は

$ ./a.out
data: foo
data: bar
data: buz
data: buz
data: bar
data: foo

これは使えるなぁ。

by typester / at 2011-11-15T17:38:00 / libuv · nginx / Comments(0)