bool engine::find(const char *keytok) { ham_u32_t numkey=0; ham_key_t key; ham_record_t rec[2]; ham_status_t st[2]; VERBOSE(("find: key: %s\n", keytok)); memset(&key, 0, sizeof(key)); memset(&rec[0], 0, sizeof(rec[0])); memset(&rec[1], 0, sizeof(rec[1])); /* * check flag NUMERIC_KEY */ if (m_config->numeric) { numkey=strtoul(keytok, 0, 0); if (!numkey) { TRACE(("line %d: key is invalid\n", m_parser->get_lineno())); return (false); } numkey=ham_h2db32(numkey); key.data=(void *)&numkey; key.size=sizeof(numkey); } else { key.data=(void *)keytok; key.size=(ham_size_t)strlen(keytok); } for (int i=0; i<2; i++) { st[i]=m_db[i]->find(&key, &rec[i]); if (st[i]) VERBOSE(("db[%d]: find failed w/ status %d\n", i, st[i])); } if (!compare_records(&rec[0], &rec[1])) { TRACE(("record mismatch\n")); return false; } if (!compare_status(st)) return (false); if (m_config->txn_group>0) return (inc_opcount()); return (true); }
static gint compare(gint sort_method, gboolean reverse, PurpleBlistNode *node1, PurpleBlistNode *node2) { gint ret = 0; switch(sort_method) { case SORT_METHOD_NOTHING: ret = compare_nothing(node1, node2); break; case SORT_METHOD_NAME: ret = compare_name(node1, node2); break; case SORT_METHOD_LAST_NAME: ret = compare_last_name(node1, node2); break; case SORT_METHOD_STATUS: ret = compare_status(node1, node2); break; case SORT_METHOD_ONOFFLINE: ret = compare_onoffline(node1, node2); break; case SORT_METHOD_PROTOCOL: ret = compare_protocol(node1, node2); break; case SORT_METHOD_PRIORITY: ret = compare_priority(node1, node2); break; case SORT_METHOD_ONOFFLINETIME: ret = compare_onofflinetime(node1, node2); break; case SORT_METHOD_LOGSIZE: ret = compare_logsize(node1, node2); break; case SORT_METHOD_ACCOUNT: ret = compare_account(node1, node2); break; } if(reverse) { ret *= (-1); } return ret; }
/** * coffman_algorithm * * Función principal para calcular el algoritmo de * coffman sobre las matrices A y M y el vector RE * El funcionamiento está explicando en la implementación */ void coffman_algorithm(COFFMAN_DATA* data, FILE* target) { // primero necesitamos calcular RA int i,j; // shorcuts int p = data->num_proccess; int r = data->num_resources; // vector RA inicial que necesitamos int RA[r]; // vector RD (alias X), que iremos actualizando // conforme progrese el algoritmo, necesitamos // una copia puesto que sólo tenemos que actualizarlo // en una iteración de todos los procesos sin marcar // y vamos a usar el vector para comprobar ciertas condiciones int RD[r]; int RD_copy[r]; // procesos marcados, también necesitamos una copia // puesto que necesitamos comprobar a posteriori (una vez marcados) // si coincide con el estado anterior, y si es el mismo estamos // ante un interbloqueo int marked[p]; int marked_copy[p]; int previous=-1; int all_marked = 0, deadlock = 0; // inicializamos los vectores init_vector(RA, r); init_vector(RD, r); init_vector(marked, p); // calculamos el vector RA sumando // las filas de la matriz A for(i=0; i<p; i++) { for(j=0; j<r; j++) { RA[j] += data->A[i][j]; } } // calculamos RD(X) restando a RE-A for(i=0; i<r; i++) { RD[i] = data->RE[i] - RA[i]; } fprintf(target, COFFMAN_RD); print_vector(RD, r, target); fprintf(target, EOL); fprintf(target, COFFMAN_INIT_X); print_vector(RD, r, target); fprintf(target, EOL); // ver si hay algun proceso para marcar en A for(i=0; i<p; i++) { // recorremos las columnas for(j=0; j<r; j++) { previous = data->A[i][j]; // si algún elemento no es 0, salimos if(data->A[i][j] != 0) break; } // no ha habido elementos distintos de 0 // el proceso se marca para no procesarlo if(previous == 0) { marked[i] = 1; fprintf(target, COFFMAN_INIT_MARK, i+1); } } // hacemos un bucle infinito, hasta que encontremos // un interbloqueo o todos los procesos se marquen for(;;) { // comprobamos si ya están todos marcados if(all_proccess_marked(marked, p)) { all_marked = 1; break; } fprintf(target, COFFMAN_WITHOUT_MARK); without_mark(marked, p, target); fprintf(target, EOL); fprintf(target, EOL); // hacemos las copias de marked y RD, puesto que // usaremos esto para comprobar el estado interno copy_vector(marked_copy, marked, p); copy_vector(RD_copy, RD, p); // un bloque por procesos, solo cogiendo aquellos sin marcar for(i=0; i<p; i++) { // proceso no marcado, comprobamos ciertas cosas if(!marked[i]) { // si la comparación es 0, necesitamos marcar el proceso // y actualizar el vector RD, pero usamos RD_copy para los // otros procesos de esta interación if(compare_resource_vector(data->M[i], RD_copy, r)) { fprintf(target, COFFMAN_PROCCESS_AGAIN, i+1); // se marca el proceso marked[i] = 1; // actualizamos los recoursos en RD for(j=0; j<r; j++) { RD[j] += data->A[i][j]; } fprintf(target, COFFMAN_X); print_vector(RD, r, target); fprintf(target, EOL); } } } // si despues del algoritmo los procesos marcados // son iguales a los de la fase anterior, deadlock if(compare_status(marked, marked_copy, p) == 1) { deadlock = 1; break; } } fprintf(target, EOL); // todos los procesos marcados if(all_marked) fprintf(target, COFFMAN_NOT_DEADLOCK); // hemos llegado a un interbloqueo if(deadlock) { fprintf(target, COFFMAN_DEADLOCK); without_mark(marked, p, target); } }
bool engine::insert(const char *keytok, const char *data) { ham_u32_t numkey=0; ham_size_t data_size; ham_key_t key; ham_record_t rec; ham_status_t st[2]; VERBOSE(("insert: key: %s, data: %s\n", keytok, data)); memset(&key, 0, sizeof(key)); memset(&rec, 0, sizeof(rec)); /* * check flag NUMERIC_KEY */ if (m_config->numeric) { numkey=strtoul(keytok, 0, 0); if (!numkey) { TRACE(("line %d: key is invalid\n", m_parser->get_lineno())); return (false); } numkey=ham_h2db32(numkey); key.data=(void *)&numkey; key.size=sizeof(numkey); } else { key.data=(void *)keytok; key.size=(ham_size_t)strlen(keytok)+1; } /* * allocate and initialize data */ data_size=strtoul(data, 0, 0); if (data_size) { if (data_size>m_config->data_size) { m_config->data_size=data_size; m_config->data_ptr=realloc(m_config->data_ptr, data_size); if (!m_config->data_ptr) { TRACE(("line %d: out of memory\n", m_parser->get_lineno())); return 0; } } /* always start with a random number - otherwise berkeleydb fails * too often when duplicate keys are inserted with duplicate * records */ for (ham_size_t i=0; i<data_size; i++) ((char *)m_config->data_ptr)[i]=(m_parser->get_lineno()+i)&0xff; if (data_size>=sizeof(unsigned)) *(unsigned *)m_config->data_ptr=m_parser->get_lineno(); rec.data=m_config->data_ptr; rec.size=data_size; } for (int i=0; i<2; i++) { st[i]=m_db[i]->insert(&key, &rec); if (st[i]) VERBOSE(("db[%d]: insert failed w/ status %d\n", i, st[i])); } if (!compare_status(st)) return (false); if (m_config->txn_group>0) return (inc_opcount()); return (true); }
bool engine::fullcheck(void) { ham_key_t key[2]; ham_record_t rec[2]; void *c[2]; ham_status_t st[2]; st[0]=m_db[0]->check_integrity(); st[1]=m_db[1]->check_integrity(); if (!compare_status(st)) return false; c[0]=m_db[0]->create_cursor(); c[1]=m_db[1]->create_cursor(); for(;;) { memset(key, 0, sizeof(key)); memset(rec, 0, sizeof(rec)); if (m_config->puseralloc) { key[0].data=m_config->puseralloc; key[0].flags=HAM_KEY_USER_ALLOC; /* keysize is a 16-bit value! */ assert(USER_MALLOC_KEYRECSIZE > 65530); key[0].size=65530; rec[0].data = static_cast<char *>(m_config->puseralloc) + 65530; rec[0].size = USER_MALLOC_KEYRECSIZE - 65530; rec[0].flags=HAM_RECORD_USER_ALLOC; } /* first: berkeley db */ if (m_config->fullcheck_find) { st[1]=m_db[1]->get_next(c[1], &key[1], &rec[1], HAM_SKIP_DUPLICATES); } else if (m_config->fullcheck_backwards) { st[1]=m_db[1]->get_previous(c[1], &key[1], &rec[1], 0); } else { st[1]=m_db[1]->get_next(c[1], &key[1], &rec[1], 0); } /* then: hamster db */ if (m_config->fullcheck_find) { /* * different behaviour for BDB and hamsterdb: * * since BDB is used in this mode to fetch keys from its database * and hamsterdb can only /look/ for keys, it's no use feeding * hamsterdb an (illegal) key to look for when BDB didn't deliver * one. * * This mode does NOT discover keys lurking in the hamsterdb * database which are NOT in the BDB database. Use regular * fullcheck or fullcheck-backwards to cover that sort of thing. */ if (st[1]==HAM_KEY_NOT_FOUND) st[0]=st[1]; else st[0]=m_db[0]->find(&key[1], &rec[0]); /* !! */ } else if (m_config->fullcheck_backwards) st[0]=m_db[0]->get_previous(c[0], &key[0], &rec[0], 0); else st[0]=m_db[0]->get_next(c[0], &key[0], &rec[0], 0); if (m_config->verbose>1) { if (m_config->numeric) printf("fullcheck: %d/%d, keys %d/%d, blob size %d/%d\n", st[0], st[1], key[0].data ? *(int *)key[0].data : 0, key[1].data ? *(int *)key[1].data : 0, rec[0].size, rec[1].size); else printf("fullcheck: %d/%d, keys %s/%s, blob size %d/%d\n", st[0], st[1], key[0].data ? (char *)key[0].data : "(null)", key[1].data ? (char *)key[1].data : "(null)", rec[0].size, rec[1].size); } /* if (key[0].data && *(unsigned *)key[0].data==12 && rec[0].size==835) { printf("hit\n"); } */ if (!compare_status(st)) return false; if (st[0]!=0) break; if (!compare_records(&rec[0], &rec[1])) { TRACE(("record mismatch\n")); return false; } } m_db[0]->close_cursor(c[0]); m_db[1]->close_cursor(c[1]); return (true); }