HistoryKeeper::HistoryKeeper(GenericDdInterface *db_) : db(db_) { /* DB format chats: * name -> id map id -- auto-incrementing number name -- chat's name (for user to user conversation it is opposite user public key) ctype -- chat type, reserved for group chats alisases: * user_id -> id map id -- auto-incrementing number name -- user's public key history: id -- auto-incrementing number timestamp chat_id -- current chat ID (resolves from chats table) sender -- sender's ID (resolves from aliases table) message */ // for old tables: QSqlQuery ans = db->exec("select seq from sqlite_sequence where name=\"history\";"); if (ans.first()) { int idMax = ans.value(0).toInt(); QSqlQuery ret = db->exec("select seq from sqlite_sequence where name=\"sent_status\";"); int idCur = 0; if (ret.first()) { idCur = ret.value(0).toInt(); } if (idCur != idMax) { QString cmd = QString("INSERT INTO sent_status (id, status) VALUES (%1, 1);").arg(idMax); db->exec(cmd); } } updateChatsID(); updateAliases(); setSyncType(Settings::getInstance().getDbSyncType()); messageID = 0; QSqlQuery sqlAnswer = db->exec("select seq from sqlite_sequence where name=\"history\";"); if (sqlAnswer.first()) messageID = sqlAnswer.value(0).toLongLong(); }
///MAIN/// int main(int argc, char *argv[]){ //STRUCTS AND VARIABLES //getopt related struct option longopts[] = { {"threads", required_argument, NULL, 't'}, {"iterations", required_argument, NULL, 'i'}, {"yield", no_argument, NULL, 'y'}, {"sync", required_argument, NULL, 's'}, {0,0,0,0}, }; //number variables int nThreads = 1; int nIter = 1; long long count = 0; char *name = "add-none"; //time holding structs struct timespec start; struct timespec end; //getopts temporary variables int opt; int longindex; int temp; //pthread related variables pthread_t *thArr; pthArg args; //ACTUAL CODE //set the values for these variables using getopt_long while((opt = getopt_long(argc,argv, "t:i:ys:", longopts, &longindex)) != -1){ switch(opt){ //THREAD case 't': temp = atoi(optarg); if(temp < 1){ fprintf(stderr, "Number of threads must be at least 1. Skipping this option.\n"); continue; } nThreads = temp; break; //ITERATIONS case 'i': temp = atoi(optarg); if(temp < 1){ fprintf(stderr, "Number of iterations must be at least 1. Skipping this option.\n"); continue; } nIter = temp; break; //YIELD case 'y': opt_yield = 1; setName(&name); break; //SYNC case 's': if(setSyncType(optarg) != 0){ fprintf(stderr, "Not a valid sync argument. Skipping this option.\n"); } setName(&name); break; //UNRECOGNIZED OPTION (DEFAULT) default: fprintf(stderr, "%s is not an option. Skipping this option.\n", argv[optind - 1]); continue; } } //Allocate appropriate amount of memory for the thread ID container thArr = (pthread_t*) malloc(nThreads * sizeof(pthread_t)); if(thArr == NULL){ fprintf(stderr,"Could not allocate memory for thread ID.\n"); exit(1); } //set the arguments to pass for each thread args.pointer = &count; args.nIter = nIter; //get the initial time, check for error if(clock_gettime(CLOCK_REALTIME, &start)){ fprintf(stderr, "Failed to obtain starting time.\n"); exit(1); } //start threading int i; for(i = 0; i < nThreads; i++){ if(pthread_create(&(thArr[i]), NULL, doNone, (void*) &args)){ fprintf(stderr, "pthread_create() error\n"); exit(1); } } //join threads int j; for(j =0; j < nThreads; j++){ if(pthread_join(thArr[j], NULL)){ fprintf(stderr, "pthread_join() error\n"); exit(1); } } //take end time if(clock_gettime(CLOCK_REALTIME, &end)){ fprintf(stderr, "Failed to obtain ending time.\n"); exit(1); } //calculate the numbers to output int ops = nThreads * nIter * 2; long long sec = (long long) (end.tv_sec - start.tv_sec); long long nsec = (long long) (end.tv_nsec - start.tv_nsec); long long result = sec * 1000000000 + nsec; double tpo = (double) (result / ops) + ((result % ops) / (double) ops); //output as csv printf("%s,%d,%d,%d,%ld,%f,%ld\n", name, nThreads, nIter, ops, result, tpo, count); //free memory free(thArr); }
HistoryKeeper::HistoryKeeper(GenericDdInterface *db_) : db(db_) { /* DB format chats: * name -> id map id -- auto-incrementing number name -- chat's name (for user to user conversation it is opposite user public key) ctype -- chat type, reserved for group chats aliases: * user_id -> id map id -- auto-incrementing number user_id -- user's public key av_hash -- hash of user's avatar avatar -- user's avatar history: id -- auto-incrementing number timestamp chat_id -- current chat ID (resolves from chats table) sender -- sender's ID (resolves from aliases table) message alias -- sender's alias in */ // for old tables: QSqlQuery ans = db->exec("SELECT seq FROM sqlite_sequence WHERE name=\"history\";"); if (ans.first()) { int idMax = ans.value(0).toInt(); QSqlQuery ret = db->exec("SELECT seq FROM sqlite_sequence WHERE name=\"sent_status\";"); int idCur = 0; if (ret.first()) idCur = ret.value(0).toInt(); if (idCur != idMax) { QString cmd = QString("INSERT INTO sent_status (id, status) VALUES (%1, 1);").arg(idMax); db->exec(cmd); } } //check table stuct ans = db->exec("PRAGMA table_info (\"history\")"); ans.seek(5); if (!ans.value(1).toString().contains("alias")) { //add collum in table db->exec("ALTER TABLE history ADD COLUMN alias TEXT"); qDebug() << "Struct DB updated: Added column alias in table history."; } ans.clear(); ans = db->exec("PRAGMA table_info('aliases')"); ans.seek(2); if (!ans.value(1).toString().contains("av_hash")) { //add collum in table db->exec("ALTER TABLE aliases ADD COLUMN av_hash BLOB"); qDebug() << "Struct DB updated: Added column av_hash in table aliases."; } ans.seek(3); if (!ans.value(1).toString().contains("avatar")) { //add collum in table needImport = true; db->exec("ALTER TABLE aliases ADD COLUMN avatar BLOB"); qDebug() << "Struct DB updated: Added column avatar in table aliases."; } updateChatsID(); updateAliases(); setSyncType(Settings::getInstance().getDbSyncType()); messageID = 0; QSqlQuery sqlAnswer = db->exec("SELECT seq FROM sqlite_sequence WHERE name=\"history\";"); if (sqlAnswer.first()) messageID = sqlAnswer.value(0).toLongLong(); }