コード例 #1
0
ファイル: object.c プロジェクト: russross/envoy
u32 object_write(Worker *worker, u64 oid, u32 mtime, u64 offset,
        u32 count, u8 *data, void *raw)
{
    struct object_write_env env = {
        .worker = worker,
        .oid = oid,
        .mtime = mtime,
        .offset = offset,
        .count = count,
        .data = data
    };
    Transaction *trans = trans_new(storage_servers[0], NULL, message_new());
    struct Rswrite *res;

    assert(raw != NULL);

    trans->out->raw = raw;
    trans->out->tag = ALLOCTAG;
    trans->out->id = TSWRITE;
    set_tswrite(trans->out, mtime, offset, count, data, oid);

    send_request_to_all(trans, (void (*)(void *)) object_write_cb, &env);

    res = &trans->in->msg.rswrite;
    return res->count;
}
コード例 #2
0
ファイル: object.c プロジェクト: russross/envoy
u64 object_reserve_oid(Worker *worker) {
    assert(storage_server_count > 0);

    /* is someone else in the process of requesting new oids? */
    while (object_reserve_wait != NULL)
        cond_wait(object_reserve_wait);

    /* do we need to request a fresh batch of oids? */
    if (object_reserve_remaining == 0) {
        /* the first storage server is considered the master */
        Transaction *trans = trans_new(storage_servers[0], NULL, message_new());
        struct Rsreserve *res;
        pthread_cond_t *wait;

        trans->out->tag = ALLOCTAG;
        trans->out->id = TSRESERVE;

        wait = object_reserve_wait = cond_new();
        send_request(trans);
        object_reserve_wait = NULL;
        cond_broadcast(wait);

        res = &trans->in->msg.rsreserve;

        object_reserve_next = res->firstoid;
        object_reserve_remaining = res->count;
    }

    object_reserve_remaining--;
    return object_reserve_next++;
}
コード例 #3
0
ファイル: object.c プロジェクト: russross/envoy
void object_delete(Worker *worker, u64 oid) {
    struct object_delete_env env = {
        .worker = worker,
        .oid = oid
    };
    Transaction *trans = trans_new(storage_servers[0], NULL, message_new());

    trans->out->tag = ALLOCTAG;
    trans->out->id = TSDELETE;
    set_tsdelete(trans->out, oid);

    send_request_to_all(trans, (void (*)(void *)) object_delete_cb, &env);
}
コード例 #4
0
ファイル: object.c プロジェクト: russross/envoy
void object_wstat(Worker *worker, u64 oid, struct p9stat *info) {
    struct object_wstat_env env = {
        .worker = worker,
        .oid = oid,
        .info = info
    };
    Transaction *trans = trans_new(storage_servers[0], NULL, message_new());

    trans->out->tag = ALLOCTAG;
    trans->out->id = TSWSTAT;
    set_tswstat(trans->out, oid, info);

    send_request_to_all(trans, (void (*)(void *)) object_wstat_cb, &env);
}
コード例 #5
0
ファイル: object.c プロジェクト: russross/envoy
struct p9stat *object_stat(Worker *worker, u64 oid, char *filename) {
    int i;
    Transaction *trans;
    struct Rsstat *res;
    struct p9stat *info;

    /* handle it from the cache if it exists */
    if (object_cache_isvalid(oid)) {
        info = disk_stat(worker, oid);
        info->name = filename;
        return info;
    }

    i = randInt(storage_server_count);
    trans = trans_new(storage_servers[i], NULL, message_new());

    trans->out->tag = ALLOCTAG;
    trans->out->id = TSSTAT;
    set_tsstat(trans->out, oid);

    /* send the request to one randomly chosen storage server */
    send_request(trans);

    assert(trans->in != NULL && trans->in->id == RSSTAT);
    res = &trans->in->msg.rsstat;

    /* insert the filename supplied by the caller */
    res->stat->name = filename;

    /* check if we have a cache entry with matching stats */
    if (objectroot != NULL && (info = disk_stat(worker, oid)) != NULL) {
        info->name = filename;
        info->atime = res->stat->atime;

        /* if it's up-to-date, note it as a valid entry */
        if (!p9stat_cmp(info, res->stat))
            object_cache_validate(oid);
    }

