예제 #1
0
파일: db-kyoto.c 프로젝트: Solertis/duc
void *db_get(struct db *db, const void *key, size_t key_len, size_t *val_len)
{
	size_t vall;
	void *val = kcdbget(db->kdb, key, key_len, &vall);
	*val_len = vall;
	return val;
}
예제 #2
0
파일: getVal.c 프로젝트: matgou/kmaild
/* main routine */
int
main (int argc, char **argv)
{
  KCDB *db;
  char *vbuf;
  size_t vsiz;
  int retour = 1;
  db = kcdbnew ();

  if (argc != 3)
    {
      fprintf (stderr, "Usage getVal DB_FILE KEY\n");
      return 100;
    }

  /* open the database */
  if (!kcdbopen (db, argv[1], KCOWRITER | KCOCREATE))
    {
      fprintf (stderr, "open error: %s\n", kcecodename (kcdbecode (db)));
      return 100;
    }

  vbuf = kcdbget (db, argv[2], strlen (argv[2]), &vsiz);
  if (vbuf)
    {
      printf ("%s\n", vbuf);
      kcfree (vbuf);
      retour = 0;
    }
  /* delete the database object */
  kcdbdel (db);

  return retour;
}
/* get_genid
 * Looks up the host's genid in the host->genid database
 */
