int l_sipmemcache_multi_get(lua_State *L) { struct sipmemcache *o; const char *key; size_t key_len; int i, n; o = luaL_checkudata(L, 1, "siplua.memcache"); if (o->finalized || !o->mc) { lua_pushnil(L); return 1; } n = lua_gettop(L); lua_newtable(L); if (n < 2) return 1; o->req = mc_req_new(); o->res = pkg_malloc((n - 1) * sizeof(struct memcache_res *)); for (i = 0; i < n - 1; ++i) { key = luaL_checklstring(L, i + 2, &key_len); o->res[i] = mc_req_add(o->req, (char *)key, key_len); /* o->res[i]->size = 1024; */ /* o->res[i]->val = malloc(o->res[i]->size); */ /* mc_res_free_on_delete(o->res[i], 1); */ } mc_get(o->mc, o->req); for (i = 0; i < n - 1; ++i) { if (o->res[i]->bytes) { lua_pushvalue(L, i + 2); lua_pushlstring(L, o->res[i]->val, o->res[i]->bytes); lua_rawset(L, -3); } /* mc_res_free(o->req, o->res[i]); */ } pkg_free(o->res); o->res = NULL; mc_req_free(o->req); o->req = NULL; return 1; }
int main(int argc, char *argv[]) { struct memcache *mc = NULL; u_int32_t num_tests = 0, valsize = 0; u_int32_t i; struct timeval t1, t2; const char *key; char *tests = NULL; char *val; u_int32_t keylen; double addtime, deltime; const char fmt[] = "%s\t%f\t%f\t%f\n"; struct memcache_req *req; struct memcache_res *res; if (argc > 1) num_tests = strtol(argv[1], NULL, 10); if (num_tests == 0) num_tests = 10; if (argc > 2) valsize = strtol(argv[2], NULL, 10); if (argc > 3) tests = strdup(argv[3]); if (tests == NULL) tests = strdup("adgs"); if (valsize == 0) valsize = 50; val = (char *)malloc(valsize + 1); memset(val, 69, valsize); val[valsize] = '\0'; /* XXX I should add a min/max time value for each request */ printf("Value size:\t%d\n", valsize); printf("Num tests:\t%d\n", num_tests); printf("Test\tOps per second\tTotal Time\tTime per Request\n"); key = "bench_key"; keylen = strlen(key); mc = mc_new(); if (mc == NULL) err(EX_OSERR, "Unable to allocate a new memcache object"); mc_err_filter_del(MCM_ERR_LVL_INFO); mc_err_filter_del(MCM_ERR_LVL_NOTICE); mc_server_add4(mc, "localhost:11211"); /* Establish a connection */ mc_set(mc, key, keylen, val, valsize, 0, 0); /* BEGIN set test, if specified */ if (strchr(tests, (int)'s') != NULL) { if (gettimeofday(&t1, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); for (i = 0; i < num_tests; i++) { mc_set(mc, key, keylen, val, valsize, 0, 0); } if (gettimeofday(&t2, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); /* END set test */ printf(fmt, "set", num_tests / tt(&t1, &t2), tt(&t1, &t2), tt(&t1, &t2) / num_tests); } if (strchr(tests, (int)'g') != NULL) { /* BEGIN get request */ req = mc_req_new(); res = mc_req_add(req, key, keylen); res->size = valsize; res->val = malloc(res->size); mc_res_free_on_delete(res, 1); if (gettimeofday(&t1, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); for (i = 0; i < num_tests; i++) { mc_get(mc, req); } if (gettimeofday(&t2, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); mc_req_free(req); /* END get test */ printf(fmt, "get", num_tests / tt(&t1, &t2), tt(&t1, &t2), tt(&t1, &t2) / num_tests); } if (strchr(tests, 'a') != NULL || strchr(tests, 'd') != NULL) { /* Run the add/delete test */ mc_delete(mc, key, keylen, 0); addtime = deltime = 0.0; for (i = 0; i < num_tests; i++) { /* BEGIN add test */ if (strchr(tests, 'a') != NULL) { if (gettimeofday(&t1, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); mc_add(mc, key, keylen, val, valsize, 0, 0); if (gettimeofday(&t2, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); addtime += tt(&t1, &t2); /* END add test */ } /* BEGIN delete test */ if (strchr(tests, 'd') != NULL) { if (gettimeofday(&t1, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); mc_delete(mc, key, keylen, 0); if (gettimeofday(&t2, NULL) != 0) err(EX_OSERR, "gettimeofday(2)"); deltime += tt(&t1, &t2); /* END delete test */ } } if (strchr(tests, 'a') != NULL) printf(fmt, "add", num_tests / addtime, addtime, addtime / num_tests); if (strchr(tests, 'd') != NULL) printf(fmt, "delete", num_tests / deltime, deltime, deltime / num_tests); } free(tests); free(val); mc_free(mc); return EX_OK; }
int cw_db_get(const char *family, const char *keys, char *value, int valuelen) { char *sql; char *zErr = 0; int res = 0; struct cw_db_data result; sqlite3 *db; int retry=0; if (!family || cw_strlen_zero(family)) { family = "_undef_"; } #ifdef HAVE_MEMCACHE int fullkeylen; char fullkey[256] = ""; fullkeylen = snprintf(fullkey, sizeof(fullkey), "/%s/%s", family, keys); if ( memcached_data.active ) { if ( memcached_data.has_error ) database_cache_retry_connect(); //cw_log(LOG_ERROR,"MEMCACHE GET Family %s : %s \n", family, keys); memset(value,0,valuelen); struct memcache_req *mreq; struct memcache_res *mres; mreq = mc_req_new(); mres = mc_req_add(mreq, fullkey, fullkeylen); mc_res_free_on_delete(mres, 0); mres->size = valuelen; mres->val = value; mc_get(memcached_data.mc, mreq); if ( mres->bytes ) { // FOUND //cw_log(LOG_WARNING,"MEMCACHE GET FOUND for %s: (%d) %s\n", fullkey, mres->size,(char *) mres->val); //value = mres->val; mc_req_free(mreq); return 0; } mc_req_free(mreq); } #endif sanity_check(); if (!(db = sqlite_open_db(globals.dbfile))) { return -1; } result.data = value; result.datalen = valuelen; result.rownum = 0; retry_1: if ((sql = sqlite3_mprintf("select value from %q where family='%q' and keys='%q'", globals.tablename, family, keys))) { cw_log(LOG_DEBUG, "SQL [%s]\n", sql); res = sqlite3_exec(db, sql, get_callback, &result, &zErr ); if (zErr) { if (retry >= SQL_MAX_RETRIES) { cw_log(LOG_ERROR, "SQL ERR Query: [%s] Error: [%s] Retries: %d Max: %d\n", sql, zErr, retry, SQL_MAX_RETRIES); sqlite3_free(zErr); } else { cw_log(LOG_DEBUG, "SQL ERR Query: %s Error: [%s] Retries %d\n", sql, zErr, ++retry); sqlite3_free(zErr); usleep(SQL_RETRY_USEC); goto retry_1; } res = -1; } else { if (result.rownum) res = 0; else res = -1; } } else { cw_log(LOG_ERROR, "Memory Error!\n"); res = -1; /* Return an error */ } if (sql) { sqlite3_free(sql); sql = NULL; } sqlite3_close(db); #if defined(HAVE_MEMCACHE) // We got a value out of the cache. // Store it back to the cache to improve performance. if ( !res && memcached_data.active ) { if ( memcached_data.has_error ) database_cache_retry_connect(); //cw_log(LOG_ERROR,"DB GET STANDARD RETURNING AND CACHING %s\n", value); mc_set(memcached_data.mc, fullkey, fullkeylen, value, (size_t)MCM_CSTRLEN(value), db_cache_lifetime, 0); } #endif return res; }