damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

ndb.c (4286B)


      1 
      2 
      3 #include "nostrdb.h"
      4 #include "print_util.h"
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <sys/stat.h>
      8 #include <sys/mman.h>
      9 #include <unistd.h>
     10 #include <fcntl.h>
     11 
     12 static int usage()
     13 {
     14 	printf("usage: ndb [--skip-verification] [-d db_dir] <command>\n\n");
     15 	printf("commands\n\n");
     16 	printf("	stat\n");
     17 	printf("	search [--oldest-first] [--limit 42] <fulltext query>\n");
     18 	printf("	import <line-delimited json file>\n\n");
     19 	printf("settings\n\n");
     20 	printf("	--skip-verification  skip signature validation\n");
     21 	printf("	-d <db_dir>          set database directory\n");
     22 	return 1;
     23 }
     24 
     25 
     26 static int map_file(const char *filename, unsigned char **p, size_t *flen)
     27 {
     28 	struct stat st;
     29 	int des;
     30 	stat(filename, &st);
     31 	*flen = st.st_size;
     32 
     33 	des = open(filename, O_RDONLY);
     34 
     35 	*p = mmap(NULL, *flen, PROT_READ, MAP_PRIVATE, des, 0);
     36 	close(des);
     37 
     38 	return *p != MAP_FAILED;
     39 }
     40 
     41 static inline void print_stat_counts(struct ndb_stat_counts *counts)
     42 {
     43 	printf("%zu\t%zu\t%zu\t%zu\n",
     44 	       counts->count,
     45 	       counts->key_size,
     46 	       counts->value_size,
     47 	       counts->key_size + counts->value_size);
     48 }
     49 
     50 static void print_stats(struct ndb_stat *stat)
     51 {
     52 	int i;
     53 	const char *name;
     54 	struct ndb_stat_counts *c;
     55 
     56 	struct ndb_stat_counts total;
     57 	ndb_stat_counts_init(&total);
     58 
     59 	printf("name\tcount\tkey_bytes\tvalue_bytes\ttotal_bytes\n");
     60 	printf("---\ndbs\n---\n");
     61 	for (i = 0; i < NDB_DBS; i++) {
     62 		name = ndb_db_name(i);
     63 
     64 		total.count += stat->dbs[i].count;
     65 		total.key_size += stat->dbs[i].key_size;
     66 		total.value_size += stat->dbs[i].value_size;
     67 
     68 		printf("%s\t", name);
     69 		print_stat_counts(&stat->dbs[i]);
     70 	}
     71 
     72 	printf("total\t");
     73 	print_stat_counts(&total);
     74 
     75 	printf("-----\nkinds\n-----\n");
     76 	for (i = 0; i < NDB_CKIND_COUNT; i++) {
     77 		c = &stat->common_kinds[i];
     78 		if (c->count == 0)
     79 			continue;
     80 
     81 		printf("%s\t", ndb_kind_name(i));
     82 		print_stat_counts(c);
     83 	}
     84 
     85 	if (stat->other_kinds.count != 0) {
     86 		printf("other\t");
     87 		print_stat_counts(&stat->other_kinds);
     88 	}
     89 }
     90 
     91 int ndb_print_search_keys(struct ndb_txn *txn);
     92 
     93 int main(int argc, char *argv[])
     94 {
     95 	struct ndb *ndb;
     96 	int i, flags, limit;
     97 	struct ndb_stat stat;
     98 	struct ndb_txn txn;
     99 	struct ndb_text_search_results results;
    100 	struct ndb_text_search_result *result;
    101 	const char *dir;
    102 	unsigned char *data;
    103 	size_t data_len;
    104 	struct ndb_config config;
    105 	struct ndb_text_search_config search_config;
    106 	ndb_default_config(&config);
    107 	ndb_default_text_search_config(&search_config);
    108 	ndb_config_set_mapsize(&config, 1024ULL * 1024ULL * 1024ULL * 1024ULL /* 1 TiB */);
    109 
    110 	if (argc < 2) {
    111 		return usage();
    112 	}
    113 
    114 	dir = ".";
    115 	flags = 0;
    116 	for (i = 0; i < 2; i++)
    117 	{
    118 		if (!strcmp(argv[1], "-d") && argv[2]) {
    119 			dir = argv[2];
    120 			argv += 2;
    121 			argc -= 2;
    122 		} else if (!strcmp(argv[1], "--skip-verification")) {
    123 			flags = NDB_FLAG_SKIP_NOTE_VERIFY;
    124 			argv += 1;
    125 			argc -= 1;
    126 		}
    127 	}
    128 
    129 	ndb_config_set_flags(&config, flags);
    130 
    131 	fprintf(stderr, "using db '%s'\n", dir);
    132 
    133 	if (!ndb_init(&ndb, dir, &config)) {
    134 		return 2;
    135 	}
    136 
    137 	if (argc >= 3 && !strcmp(argv[1], "search")) {
    138 		for (i = 0; i < 2; i++) {
    139 			if (!strcmp(argv[2], "--oldest-first")) {
    140 				ndb_text_search_config_set_order(&search_config, NDB_ORDER_ASCENDING);
    141 				argv++;
    142 				argc--;
    143 			} else if (!strcmp(argv[2], "--limit")) {
    144 				limit = atoi(argv[3]);
    145 				ndb_text_search_config_set_limit(&search_config, limit);
    146 				argv += 2;
    147 				argc -= 2;
    148 			}
    149 		}
    150 
    151 		ndb_begin_query(ndb, &txn);
    152 		ndb_text_search(&txn, argv[2], &results, &search_config);
    153 
    154 		// print results for now
    155 		for (i = 0; i < results.num_results; i++) {
    156 			result = &results.results[i];
    157 			printf("[%02d] ", i+1);
    158 			ndb_print_text_search_result(&txn, result);
    159 		}
    160 
    161 		ndb_end_query(&txn);
    162 	} else if (argc == 2 && !strcmp(argv[1], "stat")) {
    163 		if (!ndb_stat(ndb, &stat)) {
    164 			return 3;
    165 		}
    166 
    167 		print_stats(&stat);
    168 	} else if (argc == 3 && !strcmp(argv[1], "import")) {
    169 		if (!strcmp(argv[2], "-")) {
    170 			ndb_process_events_stream(ndb, stdin);
    171 		} else {
    172 			map_file(argv[2], &data, &data_len);
    173 			ndb_process_events(ndb, (const char *)data, data_len);
    174 			ndb_process_client_events(ndb, (const char *)data, data_len);
    175 		}
    176 	} else if (argc == 2 && !strcmp(argv[1], "print-search-keys")) {
    177 		ndb_begin_query(ndb, &txn);
    178 		ndb_print_search_keys(&txn);
    179 		ndb_end_query(&txn);
    180 	} else {
    181 		return usage();
    182 	}
    183 
    184 	ndb_destroy(ndb);
    185 }