    return res->stat;
}
コード例 #6
0
ファイル: object.c プロジェクト: russross/envoy
void *object_read(Worker *worker, u64 oid, u32 atime, u64 offset, u32 count,
        u32 *bytesread, u8 **data)
{
    int i;
    Transaction *trans;
    struct Rsread *res;
    void *result;

    /* read from the cache if it exists */
    if (object_cache_isvalid(oid)) {
        u8 *raw = raw_new();
        int len;

        *data = raw + RSREAD_DATA_OFFSET;
        len = disk_read(worker, oid, atime, offset, count, *data);
        assert(len > 0);
        *bytesread = len;

        return raw;
    }

    i = randInt(storage_server_count);
    trans = trans_new(storage_servers[i], NULL, message_new());

    trans->out->tag = ALLOCTAG;
    trans->out->id = TSREAD;
    set_tsread(trans->out, oid, atime, offset, count);

    /* send the request to one randomly chosen storage server */
    send_request(trans);

    assert(trans->in != NULL && trans->in->id == RSREAD);
    res = &trans->in->msg.rsread;

    *bytesread = res->count;
    *data = res->data;
    result = trans->in->raw;
    trans->in->raw = NULL;
    return result;
}
コード例 #7
0
ファイル: object.c プロジェクト: russross/envoy
static void send_request_to_all(Transaction *trans,
        void (*callback)(void *), void *env)
{
    List *requests = cons(trans, NULL);
    int i;

    for (i = 1; i < storage_server_count; i++) {
        Transaction *newtrans =
            trans_new(storage_servers[i], NULL, message_new());

        /* copy the whole mess over */
        memcpy(newtrans->out, trans->out, sizeof(Message));

        /* for tswrite, we need to copy the data payload as well */
        if (newtrans->out->raw != NULL) {
            struct Tswrite *req = &newtrans->out->msg.tswrite;

            assert(trans->out->id == TSWRITE);

            newtrans->out->raw = raw_new();
            req->data = newtrans->out->raw + TWRITE_DATA_OFFSET;
            memcpy(req->data, trans->out->raw + TWRITE_DATA_OFFSET, req->count);
        }

        requests = cons(newtrans, requests);
    }

    /* send request to all storage servers and wait for all to respond */
    send_requests(requests, callback, env);

    /* make sure they all succeeded */
    while (!null(requests)) {
        trans = car(requests);
        assert(trans->in != NULL && trans->in->id == trans->out->id + 1);
        requests = cdr(requests);
    }
}
コード例 #8
0
ファイル: object.c プロジェクト: russross/envoy
struct qid object_create(Worker *worker, u64 oid, u32 mode,
        u32 ctime, char *uid, char *gid, char *extension)
{
    Transaction *trans = trans_new(storage_servers[0], NULL, message_new());
    struct Rscreate *res;
    int len;

    /* create it in the cache */
    if (objectroot != NULL) {
        len = disk_create(worker, oid, mode, ctime, uid, gid, extension);
        assert(len >= 0);
        object_cache_validate(oid);
    }

    /* create it on the storage servers */
    trans->out->tag = ALLOCTAG;
    trans->out->id = TSCREATE;
    set_tscreate(trans->out, oid, mode, ctime, uid, gid, extension);

    send_request_to_all(trans, NULL, NULL);

    res = &trans->in->msg.rscreate;
    return res->qid;
}
コード例 #9
0
ファイル: clib_test.c プロジェクト: JasonChunZheng/cantera
int main(int argc, char** argv)
{
    int ret;
    int xml_file = xml_get_XML_File("gri30.xml", 0);
    assert(xml_file > 0);

    int phase_node = xml_findID(xml_file, "gri30_mix");
    assert(phase_node > 0);

    int thermo = thermo_newFromXML(phase_node);
    assert(thermo > 0);
    int nsp = thermo_nSpecies(thermo);
    assert(nsp == 53);

    ret = thermo_setTemperature(thermo, 500);
    assert(ret == 0);
    ret = thermo_setPressure(thermo, 5 * 101325);
    assert(ret == 0);
    ret = thermo_setMoleFractionsByName(thermo, "CH4:1.0, O2:2.0, N2:7.52");
    assert(ret == 0);

    ret = thermo_equilibrate(thermo, "HP", 0, 1e-9, 50000, 1000, 0);
    assert(ret == 0);
    double T = thermo_temperature(thermo);
    assert(T > 2200 && T < 2300);

    ret = thermo_print(thermo, 1, 0);
    assert(ret == 0);

    int kin = kin_newFromXML(phase_node, thermo, 0, 0, 0, 0);
    assert(kin > 0);

    size_t nr = kin_nReactions(kin);
    assert(nr == 325 );

    ret = thermo_setTemperature(thermo, T - 200);
    assert(ret == 0);

    char buf [1000];
    double ropf[325];
    printf("\n                   Reaction           Forward ROP\n");
    kin_getFwdRatesOfProgress(kin, 325, ropf);
    size_t n; // declare this here for C89 compatibility
    for (n = 0; n < nr; n++) {
        kin_getReactionString(kin, n, 1000, buf);
        printf("%35s   %8.6e\n", buf, ropf[n]);
    }

    printf("\n  Species    Mix diff coeff\n");
    int tran = trans_new("Mix", thermo, 0);
    double dkm[53];
    trans_getMixDiffCoeffs(tran, 53, dkm);
    int k; // declare this here for C89 compatibility
    for (k = 0; k < nsp; k++) {
        thermo_getSpeciesName(thermo, k, 1000, buf);
        printf("%10s   %8.6e\n", buf, dkm[k]);
    }

    ret = thermo_setTemperature(thermo, 1050);
    assert(ret == 0);
    ret = thermo_setPressure(thermo, 5 * 101325);
    assert(ret == 0);
    ret = thermo_setMoleFractionsByName(thermo, "CH4:1.0, O2:2.0, N2:7.52");
    assert(ret == 0);

    printf("\ntime       Temperature\n");
    int reactor = reactor_new(5);
    int net = reactornet_new();
    ret = reactor_setThermoMgr(reactor, thermo);
    assert(ret == 0);
    ret = reactor_setKineticsMgr(reactor, kin);
    assert(ret == 0);
    ret = reactornet_addreactor(net, reactor);
    assert(ret == 0);

    double t = 0.0;
    while (t < 0.1 && ret == 0) {
        double T = reactor_temperature(reactor);
        t = reactornet_time(net);
        printf("%.2e   %.3f\n", t, T);
        ret = reactornet_advance(net, t + 5e-3);
        assert(ret == 0);
    }
    ct_appdelete();
    return 0;
}
コード例 #10
0
ファイル: object.c プロジェクト: russross/envoy
void object_fetch(Worker *worker, u64 oid, struct p9stat *info) {
    int res;
    u32 packetsize;
    u32 packetcount;
    u64 offset;
    int i;
    int start;
    u32 time = now();
    List **queues;
    struct object_fetch_env env;

    if (objectroot == NULL || object_cache_isvalid(oid))
        return;

    /* delete any existing entry in the cache */
    res = disk_delete(worker, oid);
    assert(res >= 0 || -res == ENOENT);

    /* create the file */
    disk_create(worker, oid, info->mode, info->mtime, info->uid,
            info->gid, info->extension);

    /* empty file? */
    if (info->length == 0 || !emptystring(info->extension)) {
        int res = disk_wstat(worker, oid, info);
        assert(res == 0);
        return;
    }

    /* stripe the reads across the storage servers */
    queues = GC_MALLOC(sizeof(List *) * storage_server_count);
    assert(queues != NULL);
    queues[0] = NULL;

    packetsize = (storage_servers[0]->maxSize / BLOCK_SIZE) * BLOCK_SIZE;
    for (i = 1; i < storage_server_count; i++) {
        int size = (storage_servers[i]->maxSize / BLOCK_SIZE) * BLOCK_SIZE;
        packetsize = min(packetsize, size);
        queues[i] = NULL;
    }
    packetcount = (info->length + (packetsize - 1)) / packetsize;

    i = 0;
    offset = 0;
    start = randInt(storage_server_count);

    /* create read requests in contiguous chunks for each server */
    while (offset < info->length) {
        u64 size = info->length - offset;
        if (size > packetsize)
            size = packetsize;
        Transaction *trans = trans_new(
                storage_servers[(i + start) % storage_server_count],
                NULL, message_new());
        trans->out->tag = ALLOCTAG;
        trans->out->id = TSREAD;
        set_tsread(trans->out, oid, time, offset, (u32) size);
        queues[i] = cons(trans, queues[i]);
        offset += size;

        /* time to switch to next server? */
        if (offset * storage_server_count > info->length * (i + 1))
            i++;
    }

    /* put the requests in sequential order */
    for (i = 0; i < storage_server_count; i++)
        queues[i] = reverse(queues[i]);

    env.file = disk_get_openfile(worker, oid);
    assert(env.file != NULL);
    env.wait = NULL;

    if (ftruncate(env.file->fd, info->length) < 0)
        assert(0);

    send_requests_streamed(queues, storage_server_count,
            (void (*)(void *, Transaction *)) object_fetch_iter, &env);

    if (disk_wstat(worker, oid, info) != 0)
        assert(0);

    object_cache_validate(oid);
}