static int
get_genid(char *host)
{
  KCDB *db;
  char *vbuf;
  size_t vsiz;
  int answer = 0;
  int host_size;

  /* create the database object */
  db = kcdbnew();

  /* open the database */
  if (!kcdbopen(db, genid_kyoto_db, KCOREADER | KCONOLOCK)) {
    TSDebug(PLUGIN_NAME, "could not open the genid database %s", genid_kyoto_db);
    TSError("[%s] could not open the genid database %s: %s", PLUGIN_NAME, genid_kyoto_db, strerror(errno));
    return 0;
  }

  vbuf = kcdbget(db, host, strlen(host), &vsiz);

  if (vbuf) {
    TSDebug(PLUGIN_NAME, "kcdbget(%s) = %s", host, vbuf);
    answer = (int)strtol(vbuf, NULL, 10);
    kcfree(vbuf);
  } else {
    host_size = strlen(host);
    TSDebug(PLUGIN_NAME, "kcdbget(%s) - no record found, len(%d)", host, host_size);
    answer = 0;
  }

  kcdbclose(db);
  return answer;
}
예제 #4
0
파일: getValt.c 프로젝트: matgou/kmaild
/* main routine */
int
main (int argc, char **argv)
{
  KCDB *db;
  char *vbuf;
  size_t vsiz;
  /* Variable for time mesure */
  clock_t start, finish;
  int duration;
  start = clock ();

  db = kcdbnew ();

  /* open the database */
  if (!kcdbopen (db, argv[1], KCOWRITER | KCOCREATE))
    {
      fprintf (stderr, "open error: %s\n", kcecodename (kcdbecode (db)));
      return 100;
    }

  vbuf = kcdbget (db, argv[2], strlen (argv[2]), &vsiz);
  if (vbuf)
    {
      printf ("%s\n", vbuf);
      kcfree (vbuf);
    }
  /* delete the database object */
  kcdbdel (db);

  finish = clock ();
  duration = (finish - start);
  printf ("\nduration : %iclock (%i clock/s) \n", duration, CLOCKS_PER_SEC);

  return 0;
}
예제 #5
0
파일: pwd.c 프로젝트: SyuTingSong/pwd.tw
char * pwd_save(KCDB * db, const char * origin_url)
{
	char * pk, * epk, * url;
	char hash[41];
	size_t vsiz;
	if(!kcdbopen(db, db_file, KCOWRITER|KCOCREATE))
	{
		printf("Status: 500 INTERNAL ERROR\r\n\r\nkcdb open error: %s\n", kcecodename(kcdbecode(db)));
		return NULL;
	}

	if(strstr(origin_url, "http://") == NULL && strstr(origin_url, "https://") == NULL)
	{
		url = malloc(strlen(origin_url) + 8);
		strcpy(url, "http://");
		strcat(url, origin_url);
	}
	else
	{
		url = malloc(strlen(origin_url) + 1);
		strcpy(url, origin_url);
	}

	// calc url hash and check if exists
	sha1(hash, url);
	epk = kcdbget(db, hash, strlen(hash), &vsiz);
	if(epk)
	{
		pk = malloc(strlen(epk) + 1);
		strcpy(pk, epk);
		kcfree(epk);
		free(url);
		kcdbclose(db);
		return pk;
	}

	pk = pwd_get_pk(db);
	if(pk == NULL)
	{
		free(url);
		kcdbclose(db);
		return NULL;
	}

	//TODO save pk => url && hash => pk
	if(!kcdbset(db, pk, strlen(pk), url, strlen(url)))
	{
		free(pk); pk = NULL;
	}
	if(!kcdbset(db, hash, strlen(hash), pk, strlen(pk)))
	{
		free(pk); pk = NULL;
	}

	free(url);
	kcdbclose(db);
	return pk;
}
예제 #6
0
char *rdf_kb_rid_unhash(KCDB *hash_st, rid rid) {
     char tmp_rid[16+1];
     char *vbuf;
     size_t vsiz;
     sprintf(tmp_rid,"%llx",rid);
     vbuf = kcdbget(hash_st, tmp_rid , 16 * sizeof(char), &vsiz);
     //log_debug("%llx %s", rid, vbuf);
     return vbuf;
}
예제 #7
0
파일: pwd.c 프로젝트: SyuTingSong/pwd.tw
char * pwd_get_pk(KCDB * db)
{
	char * pk, * result;
	size_t vsiz;
	int i;
	const char * map = ".adgjmptw";

	pk = kcdbget(db, "master", 6, &vsiz);
	if(pk)
	{
		result = malloc(vsiz + 2);
		strcpy(result, pk);
		kcfree(pk); pk = NULL;
	}
	else
	{
		result = malloc(3);
		strcpy(result, "0");
	}

	// increase pk
	vsiz = strlen(result);
	for(i = 0; ; i++)
	{
		if(i == vsiz)
		{
			result[i] = i == 0 ? '1' : (result[i - 1] == '1' ? '2' : '1');
			result[i + 1] = '\0';
			break;
		}
		result[i]++;
		if(result[i] >= '9')
			result[i] = i > 0 ? (result[i - 1] == '0' ? '1' : '0') : '1';
		else if(i > 0 && result[i - 1] == result[i])
			i--;
		else if(i < vsiz && result[i + 1] == result[i])
			i--;
		else
			break;
	}

	if(!kcdbset(db, "master", 6, result, strlen(result)))
	{
		free(result);
		return NULL;
	}

	// mapping result
	vsiz = strlen(result);
	for(i = 0 ; i < vsiz; i++)
	{
		result[i] = map[result[i]&0x0f];
	}
	return result;
}
예제 #8
0
static nxweb_result download_on_request(nxweb_http_server_connection* conn, nxweb_http_request* req, nxweb_http_response* resp) 
{
    nxweb_parse_request_parameters( req, 0 );
    const char *name_space = nx_simple_map_get_nocase( req->parameters, "namespace" );

    char * url = malloc(strlen(req->path_info)+1);
    if (!url) {return NXWEB_ERROR;}
    strcpy(url, req->path_info);
    url[strlen(req->path_info)] = '\0';

    nxweb_url_decode( url, 0 );
    char *fname = url, *temp;
    while (temp = strstr(fname, "/")) {fname = temp + 1;}

    char *strip_args = strstr(fname, "?");

    int fname_len = strip_args ? (strip_args - fname) : strlen(fname);
    char fname_with_space[1024] = {0};
    if ( strlen(url) > sizeof(fname_with_space)-1 ) {
	char err_msg[1024] = {0};
	snprintf( err_msg, sizeof(err_msg)-1, 
		"<html><body>File not found<br/>namespace:%s<br/>filename:%.*s</body></html>", 
		name_space, fname_len, fname );
	nxweb_send_http_error(resp, 404, err_msg);
	resp->keep_alive=0;
	free(url);
	return NXWEB_MISS;
    }

    if( name_space ) {sprintf( fname_with_space, "%s:/", name_space);}
    else {strcpy( fname_with_space, ":/" );}

    strncat( fname_with_space, fname, fname_len );

    size_t file_size = 0;
    char *pfile_data = kcdbget( g_kcdb, fname_with_space, strlen(fname_with_space), &file_size );
    if ( pfile_data == NULL ) {
	char err_msg[1024] = {0};
	snprintf( err_msg, sizeof(err_msg)-1, 
		"<html><body>File not found<br/>namespace:%s<br/>filename:%.*s</body></html>", 
		name_space, fname_len, fname );
	nxweb_send_http_error(resp, 404, err_msg);
	resp->keep_alive=0;
	free(url);
	return NXWEB_MISS;
    }

    KC_DATA *ptmp = nxb_alloc_obj(req->nxb, sizeof(KC_DATA));
    nxweb_set_request_data(req, UPLOAD_HANDLER_KEY, (nxe_data)(void *)ptmp, upload_request_data_finalize);
    ptmp->data_ptr = pfile_data;

    nxweb_send_data( resp, pfile_data + RECORD_HEADER_LEN, file_size - RECORD_HEADER_LEN, "application/octet-stream" );
    free(url);
    return NXWEB_OK;
}
예제 #9
0
void get_master_pgn(struct evhttp_request *req, void *context) {
    if (evhttp_request_get_command(req) != EVHTTP_REQ_GET) {
        evhttp_send_error(req, HTTP_BADMETHOD, "Method Not Allowed");
        return;
    }

    const struct evhttp_uri *uri = evhttp_request_get_evhttp_uri(req);
    if (!uri) {
        puts("evhttp_request_get_evhttp_uri failed");
        return;
    }

    const char *path = evhttp_uri_get_path(uri);
    if (!path) {
        puts("evhttp_uri_get_path failed");
        return;
    }

    char game_id[9] = {};
    int end;
    if (1 != sscanf(path, "/master/pgn/%8s%n", game_id, &end) ||
            strlen(game_id) != 8 ||
            strlen(path) != end) {
        evhttp_send_error(req, HTTP_NOTFOUND, "Not Found");
        return;
    }

    size_t pgn_size;
    char *pgn = kcdbget(master_pgn_db, game_id, 8, &pgn_size);
    if (!pgn) {
        evhttp_send_error(req, HTTP_NOTFOUND, "Master PGN Not Found");
        return;
    }

    struct evbuffer *res = evbuffer_new();
    if (!res) {
        puts("could not allocate response buffer");
        abort();
    }

    struct evkeyvalq *headers = evhttp_request_get_output_headers(req);
    evhttp_add_header(headers, "Content-Type", "application/vnd.chess-pgn; charset=utf-8");

    evbuffer_add(res, pgn, pgn_size);
    kcfree(pgn);

    evhttp_send_reply(req, HTTP_OK, "OK", res);
    evbuffer_free(res);
}
예제 #10
0
파일: pwd.c 프로젝트: SyuTingSong/pwd.tw
char * pwd_load(KCDB * db, const char * key)
{
	char * url, * value;
	size_t vsiz;

	if(!kcdbopen(db, db_file, KCOREADER))
	{
		printf("Status: 500 INTERNAL ERROR\r\n\r\nkcdb open error: %s\n", kcecodename(kcdbecode(db)));
		return NULL;
	}

	value = kcdbget(db, key, strlen(key), &vsiz);
	if(!value)
	{
		kcdbclose(db);
		return NULL;
	}

	url = malloc(strlen(value) + 1);
	strcpy(url, value);
	kcfree(value);
	kcdbclose(db);
	return url;
}
예제 #11
0
파일: pg_kc.c 프로젝트: cloudflare/SortaSQL
Datum kc_delete(PG_FUNCTION_ARGS) {
    
    char       *map_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
    char       *start_time = text_to_cstring(PG_GETARG_TEXT_PP(1));
    ArrayType  *rids = PG_GETARG_ARRAYTYPE_P(2);
    int        i;
    Datum      *rid_datums;
    bool       *rid_nulls;
    int        rid_count;
    char       *next_rid;
    KCDB       *main_db;
    char       *vbuf;
    size_t      vsiz;
    int64_t     num_keys_to_run;
    int64_t     num_keys_deleted;
    char        **keys_to_use;
    Cloudflare__ZoneTimeBucket *msg_new;

    // Open our DB.
    main_db = kcdbnew();
    if (!open_db (main_db, map_name, start_time)) {
        PG_RETURN_INT64(0);
    }
    kcdbbegintran (main_db, 0);

    // Now run over the array.
    deconstruct_array(rids, TEXTOID, -1, false, 'i',
                      &rid_datums, &rid_nulls, &rid_count);
    if (ARR_HASNULL(rids)) {
        ereport(ERROR,
                (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                 errmsg("cannot work with arrays containing NULLs")));
    }

    keys_to_use = (char **)palloc(KC_MAX_ENTRIES_PER_RID * sizeof(char));
    num_keys_deleted = 0;
    char prefixes_to_use[rid_count][KC_MAX_RID];

    for (i = 0; i < rid_count; i++) {
        next_rid = TextDatumGetCString(rid_datums[i]);
        snprintf(prefixes_to_use[i], KC_MAX_RID, "%s%s", next_rid, CF_LABEL_SEP);
        num_keys_to_run = kcdbmatchprefix (main_db,	prefixes_to_use[i], keys_to_use, KC_MAX_ENTRIES_PER_RID);
        if (num_keys_to_run != -1) {
            num_keys_deleted += num_keys_to_run;
            int next_key;
            for (next_key=0; next_key < num_keys_to_run; next_key++) {
                vbuf = kcdbget(main_db, keys_to_use[next_key], strlen(keys_to_use[next_key]), &vsiz);
                if (vbuf) {
                    msg_new = cloudflare__zone_time_bucket__unpack(NULL, vsiz, (const uint8_t *)vbuf);
                    if (msg_new == NULL) {   // Something failed
                        ereport(ERROR,
                                (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                                 errmsg("error unpacking incoming message")));
                    } else {
                        if (msg_new->kv_map_file) {
                            unlink(msg_new->kv_map_file);
                        }
                        kcdbremove (main_db, keys_to_use[next_key], strlen(keys_to_use[next_key]));	
                    }
                    cloudflare__zone_time_bucket__free_unpacked(msg_new, NULL);
                    kcfree(vbuf);
                    kcfree(keys_to_use[next_key]);
                } else {
                    ereport(NOTICE,
                            (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                             errmsg("get error on %s -- %s", keys_to_use[next_key], kcecodename(kcdbecode(main_db)))));
                }
            }
        } else {
            ereport(NOTICE,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("prefix error on %s -- %s", prefixes_to_use[i], kcecodename(kcdbecode(main_db)))));
        }
    }

    pfree(keys_to_use);
    
    // Done!
    kcdbendtran (main_db, 1);
    if (!kcdbclose(main_db)) {
        ereport(ERROR,
                (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                 errmsg("Error Closeing db: \"%s\"", kcecodename(kcdbecode(main_db)))));
    }

    PG_RETURN_INT64(num_keys_deleted);
}
예제 #12
0
파일: pg_kc.c 프로젝트: cloudflare/SortaSQL
Datum kc_shrink(PG_FUNCTION_ARGS) {
    
    char       *map_name = text_to_cstring(PG_GETARG_TEXT_PP(0));
    char       *start_time = text_to_cstring(PG_GETARG_TEXT_PP(1)); // Start time + uid!!!
    char       *new_rid = text_to_cstring(PG_GETARG_TEXT_PP(2));
    ArrayType  *old_rids = PG_GETARG_ARRAYTYPE_P(3);
    char       *classification = text_to_cstring(PG_GETARG_TEXT_PP(4));
    char       *doctype = text_to_cstring(PG_GETARG_TEXT_PP(5));
    char       *pop = text_to_cstring(PG_GETARG_TEXT_PP(6));
    char       *psource = text_to_cstring(PG_GETARG_TEXT_PP(7));
    text       *tout;   
    int        i,j;
    Datum      *rid_datums;
    bool       *rid_nulls;
    int        rid_count;
    char       *next_rid;
    KCDB       *main_db;
    char       *vbuf;
    size_t      vsiz;

    // Open our DB.
    main_db = kcdbnew();
    if (!open_db (main_db, map_name, start_time)) {
        tout = cstring_to_text(new_rid);
        PG_RETURN_TEXT_P(tout);        
    }
    kcdbbegintran (main_db, 0);
    
    // First fill in what we can from the input.
    Cloudflare__ZoneTimeBucket msg = CLOUDFLARE__ZONE_TIME_BUCKET__INIT;
    
    msg.map_name = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.doctype = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.classification = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.pop = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.psource = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.result_id = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.db_key = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.db_path = (char *)palloc(MAX_KC_ROW_ENTRY * sizeof(char));
    msg.map_entry = palloc(MAX_KEYS_BEFORE_KV_MAP * sizeof(Cloudflare__ZoneTimeBucket__Counter));
    msg.n_map_entry = 0;

    strncpy(msg.map_name, map_name, MAX_KC_ROW_ENTRY);
    strncpy(msg.classification, classification, MAX_KC_ROW_ENTRY);
    strncpy(msg.doctype, doctype, MAX_KC_ROW_ENTRY);
    strncpy(msg.pop, pop, MAX_KC_ROW_ENTRY);
    strncpy(msg.psource, psource, MAX_KC_ROW_ENTRY);
    strncpy(msg.result_id, new_rid, KC_MAX_RID);
    snprintf(msg.db_path, MAX_KC_ROW_ENTRY, "%s%s%s", 
             map_name, "/", start_time);

    snprintf(msg.db_key, KC_MAX_RID, "%s%s%s%s%s%s%s%s%s%s%s", 
             new_rid, CF_LABEL_SEP,
             classification, CF_LABEL_SEP, 
             doctype, CF_LABEL_SEP,
             pop, CF_LABEL_SEP,
             psource, CF_LABEL_SEP,
             map_name);

    // Now run over the array.
    deconstruct_array(old_rids, TEXTOID, -1, false, 'i',
                      &rid_datums, &rid_nulls, &rid_count);
    if (ARR_HASNULL(old_rids)) {
        ereport(ERROR,
                (errcode(ERRCODE_ARRAY_ELEMENT_ERROR),
                 errmsg("cannot work with arrays containing NULLs")));
    }

    int num_new_keys = 0;
    int num_entries = 0;
    char keys_to_use[rid_count][KC_MAX_RID];
    Cloudflare__ZoneTimeBucket *msg_new[rid_count];
    j=0;
    for (i = 0; i < rid_count; i++) {
        next_rid = TextDatumGetCString(rid_datums[i]);
        snprintf(keys_to_use[i], KC_MAX_RID, "%s%s%s%s%s%s%s%s%s%s%s", 
                 next_rid, CF_LABEL_SEP, 
                 classification, CF_LABEL_SEP,
                 doctype, CF_LABEL_SEP,
                 pop, CF_LABEL_SEP,
                 psource, CF_LABEL_SEP,
                 map_name);

        vbuf = kcdbget(main_db, keys_to_use[i], strlen(keys_to_use[i]), &vsiz);
        if (vbuf) {
            msg_new[j] = cloudflare__zone_time_bucket__unpack(NULL, vsiz, (const uint8_t *)vbuf);
            if (msg_new[j] == NULL) {   // Something failed
                ereport(ERROR,
                        (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                         errmsg("error unpacking incoming message")));
            } else {
                if (msg_new[j]->kv_map_file) {
                    num_entries = MAX_KEYS_BEFORE_KV_MAP + 1;                    
                } else {
                    num_entries += msg_new[j]->n_map_entry; 
                }
                j++;
            }
            kcfree(vbuf);
        } else {
#ifdef CF_DUBUG
            ereport(NOTICE,
                    (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                     errmsg("get error on %s -- %s", keys_to_use[i], kcecodename(kcdbecode(main_db)))));
#endif
        }
    }
    
    // Now merge the buffers.
    KCDB* msg_db = NULL;
    if (num_entries > MAX_KEYS_BEFORE_KV_MAP) {
        msg_db = kcdbnew();
        set_kv_path(&msg, map_name, start_time, msg_db);
    }

    for (i = 0; i < j; i++) {
        if (num_entries > MAX_KEYS_BEFORE_KV_MAP) {
            num_new_keys += merge_using_kv_map(&msg, msg_new[i], msg_db);
        } else {
            num_new_keys += merge_messages_basic(&msg, msg_new[i]);
        }
        cloudflare__zone_time_bucket__free_unpacked(msg_new[i], NULL);
    }

    if (num_entries > MAX_KEYS_BEFORE_KV_MAP) {
        // Close the db.
        kcdbendtran (msg_db, 1);
        kcdbclose(msg_db);
    }

#ifdef CF_DUBUG
    ereport(NOTICE,
            (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
             errmsg("saving: num map entries: %zu -- writting with %d keys", msg.n_map_entry, num_new_keys)));
#endif

    // Save the updated buffer.
    if (num_new_keys > 0) {
        unsigned int len;
        void *buf;
        len = cloudflare__zone_time_bucket__get_packed_size (&msg);  
        buf = palloc (len);           
        cloudflare__zone_time_bucket__pack (&msg, buf);
        if(!kcdbset(main_db, msg.db_key, strlen(msg.db_key), buf, len)) {
            ereport(ERROR,
                    (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                     errmsg("set error: %s\n", kcecodename(kcdbecode(main_db)))));
        }
        pfree (buf);
    }

    // Done!
    kcdbendtran (main_db, 1);
    if (!kcdbclose(main_db)) {
        ereport(ERROR,
                (errcode(ERRCODE_EXTERNAL_ROUTINE_EXCEPTION),
                 errmsg("Error Closeing db: \"%s\"", kcecodename(kcdbecode(main_db)))));
    }

    tout = cstring_to_text(new_rid);
    PG_RETURN_TEXT_P(tout);
}
예제 #13
0
/* perform order command */
static int32_t procorder(const char* path, int64_t rnum, int32_t rnd, int32_t etc,
                         int32_t tran, int32_t oflags) {
    KCDB* db;
    KCCUR* cur, *paracur;
    int32_t err;
    char kbuf[RECBUFSIZ], *vbuf, wbuf[RECBUFSIZ], *corepath, *copypath, *snappath;
    size_t ksiz, vsiz, psiz;
    int32_t wsiz;
    int64_t i, cnt;
    double stime, etime;
    VISARG visarg;
    oprintf("<In-order Test>\n  path=%s  rnum=%ld  rnd=%d  etc=%d  tran=%d  oflags=%d\n\n",
            path, (long)rnum, rnd, etc, tran, oflags);
    err = FALSE;
    db = kcdbnew();
    oprintf("opening the database:\n");
    stime = kctime();
    if (!kcdbopen(db, path, KCOWRITER | KCOCREATE | KCOTRUNCATE | oflags)) {
        dberrprint(db, __LINE__, "kcdbopen");
        err = TRUE;
    }
    etime = kctime();
    dbmetaprint(db, FALSE);
    oprintf("time: %.3f\n", etime - stime);
    oprintf("setting records:\n");
    stime = kctime();
    for (i = 1; !err && i <= rnum; i++) {
        if (tran && !kcdbbegintran(db, FALSE)) {
            dberrprint(db, __LINE__, "kcdbbegintran");
            err = TRUE;
        }
        ksiz = sprintf(kbuf, "%08ld", (long)(rnd ? myrand(rnum) + 1 : i));
        if (!kcdbset(db, kbuf, ksiz, kbuf, ksiz)) {
            dberrprint(db, __LINE__, "kcdbset");
            err = TRUE;
        }
        if (tran && !kcdbendtran(db, TRUE)) {
            dberrprint(db, __LINE__, "kcdbendtran");
            err = TRUE;
        }
        if (rnum > 250 && i % (rnum / 250) == 0) {
            oputchar('.');
            if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08ld)\n", (long)i);
        }
    }
    etime = kctime();
    dbmetaprint(db, FALSE);
    oprintf("time: %.3f\n", etime - stime);
    if (etc) {
        oprintf("adding records:\n");
        stime = kctime();
        for (i = 1; !err && i <= rnum; i++) {
            if (tran && !kcdbbegintran(db, FALSE)) {
                dberrprint(db, __LINE__, "kcdbbegintran");
                err = TRUE;
            }
            ksiz = sprintf(kbuf, "%08ld", (long)(rnd ? myrand(rnum) + 1 : i));
            if (!kcdbadd(db, kbuf, ksiz, kbuf, ksiz) && kcdbecode(db) != KCEDUPREC) {
                dberrprint(db, __LINE__, "kcdbadd");
                err = TRUE;
            }
            if (tran && !kcdbendtran(db, TRUE)) {
                dberrprint(db, __LINE__, "kcdbendtran");
                err = TRUE;
            }
            if (rnum > 250 && i % (rnum / 250) == 0) {
                oputchar('.');
                if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08ld)\n", (long)i);
            }
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
    }
    if (etc) {
        oprintf("appending records:\n");
        stime = kctime();
        for (i = 1; !err && i <= rnum; i++) {
            if (tran && !kcdbbegintran(db, FALSE)) {
                dberrprint(db, __LINE__, "kcdbbegintran");
                err = TRUE;
            }
            ksiz = sprintf(kbuf, "%08ld", (long)(rnd ? myrand(rnum) + 1 : i));
            if (!kcdbappend(db, kbuf, ksiz, kbuf, ksiz)) {
                dberrprint(db, __LINE__, "kcdbadd");
                err = TRUE;
            }
            if (tran && !kcdbendtran(db, TRUE)) {
                dberrprint(db, __LINE__, "kcdbendtran");
                err = TRUE;
            }
            if (rnum > 250 && i % (rnum / 250) == 0) {
                oputchar('.');
                if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08ld)\n", (long)i);
            }
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
    }
    oprintf("getting records:\n");
    stime = kctime();
    for (i = 1; !err && i <= rnum; i++) {
        if (tran && !kcdbbegintran(db, FALSE)) {
            dberrprint(db, __LINE__, "kcdbbegintran");
            err = TRUE;
        }
        ksiz = sprintf(kbuf, "%08ld", (long)(rnd ? myrand(rnum) + 1 : i));
        vbuf = kcdbget(db, kbuf, ksiz, &vsiz);
        if (vbuf) {
            if (vsiz < ksiz || memcmp(vbuf, kbuf, ksiz)) {
                dberrprint(db, __LINE__, "kcdbget");
                err = TRUE;
            }
            kcfree(vbuf);
        } else if (!rnd || kcdbecode(db) != KCENOREC) {
            dberrprint(db, __LINE__, "kcdbget");
            err = TRUE;
        }
        if (tran && !kcdbendtran(db, TRUE)) {
            dberrprint(db, __LINE__, "kcdbendtran");
            err = TRUE;
        }
        if (rnum > 250 && i % (rnum / 250) == 0) {
            oputchar('.');
            if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08ld)\n", (long)i);
        }
    }
    etime = kctime();
    dbmetaprint(db, FALSE);
    oprintf("time: %.3f\n", etime - stime);
    if (etc) {
        oprintf("getting records with a buffer:\n");
        stime = kctime();
        for (i = 1; !err && i <= rnum; i++) {
            if (tran && !kcdbbegintran(db, FALSE)) {
                dberrprint(db, __LINE__, "kcdbbegintran");
                err = TRUE;
            }
            ksiz = sprintf(kbuf, "%08ld", (long)(rnd ? myrand(rnum) + 1 : i));
            wsiz = kcdbgetbuf(db, kbuf, ksiz, wbuf, sizeof(wbuf));
            if (wsiz >= 0) {
                if (wsiz < (int32_t)ksiz || memcmp(wbuf, kbuf, ksiz)) {
                    dberrprint(db, __LINE__, "kcdbgetbuf");
                    err = TRUE;
                }
            } else if (!rnd || kcdbecode(db) != KCENOREC) {
                dberrprint(db, __LINE__, "kcdbgetbuf");
                err = TRUE;
            }
            if (tran && !kcdbendtran(db, TRUE)) {
                dberrprint(db, __LINE__, "kcdbendtran");
                err = TRUE;
            }
            if (rnum > 250 && i % (rnum / 250) == 0) {
                oputchar('.');
                if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08ld)\n", (long)i);
            }
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
    }
    if (etc) {
        oprintf("traversing the database by the inner iterator:\n");
        stime = kctime();
        cnt = kcdbcount(db);
        visarg.rnum = rnum;
        visarg.rnd = rnd;
        visarg.cnt = 0;
        memset(visarg.rbuf, '+', sizeof(visarg.rbuf));
        if (tran && !kcdbbegintran(db, FALSE)) {
            dberrprint(db, __LINE__, "kcdbbegintran");
            err = TRUE;
        }
        if (!kcdbiterate(db, visitfull, &visarg, TRUE)) {
            dberrprint(db, __LINE__, "kcdbiterate");
            err = TRUE;
        }
        if (rnd) oprintf(" (end)\n");
        if (tran && !kcdbendtran(db, TRUE)) {
            dberrprint(db, __LINE__, "kcdbendtran");
            err = TRUE;
        }
        if (visarg.cnt != cnt) {
            dberrprint(db, __LINE__, "kcdbiterate");
            err = TRUE;
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
    }
    if (etc) {
        oprintf("traversing the database by the outer cursor:\n");
        stime = kctime();
        cnt = kcdbcount(db);
        visarg.rnum = rnum;
        visarg.rnd = rnd;
        visarg.cnt = 0;
        if (tran && !kcdbbegintran(db, FALSE)) {
            dberrprint(db, __LINE__, "kcdbbegintran");
            err = TRUE;
        }
        cur = kcdbcursor(db);
        if (!kccurjump(cur) && kccurecode(cur) != KCENOREC) {
            dberrprint(db, __LINE__, "kccurjump");
            err = TRUE;
        }
        paracur = kcdbcursor(db);
        while (!err && kccuraccept(cur, &visitfull, &visarg, TRUE, !rnd)) {
            if (rnd) {
                ksiz = sprintf(kbuf, "%08ld", (long)myrand(rnum));
                switch (myrand(3)) {
                case 0: {
                    if (!kcdbremove(db, kbuf, ksiz) && kcdbecode(db) != KCENOREC) {
                        dberrprint(db, __LINE__, "kcdbremove");
                        err = TRUE;
                    }
                    break;
                }
                case 1: {
                    if (!kccurjumpkey(paracur, kbuf, ksiz) && kccurecode(paracur) != KCENOREC) {
                        dberrprint(db, __LINE__, "kccurjump");
                        err = TRUE;
                    }
                    break;
                }
                default: {
                    if (!kccurstep(cur) && kccurecode(cur) != KCENOREC) {
                        dberrprint(db, __LINE__, "kccurstep");
                        err = TRUE;
                    }
                    break;
                }
                }
            }
        }
        oprintf(" (end)\n");
        kccurdel(paracur);
        kccurdel(cur);
        if (tran && !kcdbendtran(db, TRUE)) {
            dberrprint(db, __LINE__, "kcdbendtran");
            err = TRUE;
        }
        if (!rnd && visarg.cnt != cnt) {
            dberrprint(db, __LINE__, "kccuraccept");
            err = TRUE;
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
    }
    if (etc) {
        oprintf("synchronizing the database:\n");
        stime = kctime();
        if (!kcdbsync(db, FALSE, NULL, NULL)) {
            dberrprint(db, __LINE__, "kcdbsync");
            err = TRUE;
        }
        if (!kcdboccupy(db, FALSE, NULL, NULL)) {
            dberrprint(db, __LINE__, "kcdboccupy");
            err = TRUE;
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
    }
    if (etc) {
        corepath = kcdbpath(db);
        psiz = strlen(corepath);
        if (strstr(corepath, ".kch") || strstr(corepath, ".kct")) {
            copypath = kcmalloc(psiz + 256);
            sprintf(copypath, "%s.tmp", corepath);
            snappath = kcmalloc(psiz + 256);
            sprintf(snappath, "%s.kcss", corepath);
        } else {
            copypath = kcmalloc(256);
            sprintf(copypath, "kclangctest.tmp");
            snappath = kcmalloc(256);
            sprintf(snappath, "kclangctest.kcss");
        }
        oprintf("copying the database file:\n");
        stime = kctime();
        if (!kcdbcopy(db, copypath)) {
            dberrprint(db, __LINE__, "kcdbcopy");
            err = TRUE;
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
        remove(copypath);
        oprintf("dumping records into snapshot:\n");
        stime = kctime();
        if (!kcdbdumpsnap(db, snappath)) {
            dberrprint(db, __LINE__, "kcdbdumpsnap");
            err = TRUE;
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
        oprintf("loading records into snapshot:\n");
        stime = kctime();
        cnt = kcdbcount(db);
        if (rnd && myrand(2) == 0 && !kcdbclear(db)) {
            dberrprint(db, __LINE__, "kcdbclear");
            err = TRUE;
        }
        if (!kcdbloadsnap(db, snappath) || kcdbcount(db) != cnt) {
            dberrprint(db, __LINE__, "kcdbloadsnap");
            err = TRUE;
        }
        etime = kctime();
        dbmetaprint(db, FALSE);
        oprintf("time: %.3f\n", etime - stime);
        remove(snappath);
        kcfree(copypath);
        kcfree(snappath);
        kcfree(corepath);
    }
    oprintf("removing records:\n");
    stime = kctime();
    for (i = 1; !err && i <= rnum; i++) {
        if (tran && !kcdbbegintran(db, FALSE)) {
            dberrprint(db, __LINE__, "kcdbbegintran");
            err = TRUE;
        }
        ksiz = sprintf(kbuf, "%08ld", (long)(rnd ? myrand(rnum) + 1 : i));
        if (!kcdbremove(db, kbuf, ksiz) &&
                ((!rnd && !etc) || kcdbecode(db) != KCENOREC)) {
            dberrprint(db, __LINE__, "kcdbremove");
            err = TRUE;
        }
        if (tran && !kcdbendtran(db, TRUE)) {
            dberrprint(db, __LINE__, "kcdbendtran");
            err = TRUE;
        }
        if (rnum > 250 && i % (rnum / 250) == 0) {
            oputchar('.');
            if (i == rnum || i % (rnum / 10) == 0) oprintf(" (%08ld)\n", (long)i);
        }
    }
    etime = kctime();
    dbmetaprint(db, TRUE);
    oprintf("time: %.3f\n", etime - stime);
    oprintf("closing the database:\n");
    stime = kctime();
    if (!kcdbclose(db)) {
        dberrprint(db, __LINE__, "kcdbclose");
        err = TRUE;
    }
    etime = kctime();
    oprintf("time: %.3f\n", etime - stime);
    kcdbdel(db);
    oprintf("%s\n\n", err ? "error" : "ok");
    return err ? 1 : 0;
}
예제 #14
0
void get_master(struct evhttp_request *req, void *context) {
    if (evhttp_request_get_command(req) != EVHTTP_REQ_GET) {
        evhttp_send_error(req, HTTP_BADMETHOD, "Method Not Allowed");
        return;
    }

    const char *uri = evhttp_request_get_uri(req);
    if (!uri) {
        puts("evhttp_request_get_uri failed");
        return;
    }

    struct evkeyvalq query;
    const char *fen = NULL;
    const char *jsonp = NULL;
    int moves = 12;
    int topGames = 4;
    if (0 == evhttp_parse_query(uri, &query)) {
        fen = evhttp_find_header(&query, "fen");
        jsonp = evhttp_find_header(&query, "callback");

        if (evhttp_find_header(&query, "moves")) {
            moves = atoi(evhttp_find_header(&query, "moves"));
        }

        if (evhttp_find_header(&query, "topGames")) {
            topGames = atoi(evhttp_find_header(&query, "topGames"));
        }
    }
    if (!fen || !strlen(fen)) {
        evhttp_send_error(req, HTTP_BADREQUEST, "Missing FEN");
        return;
    }

    // Look up positon.
    board_t pos;
    if (!board_set_fen(&pos, fen)) {
        evhttp_send_error(req, HTTP_BADREQUEST, "Invalid FEN");
    }

    if (verbose) printf("master: %.255s\n", fen);

    struct evbuffer *res = evbuffer_new();
    if (!res) {
        puts("could not allocate response buffer");
        abort();
    }

    // CORS.
    struct evkeyvalq *headers = evhttp_request_get_output_headers(req);
    if (cors) evhttp_add_header(headers, "Access-Control-Allow-Origin", "*");

    // Set Content-Type.
    if (jsonp && strlen(jsonp)) {
        evhttp_add_header(headers, "Content-Type", "application/javascript");
        evbuffer_add_printf(res, "%s(", jsonp);
    } else {
        evhttp_add_header(headers, "Content-Type", "application/json");
    }

    uint64_t zobrist_hash = board_zobrist_hash(&pos, POLYGLOT);

    struct master_record *record = master_record_new();
    size_t record_size;
    char *encoded_record = kcdbget(master_db, (const char *) &zobrist_hash, 8, &record_size);
    if (encoded_record) {
        decode_master_record((const uint8_t *) encoded_record, record);
    }

    unsigned long average_rating_sum = master_record_average_rating_sum(record);
    unsigned long total_white = master_record_white(record);
    unsigned long total_draws = master_record_draws(record);
    unsigned long total_black = master_record_black(record);
    unsigned long total = total_white + total_draws + total_black;

    evbuffer_add_printf(res, "{\n");

    // Add totals.
    evbuffer_add_printf(res, "  \"white\": %lu,\n", total_white);
    evbuffer_add_printf(res, "  \"draws\": %lu,\n", total_draws);
    evbuffer_add_printf(res, "  \"black\": %lu,\n", total_black);
    if (total) evbuffer_add_printf(res, "  \"averageRating\": %lu,\n", average_rating_sum / total);
    else evbuffer_add_printf(res, "  \"averageRating\": null,\n");

    // Add move list.
    evbuffer_add_printf(res, "  \"moves\": [\n");
    for (size_t i = 0; i < record->num_moves && i < moves; i++) {
        unsigned long move_total = record->moves[i].white + record->moves[i].draws + record->moves[i].black;

        char uci[LEN_UCI], san[LEN_SAN];
        move_uci(record->moves[i].move, uci);
        board_san(&pos, record->moves[i].move, san);

        evbuffer_add_printf(res, "    {\n");
        evbuffer_add_printf(res, "      \"uci\": \"%s\",\n", uci);
        evbuffer_add_printf(res, "      \"san\": \"%s\",\n", san);
        evbuffer_add_printf(res, "      \"white\": %lu,\n", record->moves[i].white);
        evbuffer_add_printf(res, "      \"draws\": %lu,\n", record->moves[i].draws);
        evbuffer_add_printf(res, "      \"black\": %lu,\n", record->moves[i].black);
        if (move_total) {
            evbuffer_add_printf(res, "      \"averageRating\": %lu\n", record->moves[i].average_rating_sum / move_total);
        } else {
            evbuffer_add_printf(res, "      \"averageRating\": null\n");
        }
        evbuffer_add_printf(res, "    }%s\n", (i < record->num_moves - 1 && i < moves - 1) ? "," : "");
    }

    evbuffer_add_printf(res, "  ],\n");

    // Add top games.
    evbuffer_add_printf(res, "  \"topGames\": [\n");
    for (size_t i = 0; i < record->num_refs && i < topGames; i++) {
        char game_id[9] = {};
        strncpy(game_id, record->refs[i].game_id, 8);

        size_t pgn_size;
        char *pgn = kcdbget(master_pgn_db, game_id, 8, &pgn_size);
        if (!pgn) continue;

        char *save_ptr;
        struct pgn_game_info *game_info = pgn_game_info_read(pgn, &save_ptr);
        if (!game_info->white || !game_info->black) continue;

        evbuffer_add_printf(res, "    {\n");
        // TODO: winner, white.name, white.rating, black.name, black.rating, -avg rating
        evbuffer_add_printf(res, "      \"id\": \"%s\",\n", game_id);
        evbuffer_add_printf(res, "      \"winner\": \"%s\",\n", game_info->result ? (game_info->result > 0 ? "white" : "black") : "draw");
        evbuffer_add_printf(res, "      \"white\": {\n");
        evbuffer_add_printf(res, "        \"name\": \"%s\",\n", game_info->white); // XXX TODO !
        evbuffer_add_printf(res, "        \"rating\": %d\n", game_info->white_elo);
        evbuffer_add_printf(res, "      },\n");
        evbuffer_add_printf(res, "      \"black\": {\n");
        evbuffer_add_printf(res, "        \"name\": \"%s\",\n", game_info->black); // XXX TODO !
        evbuffer_add_printf(res, "        \"rating\": %d\n", game_info->black_elo);
        evbuffer_add_printf(res, "      },\n");
        evbuffer_add_printf(res, "      \"year\": %d\n", game_info->year);
        evbuffer_add_printf(res, "    }%s\n", (i < record->num_refs - 1 && i < topGames - 1) ? "," : "");
    }
    evbuffer_add_printf(res, "  ]\n");

    evbuffer_add_printf(res, "}%s\n", (jsonp && strlen(jsonp)) ? ")" : "");

    evhttp_send_reply(req, HTTP_OK, "OK", res);
    evbuffer_free(res);
}