static void transact_command(ostream &out, istream &in) { int choice ; int transaction ; int result ; do { choice = display_menu(out,in,true,3, "Transactions", "\t1. Start a transaction\n" "\t2. End a transaction\n" "\t3. Abort a transaction\n" ) ; switch (choice) { case 0: // do nothing break ; case 1: transaction = start_transaction() ; if (transaction == -1) out << "Unable to start transaction" << endl ; else out << "Started transaction number " << transaction << endl ; break ; case 2: transaction = get_number(out,in,"Transaction number:",-1, SHRT_MAX) ; result = end_transaction(transaction) ; if (result == -1) out << "Failed while ending transaction, error code = " << Fr_errno << endl ; else out << "Transaction ended successfully" << endl ; break ; case 3: transaction = get_number(out,in,"Transaction number:",-1, SHRT_MAX) ; result = abort_transaction(transaction) ; if (result == -1) { out << "Failed while aborting transaction, error code = " << Fr_errno << endl ; } else out << "Transaction successfully rolled back" << endl ; break ; default: FrMissedCase("transact_command") ; break ; } } while (choice != 0) ; return ; }
static void lock_command(ostream &out, istream &in) { int choice ; FrSymbol *name ; do { choice = display_menu(out,in,true,2, "FrFrame Locking", "\t1. Lock FrFrame\n" "\t2. Unlock FrFrame\n" ) ; if (choice != 0) name = get_symbol(out,in,"FrFrame name:") ; else name = 0 ; // avoid "uninit var" warning switch (choice) { case 0: // do nothing break ; case 1: if (name->isLocked()) out << "The frame was already locked." << endl ; else { name->lockFrame() ; out << "The frame was not yet locked, and is " ; if (name->isLocked()) out << "now locked." << endl ; else out << "STILL NOT locked." << endl ; } break ; case 2: if (!frame_locked(name)) out << "The frame was not locked." << endl ; else { unlock_frame(name) ; out << "The frame was locked, and is " ; if (frame_locked(name)) out << "STILL locked." << endl ; else out << "now unlocked." << endl ; } break ; default: FrMissedCase("lock_command") ; break ; } } while (choice != 0) ; return ; }
static void symtab_menu(ostream &out, istream &in) { int choice ; static FrList *symtabs = 0 ; FrCons *newtab ; FrSymbolTable *old_symtab = FrSymbolTable::current() ; do { FrSymbolTable::selectDefault() ; // read into default symbol table choice = display_menu(out,in,true,5, "FrSymbol Table Options:", "\t1. Select default symbol table\n" "\t2. Create a new symbol table\n" "\t3. FrList symbol tables\n" "\t4. Select symbol table by name\n" "\t5. Destroy a symbol table\n" ) ; old_symtab->select() ; // restore symbol table after reading input switch (choice) { case 0: // do nothing break ; case 1: FrSymbolTable::selectDefault() ; break ; case 2: newtab = symtab_create(in,symtabs) ; if (newtab) pushlist(newtab,symtabs) ; break ; case 3: out << "\nCurrent symbol tables: (default)" ; FrList *sym ; for (sym = symtabs ; sym ; sym = sym->rest()) out << ", " << sym->car()->car() ; out << endl << endl ; break ; case 4: old_symtab = symtab_select(in,symtabs) ; break ; case 5: symtabs = symtab_delete(in,symtabs) ; break ; default: FrMissedCase("symtab_menu") ; break ; } } while (choice != 0) ; old_symtab->select() ; return ; }
static void demons_command(ostream &, istream &) { int choice ; static bool DemonsInstalled = false ; FrSymbol *symbolISA = FrSymbolTable::add("IS-A") ; do { choice = display_menu(cout,cin,true,2, "Demons", "\t1. Install monitoring demons\n" "\t2. Remove monitoring demons\n" ) ; switch (choice) { case 0: // do nothing break ; case 1: if (!DemonsInstalled) { add_demon(symbolISA,DT_IfCreated,monitor_create,0) ; add_demon(symbolISA,DT_IfAdded,monitor_add,0) ; add_demon(symbolISA,DT_IfRetrieved,monitor_get,0) ; add_demon(symbolISA,DT_IfMissing,monitor_inherit,0) ; add_demon(symbolISA,DT_IfDeleted,monitor_delete,0) ; cout << "Demons installed" << endl ; DemonsInstalled = true ; } break ; case 2: if (DemonsInstalled) { remove_demon(symbolISA,DT_IfCreated,monitor_create) ; remove_demon(symbolISA,DT_IfAdded,monitor_add) ; remove_demon(symbolISA,DT_IfRetrieved,monitor_get) ; remove_demon(symbolISA,DT_IfMissing,monitor_inherit) ; remove_demon(symbolISA,DT_IfDeleted,monitor_delete) ; cout << "Demons removed" << endl ; DemonsInstalled = false ; } break ; default: FrMissedCase("demons_menu") ; break ; } } while (choice != 0) ; return ; }
double combine_values(double val1, double val2, FrTextSpan_Operation op) { switch (op) { case FrTSOp_None: // do nothing, keep original value return val1 ; case FrTSOp_Default: case FrTSOp_Add: return val1 + val2 ; case FrTSOp_Max: return (val1 > val2) ? val1 : val2 ; case FrTSOp_Min: return (val1 < val2) ? val1 : val2 ; case FrTSOp_Product: return val1 * val2 ; case FrTSOp_Average: return (val1 + val2) / 2.0 ; default: FrMissedCase("combine_values") ; return val1 ; } }
static double update_value(FrTextSpan_Operation op, double oldval, double update) { switch (op) { case FrTSOp_Default: case FrTSOp_None: return oldval ; case FrTSOp_Add: return oldval + update ; case FrTSOp_Product: return oldval * update ; case FrTSOp_Min: return (oldval < update) ? oldval : update ; case FrTSOp_Max: return (oldval > update) ? oldval : update ; case FrTSOp_Average: return (oldval + update) / 2 ; default: FrMissedCase("update_value(FrTextSpan_Operation)") ; } return oldval ; }
static void hash_test(FrThreadPool *user_pool, ostream &out, size_t threads, size_t cycles, HashT *ht, size_t maxsize, KeyT *syms, enum Operation op, bool terse, bool strict = true, uint32_t *randnums = 0) { FrThreadPool *tpool = user_pool ? user_pool : new FrThreadPool(threads) ; bool must_wait = (threads != 0) ; if (threads == 0) threads = 1 ; HashRequestOrder *hashorders = FrNewC(HashRequestOrder,threads) ; //out << " Dispatching threads" << endl ; size_t slice_size = (maxsize + threads/2) / threads ; if (ht) { ht->clearGlobalStats() ; ht->clearPerThreadStats() ; } FrElapsedTimer etimer ; FrTimer timer ; for (size_t i = 0 ; i < threads ; ++i) { hashorders[i].op = op ; hashorders[i].size = maxsize ; hashorders[i].ht = (void*)ht ; hashorders[i].syms = (FrSymbol**)syms ; hashorders[i].randnums = randnums ; hashorders[i].strict = strict ; hashorders[i].m_verbose = false ; hashorders[i].m_terse = terse ; hashorders[i].cycles = cycles ; hashorders[i].id = i+1 ; hashorders[i].threads = threads ; hashorders[i].pool = tpool ; hashorders[i].slice_start = i * slice_size ; hashorders[i].slice_size = (i+1 < threads) ? slice_size : (maxsize - hashorders[i].slice_start) ; hashorders[i].extra_arg = 0 ; hashorders[i].total_ops = 0 ; switch (op) { case Op_GENSYM: hashorders[i].func = hash_gensym ; break ; case Op_ADD: hashorders[i].func = hash_add<HashT,KeyT> ; break ; case Op_CHECK: hashorders[i].func = hash_check<HashT,KeyT> ; break ; case Op_CHECKMISS: hashorders[i].func = hash_check<HashT,KeyT> ; hashorders[i].extra_arg = 1 ; break ; case Op_CHECKSYMS: hashorders[i].func = hash_checksyms<HashT,KeyT> ; break ; case Op_REMOVE: hashorders[i].func = hash_remove<HashT,KeyT> ; break ; case Op_RANDOM: hashorders[i].func = hash_random<HashT,KeyT> ; hashorders[i].extra_arg = 3 ; break ; case Op_RANDOM_LOWREMOVE: hashorders[i].func = hash_random<HashT,KeyT> ; hashorders[i].extra_arg = 1 ; break ; case Op_RANDOM_HIGHREMOVE: hashorders[i].func = hash_random<HashT,KeyT> ; hashorders[i].extra_arg = 7 ; break ; case Op_RANDOM_NOREMOVE: hashorders[i].func = hash_random<HashT,KeyT> ; break ; case Op_RANDOM_ADDONLY: hashorders[i].func = hash_random_add<HashT,KeyT> ; break ; default: FrMissedCase("hash_test") ; } tpool->dispatch(&hash_dispatch<HashT>,&hashorders[i],0) ; } if (must_wait) { if (!terse) out << " Waiting for thread completion" << endl ; tpool->waitUntilIdle() ; } double walltime_noreclaim = etimer.read() ; if (ht && op == Op_REMOVE) { ht->reclaimDeletions() ; ht->updateGlobalStats() ; } double time = timer.readsec() ; double walltime = etimer.stop() ; if (!user_pool) delete tpool ; size_t ops = cycles * maxsize ; if (op == Op_RANDOM || op == Op_RANDOM_LOWREMOVE || op == Op_RANDOM_HIGHREMOVE || op == Op_RANDOM_NOREMOVE) { // sum up the per-thread counts of operations performed ops = 0 ; for (size_t i = 0 ; i < threads ; ++i) { FrCriticalSection::increment(ops,hashorders[i].total_ops) ; } } FrFree(hashorders) ; walltime = (round(10000*walltime)/10000) ; if (time <= 0.0) time = 0.00001 ; if (walltime <= 0.0) walltime = 0.00001 ; out << " Time: " << walltime << "s, " << time << "s CPU (" << 100.0*(time/walltime) << "%), " ; pretty_print((size_t)(ops / walltime),out) ; out << " ops/sec" << endl ; if (op == Op_REMOVE) { out << " RwTm: " << walltime_noreclaim << "s without reclamation (" ; pretty_print((size_t)(ops / walltime_noreclaim),out) ; out << " ops/sec)" << endl ; } // verify success size_t size = ht ? ht->currentSize() : 0 ; size_t count = ht ? ht->countItems() : 0 ; size_t deleted = ht ? ht->countDeletedItems() : 0 ; if (size != count) { out << "'size' and 'count' disagree! " << size << " vs " << count << endl ; } if (op == Op_ADD) { if (size > maxsize) out << " " << (size-maxsize) << "spurious additions to hash table!" << endl ; else if (size< maxsize) out << " Failed to add " << (maxsize-size) << " items to hash table!" << endl ; } if (op == Op_REMOVE || op == Op_RANDOM) { if (deleted > 0) { if (ht) ht->reclaimDeletions() ; out << " Pending deletions: " << deleted << " marked for deletion, " << (ht ? ht->countDeletedItems() : 0) << " after reclamation" << endl ; } } if (op == Op_REMOVE) { if (size != 0) out << " Hash table was not emptied! " << size << " items remain (activeitems=" << count << ")." << endl ; } if (!ht) return ; #ifdef FrHASHTABLE_STATS size_t stat_ins = ht->numberOfInsertions() ; size_t stat_ins_dup = ht->numberOfDupInsertions() ; size_t stat_ins_att = ht->numberOfInsertionAttempts() ; size_t stat_ins_forw = ht->numberOfForwardedInsertions() ; size_t stat_ins_resize = ht->numberOfResizeInsertions() ; size_t stat_cont = ht->numberOfContainsCalls() ; size_t stat_cont_succ = ht->numberOfSuccessfulContains() ; size_t stat_cont_forw = ht->numberOfForwardedContains() ; size_t stat_lookup = ht->numberOfLookups() ; size_t stat_lookup_succ = ht->numberOfSuccessfulLookups() ; size_t stat_lookup_forw = ht->numberOfForwardedLookups() ; size_t stat_rem = ht->numberOfRemovals() ; size_t stat_rem_count = ht->numberOfItemsRemoved() ; size_t stat_rem_forw = ht->numberOfForwardedRemovals() ; size_t stat_resize = ht->numberOfResizes() ; size_t stat_resize_assist = ht->numberOfResizeAssists() ; size_t stat_reclam = ht->numberOfReclamations() ; size_t stat_moves = ht->numberOfEntriesMoved() ; size_t stat_full = ht->numberOfFullNeighborhoods() ; size_t stat_chain = ht->numberOfChainLocks() ; size_t stat_chain_coll = ht->numberOfChainLockCollisions() ; size_t retries = (stat_ins_att >= stat_ins - stat_ins_dup) ? stat_ins_att - (stat_ins - stat_ins_dup) : 0 ; out << " Stat: " << (stat_ins-stat_ins_forw) << "+" << stat_ins_forw << " ins (" << stat_ins_dup << " dup, " << retries << " retry, " << stat_ins_resize << " resz), " << stat_cont_succ << '/' << stat_cont << '+' << stat_cont_forw << " cont, " << stat_lookup_succ << '/' << stat_lookup << '+' << stat_lookup_forw << " look, " << stat_rem_count << '/' << stat_rem << '+' << stat_rem_forw << " rem" << endl ; out << " Admn: " << stat_resize << " resizes (" << stat_resize_assist << " assists), " << stat_full << " congest, " << stat_reclam << " reclam, " << stat_moves << " moves, " << stat_chain_coll << '/' << stat_chain << " chainlock" << endl ; #ifdef FrMULTITHREAD size_t stat_spin = ht->numberOfSpins() ; size_t stat_yield = ht->numberOfYields() ; size_t stat_sleep = ht->numberOfSleeps() ; size_t stat_CAS = ht->numberOfCASCollisions() ; size_t stat_resize_cleanup = ht->numberOfResizeCleanups() ; out << " Thrd: " << stat_spin << " spins, " << stat_yield << " yields, " << stat_sleep << " sleeps, " << stat_CAS << " CAS, " << stat_resize_cleanup << " resize cleanups" << endl ; #endif /* FrMULTITHREAD */ #endif /* FrHASHTABLE_STATS */ return ; }
double FrVectorSimilarity(FrClusteringMeasure sim, const double *vec1, const double *vec2, size_t veclen, bool normalize) { if (veclen == 0) return 1.0 ; // empty vectors are always identical if (!vec1 || !vec2) return -1.0 ; // maximum diff if vector missing switch (sim) { case FrCM_COSINE: return cosine_similarity(vec1,vec2,veclen,normalize) ; case FrCM_EUCLIDEAN: return 1.0 - euclidean_distance(vec1,vec2,veclen,normalize) ; case FrCM_MANHATTAN: return 1.0 - manhattan_distance(vec1,vec2,veclen,normalize) ; case FrCM_JACCARD: return jaccard_coefficient(vec1,vec2,veclen) ; case FrCM_SIMPSON: return simpson_coefficient(vec1,vec2,veclen) ; case FrCM_EXTSIMPSON: return extended_simpson_coefficient(vec1,vec2,veclen,normalize) ; case FrCM_DICE: return dice_coefficient(vec1,vec2,veclen,normalize) ; case FrCM_ANTIDICE: return antidice_coefficient(vec1,vec2,veclen,normalize) ; case FrCM_TANIMOTO: return tanimoto_coefficient(vec1,vec2,veclen,normalize) ; case FrCM_BRAUN_BLANQUET: return braun_blanquet_coefficient(vec1,vec2,veclen,normalize) ; case FrCM_KULCZYNSKI1: return kulczynski_measure1(vec1,vec2,veclen,normalize) ; case FrCM_KULCZYNSKI2: return kulczynski_measure2(vec1,vec2,veclen,normalize) ; case FrCM_OCHIAI: return ochiai_measure(vec1,vec2,veclen,normalize) ; case FrCM_SOKALSNEATH: return sokal_sneath_measure(vec1,vec2,veclen,normalize) ; case FrCM_MCCONNAUGHEY: // mcConnaughey_measure() return is in range -1.0...+1.0 return (mcConnaughey_measure(vec1,vec2,veclen,normalize)+1.0) / 2.0 ; case FrCM_LANCEWILLIAMS: return 1.0 - lance_williams_distance(vec1,vec2,veclen,normalize) ; case FrCM_BRAYCURTIS: return bray_curtis_measure(vec1,vec2,veclen,normalize) ; case FrCM_CANBERRA: return 1.0 - canberra_measure(vec1,vec2,veclen,normalize) ; case FrCM_CIRCLEPROD: return circle_product(vec1,vec2,veclen,normalize) / veclen ; case FrCM_CZEKANOWSKI: return czekanowski_measure(vec1,vec2,veclen,normalize) ; case FrCM_ROBINSON: return robinson_coefficient(vec1,vec2,veclen,normalize) / 2.0 ; case FrCM_DRENNAN: return 1.0 - drennan_dissimilarity(vec1,vec2,veclen,normalize) ; case FrCM_SIMILARITYRATIO: return similarity_ratio(vec1,vec2,veclen,normalize) ; case FrCM_JENSENSHANNON: return 1.0 - jensen_shannon_divergence(vec1,vec2,veclen,normalize) ; case FrCM_MOUNTFORD: return mountford_coefficient(vec1,vec2,veclen) ; case FrCM_FAGER_MCGOWAN: return fager_mcgowan_coefficient(vec1,vec2,veclen) ; case FrCM_TRIPARTITE: return tripartite_similarity_index(vec1,vec2,veclen) ; case FrCM_BIN_DICE: return binary_dice_coefficient(vec1,vec2,veclen) ; case FrCM_BIN_ANTIDICE: return binary_antidice_coefficient(vec1,vec2,veclen) ; case FrCM_BIN_GAMMA: return binary_gamma_coefficient(vec1,vec2,veclen) ; case FrCM_NONE: return 0.0 ; default: FrMissedCase("FrVectorSimilarity()") ; return 0.0 ; } }
static const char *re_match(const FrRegExElt *re, const char *candidate, size_t min_reps, size_t &max_reps, char *&match, const char *matchbuf_end, char **groups, size_t num_groups) { assertq(re != 0 && match != 0 && matchbuf_end != 0) ; switch (re->reType()) { case FrRegExElt::End: // match end of word if (*candidate) { max_reps = 0 ; // uh oh, not at end of word.... return 0 ; } else { max_reps = 1 ; return candidate ; } case FrRegExElt::Char: { char c = Fr_toupper(re->getChar()) ; size_t i ; for (i = 0 ; i < max_reps ; i++) { if (Fr_toupper(*candidate) != c) break ; if (match < matchbuf_end) *match++ = *candidate ; candidate++ ; } max_reps = i ; if (i >= min_reps ) return candidate ; else return 0 ; } case FrRegExElt::CharSet: { const char *set = re->getCharSet() ; if (!set) { max_reps = 0 ; return 0 ; } size_t i ; for (i = 0 ; i < max_reps && *candidate ; i++) { if (!set[*(unsigned char*)candidate]) break ; if (match < matchbuf_end) *match++ = *candidate ; candidate++ ; } max_reps = i ; if (i >= min_reps) return candidate ; else return 0 ; } case FrRegExElt::String: { const char *string = re->getString() ; size_t len = re->stringLength() ; if (!string) { max_reps = 0 ; return 0 ; } size_t i ; for (i = 0 ; i < max_reps ; i++) { if (Fr_memicmp(candidate,string,len) != 0) break ; const char *tstr = string+len+1 ; size_t tlen = strlen(tstr) ; if (match+tlen < matchbuf_end) { memcpy(match,tstr,tlen) ; match += tlen ; } candidate += len ; } max_reps = i ; if (i >= min_reps) return candidate ; else return 0 ; } case FrRegExElt::Alt: { FrRegExElt **alts = re->getAlternatives() ; char *matchbuf = match ; const char *end = re_match_alt(alts,candidate,min_reps,max_reps, match,matchbuf_end,groups,num_groups) ; if (max_reps >= min_reps) { int group_num = re->groupNumber() ; if (end && group_num >= 0 && group_num < (int)num_groups) { // since the r.e. compiler ensures that only alternations can // be used for grouping, we can get away with only recording // groupings right here *match = '\0' ; FrFree(groups[group_num]) ; groups[group_num] = FrDupString(matchbuf) ; } return end ; } else return 0 ; } case FrRegExElt::Class: { const char *end = re_match_class(re,candidate,min_reps,max_reps, match,matchbuf_end,groups, num_groups) ; return (max_reps >= min_reps) ? end : 0 ; } case FrRegExElt::Accept: return strchr(candidate,'\0') ; default: max_reps = 0 ; FrMissedCase("re_match") ; return 0 ; } }