#include #include #include #include #include #include // #include #include "ultra.h" //////////////////////////////////////////////////////////////////////////// /////////////////////////// CONSTANTS & GLOBALS ///////////////////////////// ///////////////////////////////////////////////////////////////////////////// // const int SEQ_LEN_FACTOR = 2; const int N_PROPAGATION_NODES = 1; const int N_FILES_TO_PROPAGATE = 1; const int N_FILES_TO_ADD = 3; const int INITIAL_PRIORITY = 3; const double ALPHA = .8; const double BETA = .5; const double GAMMA = .1; const double DELTA = .9; // assert((BETA + GAMMA <= 1.)); const int FILE_CACHE_SIZE = 10; // ola ma psa // const int FILE_REFERENCE_CACHE_SIZE = 200; // * const int PEER_NEIGHBOR_CACHE_SIZE = 3; const int FILE_REFERENCE_CACHE_SIZE = 500; const int MIN_FILE_REFERENCE_CACHE_SIZE = FILE_REFERENCE_CACHE_SIZE / 2; const int MAX_FILE_REFERENCE_CACHE_SIZE = (int) (1.5 * FILE_REFERENCE_CACHE_SIZE); const int PEER_NEIGHBOR_CACHE_SIZE = 10; const int N_REPLACEMENTS = 10; const int SUPER_PEER_NEIGHBOR_CACHE_SIZE = 100; const double MIN_SUPER_PEER_DESIRED_LOAD = .25; // = 100000 / 500 - 100000 / (2 * 500); const double MAX_SUPER_PEER_DESIRED_LOAD = .75; // = 100000 / 500 + 100000 / (2 * 500); const int CACHE_SIZE_MODIFICATION_STEP = 5; // const int N_SEARCHES_PER_PHASE = 100000; const int N_PHASES = 1000; const int PROPAGATION_INVERSE_FREQUENCY = 1010; const int ADDITION_INVERSE_FREQUENCY = 1020; const int CACHE_CORRECTION_INVERSE_FREQUENCY = 1010; // 5; const int FAILURE_PHASE = 1500; const int PEER_JOINING_PHASE = 1050; const int N_JOINING_PHASES = 1000; const int N_JOINING_EVALUATION_PHASES = 10000; const int STATISTICS_RESET_PHASE = 1100; // 800; const int N_LOAD_CLASSES = 4; const int LOAD_STATISTICS_PRINT_INVERSE_FREQUENCY = 10; const int STATIC_MODE = 1; const int SIMPLE_MODE = 2; const int NORMAL_MODE = 3; const int ADVANCED_MODE = 4; const int FILES_NOT_FOUND = 0; // number of files that were not cached by // any of the super-peers; run dependent; // needed for the optimal cache hit ratio // estimation const int N_SAMPLINGS = 1000000; const int WINDOW_SIZE = 1000000; int execution_mode = ADVANCED_MODE; int current_time = 0; // TODO: Eliminate these variables const char *data_file_name; int n_files_found_locally; int n_files_found_remotely; int n_files_missed; int n_global_requests; int n_files_found_locally_load[N_LOAD_CLASSES]; int n_files_found_remotely_load[N_LOAD_CLASSES]; int n_files_missed_load[N_LOAD_CLASSES]; int *n_found_locally; int *n_found_remotely; int *n_missed; const int LRU_MODE = 1; const int LFU_MODE = 2; const int MIXED_MODE = 3; const int F_MODE = MIXED_MODE; const int U_MODE = LFU_MODE; /* inline int min(int a, int b) { return (a < b) ? a : b; }; inline double min(double a, double b) { return (a > b) ? b : a; }; inline int max(int a, int b) { return (a > b) ? a : b; }; */ Network *net = NULL; // to be eliminated Timer timer1, timer2, timer3, timer4, timer5; ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Timer /////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const Timer& t) { outs << "t[" << t.state << ", " << t.start_time.tv_sec << ":" << t.start_time.tv_usec << ", " << t.running_time.tv_sec << ":" << t.running_time.tv_usec << "]"; return outs; } Timer::Timer(void) { reset(); }; void Timer::substract(struct timeval& a, struct timeval& b) { // a -= b a.tv_sec -= b.tv_sec; a.tv_usec -= b.tv_usec; if (a.tv_usec < 0) { a.tv_sec--; a.tv_usec += 1000000; } } void Timer::add(struct timeval& a, struct timeval& b) { // a += b a.tv_sec += b.tv_sec; a.tv_usec += b.tv_usec; if (a.tv_usec >= 1000000) { a.tv_sec++; a.tv_usec -= 1000000; } } void Timer::reset(void) { state = STOPPED_STATE; running_time.tv_sec = 0; running_time.tv_usec = 0; }; void Timer::start(void) { // assert(state == STOPPED_STATE); gettimeofday(&start_time, NULL); state = RUNNING_STATE; }; void Timer::stop(void) { // assert(state == RUNNING_STATE); struct timeval tv; gettimeofday(&tv, NULL); substract(tv, start_time); add(running_time, tv); state = STOPPED_STATE; }; long Timer::getTime(void) { long microseconds; if (state == STOPPED_STATE) return (long) (running_time.tv_sec * 10e6l + running_time.tv_usec); else { // state == RUNNING_STATE struct timeval tv; gettimeofday(&tv, NULL); substract(tv, start_time); add(tv, running_time); return (long) (tv.tv_sec * 10e6l + tv.tv_usec); } }; ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Hash //////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const Hash& h) { outs << "h[" << h.hash << "]"; return outs; } Hash::Hash(int& i) { hash = i; }; Hash::Hash(FileReference& fr) : hash(fr.getFileId()) { }; Hash::Hash(Peer *&peer) : hash(peer->getId()) { }; int Hash::getHash() { return hash; } ///////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Utils /////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// int *Utils::resizeArray(int *data, int length, int new_length) { int *new_data = new int[new_length]; memcpy(new_data, data, sizeof(int) * min(length, new_length)); return new_data; } int *Utils::fillWithZeros(int *data, int start_index, int end_index) { for (int i = start_index; i < end_index + 1; i++) data[i] = 0; return data; } int Utils::min(int a, int b) { return (a < b) ? a : b; } int Utils::max(int a, int b) { return (a > b) ? a : b; } double Utils::min(double a, double b) { return (a < b) ? a : b; } double Utils::max(double a, double b) { return (a > b) ? a : b; } int Utils::binarySearch(int sortedArray[], int first, int last, int key) { // function: // Searches sortedArray[first]..sortedArray[last] for key. // returns: index of the matching element if it finds key, // otherwise -(index where it could be inserted)-1. // parameters: // sortedArray in array of sorted (ascending) values. // first, last in lower and upper subscript bounds // key in value to search for. // returns: // index of key, or -insertion_position -1 if key is not // in the array. This value can easily be // transformed into the position to insert it. while (first <= last) { int mid = (first + last) / 2; // compute mid point. if (key > sortedArray[mid]) first = mid + 1; // repeat search in top half. else if (key < sortedArray[mid]) last = mid - 1; // repeat search in bottom half. else return mid; // found it. return position ///// } return -(first + 1); // failed to find key } int Utils::binarySearch(double sortedArray[], int first, int last, double key) { // function: // Searches sortedArray[first]..sortedArray[last] for key. // returns: index of the matching element if it finds key, // otherwise -(index where it could be inserted)-1. // parameters: // sortedArray in array of sorted (ascending) values. // first, last in lower and upper subscript bounds // key in value to search for. // returns: // index of key, or -insertion_position -1 if key is not // in the array. This value can easily be // transformed into the position to insert it. while (first <= last) { int mid = (first + last) / 2; // compute mid point. if (key > sortedArray[mid]) first = mid + 1; // repeat search in top half. else if (key < sortedArray[mid]) last = mid - 1; // repeat search in bottom half. else return mid; // found it. return position ///// } return -(first + 1); // failed to find key } ///////////////////////////////////////////////////////////////////////////// /////////////////////////// RandomNumberGenerator /////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const RandomNumberGenerator& rng) { outs << "rng[" << rng.max << "]"; return outs; }; // RandomNumberGenerator::RandomNumberGenerator(int p_max) : max(p_max) { // }; int *RandomNumberGenerator::getSequence(int length) { int *seq = new int[length]; for (int i = 0; i < length; i++) { seq[i] = getNext(); // (int) floor(pow(10., expo)); } return seq; }; ///////////////////////////////////////////////////////////////////////////// /////////////////////////////// CyclicGenerator ///////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const CyclicGenerator& cg) { outs << "cg[" << cg.max << "]"; return outs; }; CyclicGenerator::CyclicGenerator(int p_max) : last(0) { max = p_max; // can not be intitialized in the header }; int CyclicGenerator::getNext() { int result = last + 1; last = (last + 1) % max; return result; // return random() % max + 1; }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////////// UniformGenerator ///////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const UniformGenerator& ug) { outs << "ug[" << ug.max << "]"; return outs; }; UniformGenerator::UniformGenerator(int p_max) { max = p_max; }; int UniformGenerator::getNext() { return 1 + (int) (1. * max * rand() / (RAND_MAX + 1.)); // return random() % max + 1; }; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////// PowerLawGenerator ///////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const PowerLawGenerator& plg) { outs << "ug[" << plg.max << "," << plg.p << "]"; return outs; }; PowerLawGenerator::PowerLawGenerator(int p_max, double p_p) : p(p_p) { max = p_max; }; int PowerLawGenerator::getNext() { double nexp = p + 1.; double norm = 1. / (pow((max + 1) * 1., nexp) - pow(1., nexp)); double r = (random() * 1.) / (RAND_MAX * 1.); double expo = log10(r / norm + pow(1., nexp)) / nexp; return (int) floor(pow(10., expo)); }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////////// ZipfLawGenerator ///////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const ZipfLawGenerator& zlg) { outs << "zlg[" << zlg.max << "]"; return outs; }; ZipfLawGenerator::ZipfLawGenerator(int p_max) { max = p_max; sum = 0.; for (int i = 1; i <= max; i++) sum += 1. / i; }; int ZipfLawGenerator::getNext() { double r = (sum * random() / RAND_MAX); double s = 0.; int i = 0; do { i++; s += 1. / i; } while (s < r); return i; }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////// ZipfLawCategoryGenerator ///////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const ZipfLawCategoryGenerator& zlcg) { outs << "zlcg[" << zlcg.max << "]"; return outs; }; int ZipfLawCategoryGenerator::getCategory() { double r = (sum * random() / RAND_MAX); double s = 0.; int i = 0; do { s += p_ns[i++]; } while (s < r); return i; }; ZipfLawCategoryGenerator::ZipfLawCategoryGenerator(int p_max, int category, int n_categories, double alpha) { max = p_max; category_sizes = new int[n_categories]; sum = .0; double dummy = .0; int i; int dummy_sum = 0; for (i = 1; i <= n_categories; i++) dummy += 1. / i; for (i = 1; i <= n_categories; i++) { category_sizes[i - 1] = (int) (((1. / i) / dummy) * max); if ((category_sizes[i - 1] == 0) && (dummy_sum != max)) category_sizes[i - 1] = 1; dummy_sum += category_sizes[i - 1]; } // cout << dummy_sum << " " << max << endl; if (dummy_sum != max) category_sizes[0] += max - dummy_sum; // for (i = 0; i < n_categories; i++) // cout << i + 1 << " " << category_sizes[i] << endl; p_ns = new double[n_categories]; category_sums = new double[n_categories]; for (i = 1; i <= n_categories; i++) { category_sums[i - 1] = .0; for (int j = 1; j <= category_sizes[i - 1]; j++) category_sums[i - 1] += 1. / j; if (i == category) p_ns[i - 1] = category_sums[i - 1] * alpha / category; else p_ns[i - 1] = category_sums[i - 1] * (1 - alpha) / (i * (n_categories - 1)); sum += p_ns[i - 1]; } }; ZipfLawCategoryGenerator::~ZipfLawCategoryGenerator() { delete [] p_ns; delete [] category_sizes; delete [] category_sums; }; int ZipfLawCategoryGenerator::getNext() { int category = getCategory(); int shift = 0; for (int j = 0; j < category - 1; j++) { shift += category_sizes[j]; // cout << shift << " " << category_sizes[j] << endl; } double r = (category_sums[category - 1] * random() / RAND_MAX); double s = 0.; int i = 0; int index = 0; do { i++; s += 1. / i; } while (s < r); return shift + i; }; ///////////////////////////////////////////////////////////////////////////// //////////////////// BalancedZipfLawCategoryGenerator /////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const BalancedZipfLawCategoryGenerator& bzlcg) { outs << "zlcg[" << bzlcg.max << "]"; return outs; }; int BalancedZipfLawCategoryGenerator::getCategory() { double r = (sum * random() / RAND_MAX); double s = 0.; int i = 0; do { s += p_ns[i++]; } while (s < r); return i; }; BalancedZipfLawCategoryGenerator::BalancedZipfLawCategoryGenerator(int p_max, int category, int n_categories, double alpha) { max = p_max; category_size = max / n_categories; rest = max - category_size * n_categories; int i; category_sum = 0.; sum = .0; p_ns = new double[n_categories]; for (i = 1; i <= category_size; i++) category_sum += 1. / i; for (i = 1; i <= n_categories; i++) { if (i == category) p_ns[i - 1] = alpha + (1 - alpha) / category; else p_ns[i - 1] = (1 - alpha) / i; sum += p_ns[i - 1]; } // cout << category_sum << " " << category_size << endl; }; BalancedZipfLawCategoryGenerator::~BalancedZipfLawCategoryGenerator() { delete [] p_ns; // delete [] category_sizes; }; int BalancedZipfLawCategoryGenerator::getNext() { int category = getCategory(); int shift = (category - 1) * category_size; double r; if (category > rest) r = category_sum * random() / RAND_MAX; else r = (category_sum + (1. / (category_size + 1.))) * random() / RAND_MAX; double s = 0.; int i = 0; int index = 0; do { i++; s += 1. / i; } while (s < r); // cout << "i == " << i << endl; return shift + i; }; ///////////////////////////////////////////////////////////////////////////// ////////////////////// FileDefinedCategoryGenerator ///////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const FileDefinedCategoryGenerator& fdcg) { outs << "fdcg[" << fdcg.max << "]"; return outs; }; int FileDefinedCategoryGenerator::getCategory(int category) { double r = 1. * random() / RAND_MAX; // cout << "1: r == " << r << " alpha == " << alpha << endl; if (r < alpha) return category; r = 1. * sum * random() / RAND_MAX; // cout << "2: r == " << r << " alpha == " << alpha << " sum == " << sum << endl; int s = 0; int i = 0; do { s += category_sums[i++]; } while (s < r); return i; }; FileDefinedCategoryGenerator::FileDefinedCategoryGenerator(double p_alpha, const char* file_name) : alpha(p_alpha) { ifstream input; // cout << "Zyje" << endl; // fflush(0); input.open(file_name, ios::in); if ((input.rdstate() & ifstream::failbit ) != 0) { cerr << "Error opening file: " << file_name << endl; return; } int max_categories = 2; int max_files = 2; int file_index = -1; int category_index; int prev_category_index = -1; int file_weight; sum = 0; category_sums = new int[max_categories]; category_heads = new int[max_categories]; file_weights = new int[max_files]; int *dummy; Utils::fillWithZeros(category_sums, 0, max_categories - 1); while (!input.eof()) { // read category input >> category_index; if (input.eof()) continue; if (category_index >= max_categories) { dummy = category_sums; category_sums = Utils::resizeArray(category_sums, max_categories, 2 * max_categories); delete [] dummy; dummy = category_heads; category_heads = Utils::resizeArray(category_heads, max_categories, 2 * max_categories); delete [] dummy; Utils::fillWithZeros(category_sums, max_categories, 2 * max_categories - 1); max_categories *= 2; } // read file weight file_weight = -1; input >> file_weight; file_index++; // cout << "read " << category_index << " " << file_index << " " << file_weight << endl; if (file_index == max_files) { dummy = file_weights; file_weights = Utils::resizeArray(file_weights, max_files, 2 * max_files); delete [] dummy; max_files *= 2; } file_weights[file_index] = file_weight; category_sums[category_index] += file_weight; if (prev_category_index != category_index) { category_heads[category_index] = file_index; prev_category_index = category_index; } sum += file_weight; } n_categories = category_index + 1; dummy = category_sums; category_sums = Utils::resizeArray(category_sums, max_categories, n_categories); delete [] dummy; dummy = category_heads; category_heads = Utils::resizeArray(category_heads, max_categories, n_categories); delete [] dummy; n_files = file_index + 1; dummy = file_weights; file_weights = Utils::resizeArray(file_weights, max_files, n_files); delete [] dummy; // delete [] file_weights; max = file_index + 1; int i; category_sums_partial_sums = new int[n_categories]; category_sums_partial_sums[0] = category_sums[0]; for (i = 1; i < n_categories; i++) category_sums_partial_sums[i] = category_sums_partial_sums[i - 1] + category_sums[i]; file_weights_partial_sums = new int[n_files]; file_weights_partial_sums[0] = file_weights[0]; int s = 0; int c = 0; for (i = 0; i < n_files; i++) { if (i == category_heads[c]) { s = 0; c++; } s = (file_weights_partial_sums[i] = s + file_weights[i]); } // cout << "category_index == " << category_index << " file_index == " << // file_index << " sum == " << sum << " alpha == " << alpha << endl; input.close(); }; FileDefinedCategoryGenerator::~FileDefinedCategoryGenerator() { delete [] category_sums; delete [] category_heads; delete [] file_weights; delete [] category_sums_partial_sums; delete [] file_weights_partial_sums; }; int FileDefinedCategoryGenerator::getNext() { int r = (int) (1. * sum * random() / RAND_MAX); int s = 0; /* int i = 0; do { s += category_sums[i++]; } while (s < r); */ int left = 0; int right = n_categories; int i = Utils::binarySearch(category_sums_partial_sums, left, right, r); if (i < 0) i *= -1; else i++; return i; }; int FileDefinedCategoryGenerator::getNext(int category) { // cout << "alpha == " << alpha << " sum == " << sum << endl; int selected_category = getCategory(category); // cout << "Zyje " << selected_category << endl; int r = (int) (1. * category_sums[selected_category - 1] * random() / RAND_MAX); // cout << "r == " << r << endl; /* int s = 0; int i = category_heads[selected_category - 1]; do { s += file_weights[i++]; // CHECK: is it OK? Shouldn't it be ++i?? } while (s < r); */ int left = category_heads[selected_category - 1]; int right; if (selected_category == n_categories) right = n_files - 1; else right = category_heads[selected_category]; int i = Utils::binarySearch(file_weights_partial_sums, left, right, r); if (i < 0) i *= -1; else i++; // cout << "i == " << i << endl; return i; }; inline int comp_nums(const double *num1, const double *num2) { if (*num1 < *num2) return 1; // normally should be -1 if (*num1 > *num2) return -1; // normally should be 1 return 0; }; double FileDefinedCategoryGenerator::getOptimalHitRatio(int n_files, int n_categories) { double hit_ratio = .0; double new_file_weights[n_files]; int i, j; for (i = 0; i < n_categories; i++) { double new_sum = .0; for (j = 0; j < n_files; j++) { if ((j >= category_heads[i]) && ((i == n_categories - 1) || (j < category_heads[i + 1]))) new_file_weights[j] = 1. * file_weights[j]; else new_file_weights[j] = (1. - alpha) * file_weights[j]; new_sum += new_file_weights[j]; } qsort(new_file_weights, n_files, sizeof(double), (int (*)(const void *, const void *)) comp_nums); // if (i == 1) // for (j = 0; j < n_files; j++) // cout << "aaala " << new_file_weights[j] << endl; double new_group_sum = .0; int cache_capacity_limit = 2 * FILE_REFERENCE_CACHE_SIZE * PEER_NEIGHBOR_CACHE_SIZE + FILE_CACHE_SIZE; for (j = 0; j < cache_capacity_limit; j++) new_group_sum += new_file_weights[j]; for (j = cache_capacity_limit; j < cache_capacity_limit + FILES_NOT_FOUND; j++) new_sum -= new_file_weights[j]; // new_sum = .0; // for (j = 0; j < n_files * .75; j++) // new_sum += new_file_weights[j]; hit_ratio += (1. * category_sums[i] / sum) * new_group_sum / new_sum; cout << i << " " << new_group_sum / new_sum << " " << hit_ratio << endl; } return hit_ratio; }; ///////////////////////////////////////////////////////////////////////////// ///////////////////// ZipfLawCategorySelectionGenerator ///////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const ZipfLawCategorySelectionGenerator& zlcsg) { outs << "zlcg[" << zlcsg.max << "]"; return outs; }; ZipfLawCategorySelectionGenerator::ZipfLawCategorySelectionGenerator(int p_max, int p_n_categories, double alpha) : n_categories(p_n_categories) { max = p_max; int *category_sizes = new int[n_categories]; double dummy = .0; int i, j; int dummy_sum = 0; for (i = 1; i <= n_categories; i++) dummy += 1. / i; for (i = 1; i <= n_categories; i++) { category_sizes[i - 1] = (int) (((1. / i) / dummy) * max); if ((category_sizes[i - 1] == 0) && (dummy_sum != max)) category_sizes[i - 1] = 1; dummy_sum += category_sizes[i - 1]; } // cout << dummy_sum << " " << max << endl; if (dummy_sum != max) category_sizes[0] += max - dummy_sum; // for (i = 0; i < n_categories; i++) // cout << i + 1 << " " << category_sizes[i] << endl; double *partial_sums = new double[n_categories]; // partial_sums[n] = sum_{k=1}^{d_n} k^{-1} for (i = 1; i <= n_categories; i++) { partial_sums[i - 1] = .0; for (j = 1; j <= category_sizes[i - 1]; j++) partial_sums[i - 1] += 1. / j; } category_sums = new double[n_categories]; category_sums_partial_sums = new double[n_categories]; sum = .0; for (i = 1; i <= n_categories; i++) { category_sums[i - 1] = .0; for (j = 1; j <= n_categories; j++) if (i == j) category_sums[i - 1] += (alpha / i) * partial_sums[i - 1]; else category_sums[i - 1] += partial_sums[j - 1] * (1 - alpha) / (j * (n_categories - 1)); // cout << "u_" << i << " == " << category_sums[i - 1] << endl; sum += category_sums[i - 1]; if (i == 1) category_sums_partial_sums[0] = category_sums[0]; else category_sums_partial_sums[i - 1] = category_sums_partial_sums[i - 2] + category_sums[i - 1]; } delete [] category_sizes; delete [] partial_sums; }; ZipfLawCategorySelectionGenerator::~ZipfLawCategorySelectionGenerator() { delete [] category_sums; delete [] category_sums_partial_sums; }; int ZipfLawCategorySelectionGenerator::getNext() { double r = (sum * random() / RAND_MAX); double s = 0.; /* int i = 0; do { s += category_sums[i++]; } while (s < r); */ int left = 0; int right = n_categories; int i = Utils::binarySearch(category_sums_partial_sums, left, right, r); if (i < 0) i *= -1; else i++; return i; }; ///////////////////////////////////////////////////////////////////////////// ////////////////// FileDefinedCategorySelectionGenerator //////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const FileDefinedCategorySelectionGenerator& fdcsg) { outs << "fdcsg[" << fdcsg.max << "]"; return outs; }; FileDefinedCategorySelectionGenerator::FileDefinedCategorySelectionGenerator( const char* file_name) { // cout << "asdasdasda" << endl; ifstream input; input.open(file_name, ios::in); if ((input.rdstate() & ifstream::failbit ) != 0) { cerr << "Error opening file: " << file_name << endl; return; } int max_categories = 2; int category_index; int file_weight; int *dummy; sum = .0; category_sums = new int[max_categories]; Utils::fillWithZeros(category_sums, 0, max_categories - 1); while (!input.eof()) { // read category input >> category_index; if (input.eof()) continue; // cout << category_index << endl; if (category_index >= max_categories) { dummy = category_sums; category_sums = Utils::resizeArray(category_sums, max_categories, 2 * max_categories); delete [] dummy; Utils::fillWithZeros(category_sums, max_categories, 2 * max_categories - 1); max_categories *= 2; } // read file weight input >> file_weight; category_sums[category_index] += file_weight; sum += file_weight; } n_categories = category_index + 1; dummy = category_sums; category_sums = Utils::resizeArray(category_sums, max_categories, n_categories); delete [] dummy; max = n_categories; input.close(); category_sums_partial_sums = new int[n_categories]; category_sums_partial_sums[0] = category_sums[0]; for (int i = 1; i < n_categories; i++) category_sums_partial_sums[i] = category_sums_partial_sums[i - 1] + category_sums[i]; }; FileDefinedCategorySelectionGenerator::~FileDefinedCategorySelectionGenerator() { delete [] category_sums; delete [] category_sums_partial_sums; }; int FileDefinedCategorySelectionGenerator::getNext() { int r = (int) (1. * sum * random() / RAND_MAX); int s = 0; /* int i = 0; do { s += category_sums[i++]; } while (s < r); */ int left = 0; int right = n_categories; int i = Utils::binarySearch(category_sums_partial_sums, left, right, r); if (i < 0) i *= -1; else i++; return i; }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////// PermutationGenerator ///////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const PermutationGenerator& pg) { outs << "pg[" << pg.n << "]"; return outs; }; PermutationGenerator::PermutationGenerator(const int p_n) : n(p_n), ug(p_n) { last_permutation = new int[n]; for (int i = 0; i < n; i++) last_permutation[i] = i + 1; }; int *PermutationGenerator::getNextPermutation() { for (int i = 0; i < n; i++) { int j = ug.getNext(); int tmp = last_permutation[j - 1]; last_permutation[j - 1] = last_permutation[i]; last_permutation[i] = tmp; } return last_permutation; } PermutationGenerator::~PermutationGenerator() { delete [] last_permutation; } ///////////////////////////////////////////////////////////////////////////// /////////////////////////////// FileReference /////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const FileReference& fr) { outs << "fr[" << fr.file_id << "," << *(fr.peer) << "]"; return outs; }; FileReference::FileReference() { file_id = -1; peer = NULL; }; FileReference::FileReference(int p_file_id, Peer *p_peer) : file_id(p_file_id), peer(p_peer) { }; FileReference::FileReference(const FileReference &fr) : file_id(fr.file_id), peer(fr.peer) { }; FileReference& FileReference::operator=(const FileReference& file_reference) { file_id = file_reference.file_id; peer = file_reference.peer; return *this; }; bool FileReference::operator==(const FileReference& file_reference) { if (file_id != file_reference.file_id) return false; if (peer != file_reference.peer) return false; return true; }; bool FileReference::operator!=(const FileReference& file_reference) { return !(*this == file_reference); }; int FileReference::getFileId() { return file_id; }; void FileReference::setFileId(int p_file_id) { file_id = p_file_id; }; Peer *FileReference::getPeer() { return peer; }; void FileReference::setPeer(Peer *p_peer) { peer = p_peer; }; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////// Assignment //////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const Assignment& a) { outs << "a[" << *(a.peer) << "," << *(a.super_peer) << "]"; return outs; }; Assignment::Assignment() { peer = NULL; super_peer = NULL; }; Assignment::Assignment(Peer *p_peer, SuperPeer *p_super_peer) : peer(p_peer), super_peer(p_super_peer) { }; Assignment::Assignment(const Assignment &a) : peer(a.peer), super_peer(a.super_peer) { }; Assignment& Assignment::operator=(const Assignment& assignment) { peer = assignment.peer; super_peer = assignment.super_peer; return *this; }; Peer *Assignment::getPeer() { return peer; }; SuperPeer *Assignment::getSuperPeer() { return super_peer; }; void Assignment::setPeer(Peer* p_peer) { peer = p_peer; }; void Assignment::setSuperPeer(SuperPeer* p_super_peer) { super_peer = p_super_peer; }; ///////////////////////////////////////////////////////////////////////////// /////////////////////////////// PriorityQueue /////////////////////////////// ///////////////////////////////////////////////////////////////////////////// template ostream& operator<<(ostream& outs, const PriorityQueue& pq) { /* outs << "pq[" << pq.max_size << "," << pq.initial_priority << ",{"; // vector::const_iterator iter; // for (iter = pq.values.begin(); iter != pq.values.end(); iter++) // outs << *iter << " "; // outs << "},{"; vector::const_iterator p_iter; for (p_iter = pq.priorities.begin(); p_iter != pq.priorities.end(); p_iter++) outs << *p_iter << " "; outs << "}]"; return outs; */ return ((PriorityQueue&) pq).print(outs); }; template ostream& PriorityQueue::print(ostream& outs) { outs << "pq[" << max_size << "," << initial_priority << ",{"; typename vector::const_iterator iter; for (iter = values.begin(); iter != values.end(); iter++) outs << *iter << " "; outs << "},{"; vector::const_iterator p_iter; for (p_iter = priorities.begin(); p_iter != priorities.end(); p_iter++) // printf("%i ", *p_iter); outs << "_" << (*p_iter) << "_ "; outs << "}]"; return outs; }; template PriorityQueue::PriorityQueue(int p_max_size, int p_initial_priority) : max_size(p_max_size), initial_priority(p_initial_priority), values_dictionary(NULL) { }; template PriorityQueue::PriorityQueue(int p_max_size, int p_initial_priority, map *p_values_dictionary) : max_size(p_max_size), initial_priority(p_initial_priority), values_dictionary(p_values_dictionary) { }; template void PriorityQueue::correctSize() { int size = values.size(); for (int size = values.size(); size > 2 * max_size; size--) { T begin = (T) *(values.begin()); if (values_dictionary != NULL) values_dictionary->erase(((Hash) begin).getHash()); values.erase(values.begin()); priorities.erase(priorities.begin()); } /* std::vector *>::iterator it; typedef typename std::vector *>::iterator observerIterator; observerIterator it; typename std::vector *>::iterator it; */ /* T max_value; vector::iterator iter_p = priorities.begin(); vector::iterator iter_v = values.begin(); int min_priority = *iter_p; vector::iterator min_iter_p = iter_p; vector::const_iterator min_iter_v = iter_v; for (; iter_p != priorities.end(); iter_p++) { // CHECK if (*iter_p > max_priority) { min_priority = *iter_p; min_iter_p = iter_p; min_iter_v = iter_v; } iter_v++; } if (iter_p != priorities.end()) { priorities.erase(min_iter_p); values.erase(min_iter_v); } this.fitSize(); */ }; template void PriorityQueue::correctOrder() { // CHECK vector::iterator iter_p = priorities.begin(); vector::iterator prev_iter_p; typename vector::iterator iter_v = values.begin(); typename vector::iterator prev_iter_v; /* cout << "---" << endl; for (iter_p = priorities.begin(); iter_p != priorities.end(); iter_p++) { cout << *(iter_p) << endl; } cout << "---" << endl; */ iter_p = priorities.begin(); int prev_priority = -1; int i = 0; while ((iter_p != priorities.end()) && (prev_priority <= *iter_p)) { prev_priority = *iter_p; prev_iter_p = iter_p; prev_iter_v = iter_v; iter_p++; iter_v++; i++; } if (iter_p == priorities.end()) return; vector::iterator dummy_iter_p = iter_p; dummy_iter_p++; if ((dummy_iter_p != priorities.end()) && (*dummy_iter_p <= *prev_iter_p)) { // forward // cout << "forward" << endl; while ((iter_p != priorities.end()) && (*iter_p < prev_priority)) { iter_p++; iter_v++; } priorities.insert(iter_p, *prev_iter_p); values.insert(iter_v, *prev_iter_v); // prev_iter_p and prev_iter_v are not valid any more prev_iter_p = priorities.begin(); prev_iter_v = values.begin(); for (; i > 1; i--) { prev_iter_p++; prev_iter_v++; } priorities.erase(prev_iter_p); values.erase(prev_iter_v); } else { // backward // cout << "backward" << endl; prev_iter_p = priorities.begin(); prev_iter_v = values.begin(); while (*iter_p > *prev_iter_p) { prev_iter_p++; prev_iter_v++; } // cout << ": " << *prev_iter_v << " " << *iter_v << endl; priorities.insert(prev_iter_p, *iter_p); values.insert(prev_iter_v, *iter_v); i++; // elements were inserted before iter_p and iter_v // cout << "middle: "; // print(cout) << endl; // cout << ": " << *prev_iter_v << " " << *iter_v << endl; // iter_p and iter_v are not valid any more iter_p = priorities.begin(); iter_v = values.begin(); for (; i > 0; i--) { iter_p++; iter_v++; } priorities.erase(iter_p); values.erase(iter_v); // cout << "after: "; // print(cout) << endl; } }; template T PriorityQueue::selectWithHighestPriority() { return values.back(); /* T max_value; vector::const_iterator iter_p; vector::const_iterator iter_v = values.begin(); for (iter_p = priorities.begin(); iter_p != priorities.end(); iter_p++) { if (*iter_p > max_priority) { max_priority = *iter_p; max_value = *iter_v; } iter_v++; } return max_value; */ }; template T PriorityQueue::selectRandomly() { int sum = 0; int i = 0; vector::reverse_iterator iter_p; for (iter_p = priorities.rbegin(); (iter_p != priorities.rend()) && (i < max_size); iter_p++) { // iterate over at most max_size items with the highest priorities // cout << "priority = " << *iter_p << endl; sum += *iter_p; i++; } // cout << "sum = " << sum << endl; UniformGenerator ug(sum); int r = ug.getNext(); typename vector::reverse_iterator iter_v = values.rbegin(); iter_p = priorities.rbegin(); sum = *iter_p; while (sum < r) { iter_p++; iter_v++; sum += *iter_p; } return *iter_v; }; template int PriorityQueue::getPriority(T value) { typename vector::const_iterator iter_v = values.begin(); vector::const_iterator iter_p = priorities.begin(); while ((iter_v != values.end()) && (value != *iter_v)) { iter_v++; iter_p++; } if (iter_v == values.end()) return -1; else return *iter_p; }; template void PriorityQueue::incPriority(T value, int mode) { // cout << "dupa 1" << endl; typename vector::const_iterator iter_v = values.begin(); vector::const_iterator iter_p = priorities.begin(); int i = 0; while ((iter_v != values.end()) && (value != (*iter_v))) { // cout << "val " << value << " " << *iter_v << endl; iter_v++; i++; // iter_p++; } if (iter_v != values.end()) { // update // cout << "dupa1" << endl; if (mode == LRU_MODE) priorities[i] = priorities.back() + 1; // priorities[i] + 1; else // (mode == LFU_MODE) || (mode == MIXED_MODE) priorities[i] = priorities[i] + 1; correctOrder(); } else { // insert // cout << "dupa2 " << initial_priority << endl; values.push_back(value); if (values_dictionary != NULL) (*values_dictionary)[((Hash) value).getHash()] = value; int priority; if (priorities.empty()) priority = initial_priority; else if ((mode == LRU_MODE) || (mode == MIXED_MODE)) priority = priorities.back() + 1; else { // (mode == LFU_MODE) if (priorities.size() < max_size) priority = max(priorities.front() - 1, initial_priority); else priority = max(priorities[priorities.size() - max_size] - 1, initial_priority); // priority = priorities[(priorities.size() + 1) / 2]; } priorities.push_back(priority); // initial_priority); correctOrder(); // if (values.size() > 2 * max_size) correctSize(); } // for (iter_p = priorities.begin(); iter_p != priorities.end(); iter_p++) // cout << *iter_p << " "; // cout << endl; // cout << "before: "; // print(cout) << endl; // cout << "dupa 2" << endl; }; template void PriorityQueue::decPriority(T value) { typename vector::const_iterator iter_v = values.begin(); // vector::const_iterator iter_p = priorities.begin(); int i = 0; while ((iter_v != values.end()) && (*iter_v != value)) { iter_v++; i++; // iter_p++; } if ((iter_v != values.end()) && (priorities[i] >= initial_priority)) { priorities[i] = priorities[i] - 1; correctOrder(); } // else { // values.push_back(value); // priorities.push_back(1); // } }; template void PriorityQueue::setPriority(T value, int priority) { typename vector::const_iterator iter_v = values.begin(); // vector::const_iterator iter_p = priorities.begin(); int i = 0; while ((iter_v != values.end()) && (value != (*iter_v))) { iter_v++; i++; // iter_p++; } if (iter_v != values.end()) { priorities[i] = priority; correctOrder(); } else { values.push_back(value); priorities.push_back(priority); correctOrder(); if (values.size() > 2 * max_size) correctSize(); } }; template vector& PriorityQueue::getValues() { return values; }; template vector& PriorityQueue::getPriorities() { return priorities; }; template int PriorityQueue::getMaxSize() { return max_size; }; template void PriorityQueue::setMaxSize(int p_max_size) { max_size = p_max_size; }; template map *PriorityQueue::getValuesDictionary() { return values_dictionary; }; ///////////////////////////////////////////////////////////////////////////// //////////////////////////////////// Peer /////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const Peer& peer) { outs << "p[" << peer.id << "," << peer.semantic_group->getId() << ",{"; // << peer.files << ",{"; vector::const_iterator iter; vector::const_iterator f_iter; vector::const_iterator p_iter; // p_iter = ((Peer) peer).neighbors.getPriorities().begin(); // cout << " _" << ((Peer) peer).neighbors.getPriorities().size() << "_ "; const vector &files = ((Peer&) peer).files.getValues(); const vector &priorities = ((Peer&) peer).files.getPriorities(); p_iter = priorities.begin(); for (f_iter = files.begin(); f_iter != files.end(); f_iter++) { outs << (*f_iter) << ":" << (*p_iter) << " "; p_iter++; } outs << "},{"; const vector &neighbors = ((Peer&) peer).neighbors.getValues(); const vector &n_priorities = ((Peer&) peer).neighbors.getPriorities(); p_iter = n_priorities.begin(); for (iter = neighbors.begin(); iter != neighbors.end(); iter++) { Peer *p = *iter; outs << p->id << ":" << (*p_iter) << " "; p_iter++; } outs << "}]"; return outs; }; Peer::Peer(int p_id) : id(p_id), files(FILE_CACHE_SIZE, INITIAL_PRIORITY), neighbors(PEER_NEIGHBOR_CACHE_SIZE, INITIAL_PRIORITY), semantic_group(NULL), active(true) { }; Peer::Peer(int p_id, int p_file_cache_size, int p_neighbor_cache_size) : id(p_id), files(p_file_cache_size, INITIAL_PRIORITY), neighbors(p_neighbor_cache_size, INITIAL_PRIORITY), semantic_group(NULL), active(true) { }; Peer::Peer(int p_id, vector p_files, vector p_neighbors) : id(p_id), files(FILE_CACHE_SIZE, INITIAL_PRIORITY), neighbors(PEER_NEIGHBOR_CACHE_SIZE, INITIAL_PRIORITY), semantic_group(NULL), active(true) { vector::const_iterator f_iter; for (f_iter = p_files.begin(); f_iter != p_files.end(); f_iter++) files.incPriority(*f_iter, F_MODE); vector::const_iterator p_iter; for (p_iter = p_neighbors.begin(); p_iter != p_neighbors.end(); p_iter++) neighbors.incPriority(*p_iter, U_MODE); }; int Peer::getId() { return id; }; bool Peer::hasFile(int file_id) { return (files.getPriority(file_id) != -1); }; vector& Peer::getFiles() { return files.getValues(); }; void Peer::addFile(int file_id) { files.incPriority(file_id, F_MODE); }; vector& Peer::getNeighbors() { return neighbors.getValues(); }; Peer* Peer::getRandomNeighbor() { // cout << "Before select " << id << endl; Peer *selected = neighbors.selectRandomly(); // cout << "After select " << endl; return selected; }; void Peer::addNeighbor(Peer* peer) { // cout << "addNeighbor begin" << endl; neighbors.incPriority(peer, U_MODE); /* cout << *this << endl; vector::const_iterator iter; for (iter = neighbors.getPriorities().begin(); iter != neighbors.getPriorities().end(); iter++) cout << (*iter) << " "; cout << endl; */ // cout << "addNeighbor end" << endl; }; SemanticGroup* Peer::getSemanticGroup() { return semantic_group; }; void Peer::setSemanticGroup(SemanticGroup* group) { semantic_group = group; }; void Peer::addRandomFiles() { FileReference fr; fr.setPeer(this); for (int i = 0; i < N_FILES_TO_ADD; i++) { fr.setFileId(semantic_group->getRandomFile()); addFile(fr.getFileId()); SuperPeer *sp = (SuperPeer *) neighbors.selectRandomly(); sp->addFileReference(fr); } }; void Peer::propagateFiles(Network *network) { if (!isActive()) return; FileReference fr; fr.setPeer(this); for (int i = 0; i < N_FILES_TO_PROPAGATE; i++) { fr.setFileId(files.selectRandomly()); for (int j = 0; j < N_PROPAGATION_NODES; j++) { // * SuperPeer *sp = network->getRandomSuperPeer(); SuperPeer *sp = (SuperPeer *) neighbors.selectRandomly(); sp->addFileReference(fr); } } }; Assignment Peer::search() { return search(semantic_group->getRandomFile()); }; Assignment Peer::search(int file_id) { Assignment assignment(NULL, NULL); if (!isActive()) { // cout << "NOT ACTIVE" << endl; return assignment; } current_time++; // cout << "Peer search " << id << endl; // Assignment ass; // return ass; vector &super_peers = neighbors.getValues(); vector::reverse_iterator iter = super_peers.rbegin(); bool found = false; bool found_locally = false; SuperPeer *super_peer; int i = 0; while ((i < neighbors.getMaxSize()) && !found && (iter != super_peers.rend())) { // first = false; // * for (int i = 0; !found && (i < PEER_NEIGHBOR_CACHE_SIZE); i++) { super_peer = (SuperPeer *) *iter; // * super_peer = (SuperPeer *) neighbors.selectRandomly(); // cout << "Peer search 0" << endl; FileReference file_reference(super_peer->getFileReference(file_id)); // assignment = superpeer->searchLocally(file_id); if (file_reference.getPeer() != NULL) { // cout << "id == " << file_reference.getPeer()->getId() << endl; found = found_locally = true; assignment.setPeer(file_reference.getPeer()); assignment.setSuperPeer(super_peer); // cout << "Found locally peer " << id << " " << file_id << " : " << // file_reference.getFileId() << endl; n_files_found_locally++; n_files_found_locally_load[(int) (super_peer->getDesiredLoad() * (N_LOAD_CLASSES - 1))]++; n_found_locally[file_id - 1]++; // file_references.incPriority(file_reference, F_MODE); } super_peer->incNRequests(); iter++; i++; } // cout << "Peer search 1" << endl; if (!found) { // cout << "Peer search 1" << endl; // cout << "superpeers size " << super_peers.size() << endl; super_peer = (SuperPeer *) neighbors.selectRandomly(); n_global_requests++; timer4.start(); assignment = super_peer->search(file_id); timer4.stop(); if (assignment.getPeer() != NULL) { found = true; // cout << "Found remotely file " << file_id << " peer " << id // << endl; // cout << "id == " << assignment.getPeer()->getId() << endl; n_files_found_remotely++; n_files_found_remotely_load[(int) (assignment.getSuperPeer()->getDesiredLoad() * (N_LOAD_CLASSES - 1))]++; n_found_remotely[file_id - 1]++; } super_peer->incNRequests(); } // ola ma psa if (found) { if (execution_mode >= NORMAL_MODE) neighbors.incPriority(assignment.getSuperPeer(), U_MODE); // cout << "Before " << endl; // if (!found_locally) if (execution_mode >= ADVANCED_MODE) for (i = 0; i < N_REPLACEMENTS; i++) neighbors.incPriority( (assignment.getPeer())->getRandomNeighbor(), U_MODE); // cout << "After " << endl; // files.incPriority(file_id, LRU_MODE); } else { // if (net->findFile(file_id) != NULL) { n_files_missed++; n_missed[file_id - 1]++; } // cout << "Peer search end" << endl; return assignment; }; bool Peer::isActive() { return active; }; void Peer::activate() { active = true; }; void Peer::deactivate() { active = false; }; void Peer::removeNonActive() { vector &super_peers = neighbors.getValues(); vector::iterator iter; for (iter = super_peers.begin(); iter != super_peers.end(); iter++) if (!(*iter)->isActive()) neighbors.setPriority((*iter), INITIAL_PRIORITY - 1); }; ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////// SuperPeer ///////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const SuperPeer& sp) { outs << "sp[" << sp.id << "," << sp.desired_load << "," << sp.relative_load << "," << ((SuperPeer&) sp).file_references.getMaxSize() << "," << ((SuperPeer&) sp).getNRequests() << ",{"; vector::iterator fr_iter; vector &file_references = ((SuperPeer&) sp).file_references.getValues(); vector::const_iterator p_iter = ((SuperPeer&) sp).file_references.getPriorities().begin(); for (fr_iter = file_references.begin(); fr_iter != file_references.end(); fr_iter++) { outs << (*fr_iter).getFileId() << ":" << *p_iter << " "; p_iter++; } outs << "},{"; vector::const_iterator iter; vector &neighbors = ((SuperPeer&) sp).neighbors.getValues(); for (iter = neighbors.begin(); iter != neighbors.end(); iter++) { Peer p = **iter; outs << p.getId() << " "; } outs << "},{"; vector &files = ((SuperPeer&) sp).files.getValues(); vector::const_iterator f_iter; // vector &priorities = ((SuperPeer&) sp).files.getPriorities(); p_iter = ((SuperPeer&) sp).files.getPriorities().begin(); for (f_iter = files.begin(); f_iter != files.end(); f_iter++) { outs << *f_iter << ":" << *p_iter << " "; p_iter++; } outs << "}]"; return outs; }; SuperPeer::SuperPeer(int p_id) : Peer(p_id, FILE_CACHE_SIZE, SUPER_PEER_NEIGHBOR_CACHE_SIZE), n_requests(0), file_references(FILE_REFERENCE_CACHE_SIZE, INITIAL_PRIORITY, new map), desired_load(-1), relative_load(0), service_rate(1) { }; SuperPeer::SuperPeer(int p_id, int p_file_cache_size, int p_neighbor_cache_size, int p_file_reference_cache_size) : Peer(p_id, p_file_cache_size, p_neighbor_cache_size), n_requests(0), file_references(p_file_reference_cache_size, INITIAL_PRIORITY, new map), desired_load(-1), relative_load(0), service_rate(1) { }; SuperPeer::SuperPeer(int p_id, int p_file_cache_size, int p_neighbor_cache_size, int p_file_reference_cache_size, double p_desired_load) : Peer(p_id, p_file_cache_size, p_neighbor_cache_size), n_requests(0), file_references(p_file_reference_cache_size, INITIAL_PRIORITY, new map), desired_load(p_desired_load), relative_load(0), service_rate(1) { }; SuperPeer::SuperPeer(int p_id, vector p_files, vector p_neighbors) : Peer(p_id, p_files, p_neighbors), n_requests(0), file_references(FILE_REFERENCE_CACHE_SIZE, INITIAL_PRIORITY, new map), desired_load(-1), relative_load(0), service_rate(1) { }; FileReference SuperPeer::getFileReference(int file_id) { // vector &files = file_references.getValues(); // vector::const_iterator iter; FileReference file_reference; if (!isActive()) return file_reference; // n_requests++; /* for (iter = files.begin(); iter != files.end(); iter++) { file_reference = *iter; if ((file_reference.getFileId() == file_id) && file_reference.getPeer()->isActive()) { // cout << "_p1 " << file_references.getPriority(file_reference) << // endl; if (execution_mode > STATIC_MODE) file_references.incPriority(file_reference, F_MODE); // cout << "_p2 " << file_references.getPriority(file_reference) << // endl; return file_reference; } } */ map *valuesDictionary = file_references.getValuesDictionary(); map::iterator iter = valuesDictionary->find(file_id); if (iter != valuesDictionary->end()) { file_reference = (*iter).second; if (file_reference.getPeer()->isActive()) { if (execution_mode > STATIC_MODE) file_references.incPriority(file_reference, F_MODE); return file_reference; } } file_reference.setFileId(-1); file_reference.setPeer(NULL); return file_reference; }; // bool SuperPeer::knowsFile(int file_id) { // FileReference file_reference = getFileReference(file_id); // // return file_reference.getFileId() != -1; // }; vector& SuperPeer::getFileReferences() { return file_references.getValues(); }; void SuperPeer::addFileReference(FileReference file_reference) { file_references.incPriority(file_reference, F_MODE); }; void SuperPeer::addFileReferences(vector& file_refs) { vector::const_iterator iter = file_refs.begin(); for (iter = file_refs.begin(); iter != file_refs.end(); iter++) file_references.incPriority(*iter, F_MODE); }; /* Assignment SuperPeer::search(int file_id) { FileReference file_reference = getFileReference(file_id); Assignment assignment; if (file_reference.getPeer() == NULL) assignment = network.search(file_id, this); else { assignment.setPeer(file_reference.getPeer()); assignment.setSuperPeer(this); } return network.search(file_id, this); }; */ /* Assignment SuperPeer::search(int file_id) { // vector cycle; // cout << "SuperPeer search file " << file_id << " spid " << id << endl; // Assignment ass; // return ass; // // Assignment as = net->findFileAtSuperPeer(file_id); // if (as.getPeer() != NULL) { // FileReference fr(file_id, as.getPeer()); // file_references.incPriority(fr, F_MODE); // } // return as; if (!isActive()) { Assignment assignment; return assignment; } // n_requests++; FileReference file_reference = getFileReference(file_id); if (file_reference.getPeer() != NULL) { // cout << "Found file " << file_id << " at spid " << id << endl; // file_references.incPriority(file_reference, F_MODE); Assignment assignment(file_reference.getPeer(), this); return assignment; } deque queue; bool visited[net->getNSuperPeers()]; // bool first_time = true; queue.push_back(this); for (int i = 0; i < net->getNSuperPeers(); i++) visited[i] = false; visited[getId() - 1] = true; while (!queue.empty()) { SuperPeer *super_peer = queue.front(); queue.pop_front(); vector &neighbors = super_peer->getNeighbors(); vector::const_iterator iter; for (iter = neighbors.begin(); iter != neighbors.end(); iter++) { SuperPeer *super_peer1 = (SuperPeer*) *iter; if (!visited[super_peer1->getId() - 1]) { file_reference = super_peer1->getFileReference(file_id); if (file_reference.getPeer() != NULL) { updateRelativeLoad(super_peer1); // super_peer1->updateRelativeLoad(this); if (execution_mode > STATIC_MODE) file_references.incPriority(file_reference, F_MODE); Assignment assignment(file_reference.getPeer(), super_peer1); return assignment; } queue.push_back(super_peer1); visited[super_peer1->getId() - 1] = true; } } } Assignment assignment; // cout << "SuperPeer search end" << endl; return assignment; }; */ Assignment SuperPeer::search(int file_id) { if (!isActive()) { Assignment assignment; return assignment; } double r = rand() / (RAND_MAX + 1.); if (r > service_rate) { Assignment assignment; return assignment; } // n_requests++; request_times.push_back(current_time); timer5.start(); FileReference file_reference = getFileReference(file_id); timer5.stop(); if (file_reference.getPeer() != NULL) { // cout << "Found file " << file_id << " at spid " << id << endl; // file_references.incPriority(file_reference, F_MODE); Assignment assignment(file_reference.getPeer(), this); return assignment; } // CHECK: are file references in a single file cache representing unique files? vector::const_iterator iter; for (iter = getNeighbors().begin(); iter != getNeighbors().end(); iter++) { SuperPeer *super_peer = (SuperPeer*) *iter; timer5.start(); file_reference = super_peer->getFileReference(file_id); timer5.stop(); if (file_reference.getPeer() != NULL) { // updateRelativeLoad(super_peer); // super_peer1->updateRelativeLoad(this); updateServiceRate(super_peer); super_peer->updateServiceRate(this); if (execution_mode > STATIC_MODE) file_references.incPriority(file_reference, F_MODE); Assignment assignment(file_reference.getPeer(), super_peer); return assignment; } } Assignment assignment; return assignment; }; int SuperPeer::getCacheSize() { return file_references.getMaxSize(); }; void SuperPeer::setCacheSize(int new_cache_size) { file_references.setMaxSize(new_cache_size); }; void SuperPeer::correctCacheSize() { // return; int new_size = file_references.getMaxSize(); if ((id == 1) || (id == 2)) { cout << id << ": desired_load " << desired_load << " n_requests " << n_requests << " old_size " << file_references.getMaxSize() << " relative_load " << relative_load << endl; // (int) (BETA * new_size * // ((float) (max_load - n_requests)) / // Utils::max(max_load, n_requests)) << endl; // return; } // new_size += (int) (BETA * new_size * ((float) (max_load - n_requests)) / Utils::max(max_load, n_requests)); if (relative_load < 0) new_size += CACHE_SIZE_MODIFICATION_STEP; else new_size -= CACHE_SIZE_MODIFICATION_STEP; n_requests = 0; if (new_size < MIN_FILE_REFERENCE_CACHE_SIZE) { new_size = MIN_FILE_REFERENCE_CACHE_SIZE; } else if (new_size > MAX_FILE_REFERENCE_CACHE_SIZE) { new_size = MAX_FILE_REFERENCE_CACHE_SIZE; } file_references.setMaxSize(new_size); // if ((file_references.getMaxSize() > FILE_REFERENCE_CACHE_SIZE) && // (n_requests > n_global_requests / net->getNSuperPeers())) // file_references.setMaxSize(file_references.getMaxSize() - 1); // if (n_requests < n_global_requests / net->getNSuperPeers()) // file_references.setMaxSize(file_references.getMaxSize() + 1); // // cout << "correctCacheSize " << n_requests << " " << // // n_global_requests / net->getNSuperPeers() << endl; // // N_SEARCHES_PER_PHASE * net->getNPeers() / net->getNSuperPeers() << // // endl; }; double SuperPeer::getRelativeLoad() { return relative_load; }; void SuperPeer::updateRelativeLoad(SuperPeer *super_peer) { relative_load = BETA * relative_load + GAMMA * super_peer->getRelativeLoad() + (1. - BETA - GAMMA) * (n_requests / desired_load - super_peer->getNRequests() / super_peer->getDesiredLoad()); }; double SuperPeer::getServiceRate() { return service_rate; }; void SuperPeer::updateServiceRate(SuperPeer *super_peer) { if ((getNRequestsInWindow() == 0) || (super_peer->getNRequestsInWindow() == 0)) return; double old_service_rate = service_rate; double delta = (desired_load / getNRequestsInWindow() - super_peer->getDesiredLoad() / super_peer->getNRequestsInWindow()) / (desired_load / getNRequestsInWindow() + super_peer->getDesiredLoad() / super_peer->getNRequestsInWindow()); double new_service_rate = service_rate + delta; if (new_service_rate < 0) new_service_rate = 0.; else if (new_service_rate > 1) new_service_rate = 1.; service_rate = DELTA * service_rate + (1. - DELTA) * new_service_rate; // cout << "old_service_rate: " << old_service_rate << " new_service_rate: " << service_rate << // " getNRequestsInWindow(): " << getNRequestsInWindow() << // " super_peer->getNRequestsInWindow(): " << super_peer->getNRequestsInWindow() << // " delta: " << delta << endl; }; int SuperPeer::getNRequests() { return n_requests; }; void SuperPeer::incNRequests() { n_requests++; }; double SuperPeer::getDesiredLoad() { return desired_load; }; void SuperPeer::setDesiredLoad(double p_desired_load) { desired_load = p_desired_load; }; // void SuperPeer::printFileStatistics() { // vector &file_references = file_references.getValues(); // vector::const_iterator iter; // for (iter = file_references.begin(); iter != file_references.end(); // iter++) { // cout << file_reference // } // }; void SuperPeer::removeNonActive() { vector &super_peers = neighbors.getValues(); vector::iterator iter; for (iter = super_peers.begin(); iter != super_peers.end(); iter++) if (!(*iter)->isActive()) neighbors.setPriority((*iter), INITIAL_PRIORITY - 1); vector &file_refs = file_references.getValues(); vector::iterator f_iter; for (f_iter = file_refs.begin(); f_iter != file_refs.end(); f_iter++) if (!((*f_iter).getPeer())->isActive()) file_references.setPriority((*f_iter), INITIAL_PRIORITY - 1); }; int SuperPeer::getNRequestsInWindow() { deque::iterator iter; int window_begin = current_time - WINDOW_SIZE; for (iter = request_times.begin(); iter != request_times.end();) if ((*iter) < window_begin) iter = request_times.erase(iter); else break; return request_times.size(); }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////// Network ////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const Network& n) { outs << "n[{"; vector::const_iterator s_iter; for (s_iter = n.super_peers.begin(); s_iter != n.super_peers.end(); s_iter++) outs << (*s_iter)->getId() << " "; outs << "},{"; vector::const_iterator iter; for (iter = n.peers.begin(); iter != n.peers.end(); iter++) outs << (*iter)->getId() << " "; outs << "}]"; return outs; }; Network::Network(int n_peers, int n_super_peers) { // cout << "Network begin" << endl; peer_selection_generator = new UniformGenerator(n_peers); super_peer_selection_generator = new UniformGenerator(n_super_peers); UniformGenerator super_peer_load_generator(N_LOAD_CLASSES); // super_peer_max_load_selection_generator = // new UniformGenerator((int) (10000. * MAX_SUPER_PEER_DESIRED_LOAD - // 10000. * MIN_SUPER_PEER_DESIRED_LOAD + 1)); // cout << "dupa: " << 10000. * MAX_SUPER_PEER_DESIRED_LOAD - // 10000. * MIN_SUPER_PEER_DESIRED_LOAD + 1 << endl; int i; for (i = 0; i < n_super_peers; i++) { // double load = MIN_SUPER_PEER_DESIRED_LOAD + // (super_peer_max_load_selection_generator->getNext() - 1) / 10000.; // if (load < (MAX_SUPER_PEER_DESIRED_LOAD + MIN_SUPER_PEER_DESIRED_LOAD) / 2.) // load = MIN_SUPER_PEER_DESIRED_LOAD; // else // load = MAX_SUPER_PEER_DESIRED_LOAD; double load = super_peer_load_generator.getNext() / ((double) N_LOAD_CLASSES); // cout << "load: " << load << endl; SuperPeer *super_peer = new SuperPeer(i + 1, FILE_CACHE_SIZE, SUPER_PEER_NEIGHBOR_CACHE_SIZE, FILE_REFERENCE_CACHE_SIZE, load); super_peers.push_back(super_peer); all_peers.push_back(super_peer); } for (; i < n_peers + n_super_peers; i++) { Peer *peer = new Peer(i + 1); peers.push_back(peer); all_peers.push_back(peer); } // create connections between super-peers PermutationGenerator pg(n_super_peers); vector::const_iterator iter; for (iter = super_peers.begin(); iter != super_peers.end(); iter++) { int *permutation = pg.getNextPermutation(); for (i = 0; i < SUPER_PEER_NEIGHBOR_CACHE_SIZE; i++) { SuperPeer *super_peer = super_peers[permutation[i] - 1]; // do // super_peer = getRandomSuperPeer(); // while (super_peer == (*iter)); if (super_peer != (*iter)) (*iter)->addNeighbor(super_peer); } } // cout << "Network end" << endl; }; Network::~Network() { delete peer_selection_generator; delete super_peer_selection_generator; // delete super_peer_max_load_selection_generator; vector::const_iterator iter; for (iter = all_peers.begin(); iter != all_peers.end(); iter++) delete *iter; vector::const_iterator super_iter; for (super_iter = super_peers.begin(); super_iter != super_peers.end(); super_iter++) delete *super_iter; }; Peer *Network::getRandomPeer() { return peers[peer_selection_generator->getNext() - 1]; }; SuperPeer *Network::getRandomSuperPeer() { return super_peers[super_peer_selection_generator->getNext() - 1]; }; vector& Network::getPeers() { return peers; }; vector& Network::getSuperPeers() { return super_peers; }; vector& Network::getAllPeers() { return all_peers; }; int Network::getNPeers() { return peers.size(); }; int Network::getNSuperPeers() { return super_peers.size(); }; Peer* Network::findFile(int file_id) { vector::const_iterator iter; for (iter = peers.begin(); iter != peers.end(); iter++) if ((*iter)->hasFile(file_id)) return *iter; return NULL; }; Assignment Network::findFileAtSuperPeer(int file_id) { vector::const_iterator iter; for (iter = super_peers.begin(); iter != super_peers.end(); iter++) { FileReference file_reference = (*iter)->getFileReference(file_id); if (file_reference.getPeer() != NULL) { Assignment assignment(file_reference.getPeer(), *iter); // cout << "iid == " << file_reference.getPeer()->getId() << endl; return assignment; } } Assignment assignment; return assignment; }; void Network::deactivateRandomPeer() { Peer *peer; do { peer = getRandomPeer(); } while (!peer->isActive()); peer->deactivate(); }; void Network::deactivateRandomSuperPeer() { SuperPeer *super_peer; do { super_peer = getRandomSuperPeer(); } while (!super_peer->isActive()); super_peer->deactivate(); }; void Network::removeNonActive() { vector::const_iterator p_iter; for (p_iter = peers.begin(); p_iter != peers.end(); p_iter++) (*p_iter)->removeNonActive(); vector::const_iterator sp_iter; for (sp_iter = super_peers.begin(); sp_iter != super_peers.end(); sp_iter++) (*sp_iter)->removeNonActive(); }; ostream& Network::printLoadStatistics(ostream& outs) { double average_low_desired_load = 0; double average_high_desired_load = 0; double average_low_requests = 0; double average_high_requests = 0; double average_low_cache_size = 0; double average_high_cache_size = 0; int n_low = 0; int n_high = 0; vector::const_iterator iter; for (iter = super_peers.begin(); iter != super_peers.end(); iter++) { SuperPeer *super_peer = *iter; if (super_peer->getDesiredLoad() == MIN_SUPER_PEER_DESIRED_LOAD) { average_low_desired_load += super_peer->getDesiredLoad(); average_low_requests += super_peer->getNRequests(); average_low_cache_size += super_peer->getCacheSize(); n_low++; } else { average_high_desired_load += super_peer->getDesiredLoad(); average_high_requests += super_peer->getNRequests(); average_high_cache_size += super_peer->getCacheSize(); n_high++; } } average_low_desired_load /= n_low; average_high_desired_load /= n_high; average_low_requests /= n_low; average_high_requests /= n_high; average_low_cache_size /= n_low; average_high_cache_size /= n_high; outs << "average_high_desired_load: " << average_high_desired_load << " average_low_desired_load: " << average_low_desired_load << " average_high_requests: " << average_high_requests << " average_low_requests: " << average_low_requests << " average_high_cache_size: " << average_high_cache_size << " average_low_cache_size: " << average_low_cache_size << " n_high: " << n_high << " n_low: " << n_low << endl; return outs; }; ///////////////////////////////////////////////////////////////////////////// ///////////////////////// FilePropagationGenerator ////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const FilePropagationGenerator& fpg) { outs << "fpg[" << *(fpg.peer_selection_generator) << ",{"; vector::const_iterator iter; for (iter = fpg.peers.begin(); iter != fpg.peers.end(); iter++) outs << (*iter)->getId() << " "; outs << "}]"; return outs; }; FilePropagationGenerator::FilePropagationGenerator(Network* p_network, vector p_peers, RandomNumberGenerator* p_peer_selection_generator) : network(p_network), peers(p_peers), peer_selection_generator(p_peer_selection_generator) { }; void FilePropagationGenerator::propagateFiles() { vector::const_iterator iter; // for (int i = 0; i < N_PROPAGATIONS; i++) // peers[peer_selection_generator.getNext() - 1]->propagateFiles(); for (iter = peers.begin(); iter != peers.end(); iter++) (*iter)->propagateFiles(network); }; void FilePropagationGenerator::addRandomFiles() { vector::const_iterator iter; for (iter = peers.begin(); iter != peers.end(); iter++) (*iter)->addRandomFiles(); }; ///////////////////////////////////////////////////////////////////////////// /////////////////////////////// SemanticGroup /////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const SemanticGroup& sg) { outs << "sg[" << (*(sg.file_selection_generator)) << "," << (*(sg.peer_selection_generator)) << ",{"; vector::const_iterator iter; for (iter = sg.peers.begin(); iter != sg.peers.end(); iter++) outs << (*iter)->getId() << " "; outs << "}]"; return outs; }; SemanticGroup::SemanticGroup(int p_id, vector p_peers, RandomNumberGenerator* p_file_selection_generator, RandomNumberGenerator* p_peer_selection_generator) : id(p_id), peers(p_peers), file_selection_generator(p_file_selection_generator), peer_selection_generator(p_peer_selection_generator) { }; int SemanticGroup::getId() { return id; }; vector& SemanticGroup::getPeers() { return peers; }; void SemanticGroup::setPeerSelectionGenerator(RandomNumberGenerator* p_peer_selection_generator) { if (peer_selection_generator != NULL) delete peer_selection_generator; peer_selection_generator = p_peer_selection_generator; }; void SemanticGroup::addPeer(Peer *peer) { peers.push_back(peer); }; int SemanticGroup::getRandomFile() { return ((FileDefinedCategoryGenerator *) file_selection_generator)->getNext(id); }; void SemanticGroup::initializePeers(int cache_size) { vector::const_iterator iter; int i; // cout << "initializePeers 1" << endl; for (iter = peers.begin(); iter != peers.end(); iter++) { for (i = 0; i < FILE_CACHE_SIZE; i++) { int file_id = getRandomFile(); (*iter)->addFile(file_id); } int neighbor_cache_size = // max(SUPER_PEER_NEIGHBOR_CACHE_SIZE, PEER_NEIGHBOR_CACHE_SIZE; for (int i = 0; i < neighbor_cache_size; i++) { // ola ma psa SuperPeer *super_peer = net->getRandomSuperPeer(); // * SuperPeer *super_peer = (net->getSuperPeers())[id - 1]; // * super_peer->setCacheSize(cache_size); // *** int sp_id = PEER_NEIGHBOR_CACHE_SIZE * (id - 1) + i; // *** SuperPeer *super_peer = (net->getSuperPeers())[sp_id]; // **** int sp_id = (*iter)->getId() - net->getNSuperPeers() - 1; // **** SuperPeer *super_peer = (net->getSuperPeers())[sp_id]; // if (super_peer != (*iter)) (*iter)->addNeighbor(super_peer); } } // cout << "initializePeers 2" << endl; }; /* void SemanticGroup::generateSearch() { // cout << "--------------------------generateSearch " << id << endl; if (peers.empty()) return; // for (int i = 0; i < N_SEARCHES_PER_PHASE; i++) { // * for (int i = 0; i < peers.size(); i++) { // cout << "generateSearch 1" << endl; // cout << "generateSearch 2: " << file_id << endl; int peer_index = peer_selection_generator->getNext(); Peer *peer = peers[peer_index - 1]; int file_id; do { file_id = ((FileDefinedCategoryGenerator *) file_selection_generator)->getNext(id); // cout << "DUPA" << endl; } while (peer->hasFile(file_id)); // cout << "generateSearch 3: " << peer_index << ":" << peers.size() << // endl; peer->search(file_id); // * peers[i]->search(file_id); // cout << "generateSearch 4" << endl; // * } // cout << "generateSearch end" << endl; }; */ void SemanticGroup::generateSearch() { if (peers.empty()) return; vector::const_iterator iter; int i; // cout << "SemanticGroup::generateSearch()0" << endl; for (iter = peers.begin(); iter != peers.end(); iter++) { int peer_index = peer_selection_generator->getNext(); Peer *peer = *iter; int file_id; // cout << "SemanticGroup::generateSearch()1" << endl; int i = 0; timer2.start(); do { file_id = getRandomFile(); i++; } while (peer->hasFile(file_id)); timer2.stop(); // if (i > 10) // cout << "SemanticGroup::generateSearch()2: " << i << endl; timer3.start(); peer->search(file_id); timer3.stop(); } }; void SemanticGroup::test() { cout << "test " << id << endl; fflush(NULL); for (int i = 0; i < 1000; i++) cout << "sss " << ((FileDefinedCategoryGenerator *) file_selection_generator)->getNext(id) << endl; }; ///////////////////////////////////////////////////////////////////////////// //////////////////////////////// Simulation ///////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const Simulation& s) { outs << "s[]"; return outs; }; Simulation::Simulation(int n_peers, int n_super_peers) : network(n_peers, n_super_peers) { }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////// SyntheticDataSimulation ////////////////////////// ///////////////////////////////////////////////////////////////////////////// ostream& operator<<(ostream& outs, const SyntheticDataSimulation& sds) { outs << "sds[{"; vector::const_iterator iter; for (iter = sds.semantic_groups.begin(); iter != sds.semantic_groups.end(); iter++) outs << **iter << ","; outs << "}," << sds.file_propagation_generator << "," << *(sds.group_selection_generator) << "]"; return outs; }; SyntheticDataSimulation::SyntheticDataSimulation(int n_peers, int n_super_peers, int n_files, int n_semantic_groups) : Simulation(n_peers, n_super_peers), file_propagation_generator(&network, network.getPeers(), new UniformGenerator(n_peers)), nn_files(n_files) { // network.getAllPeers(), new UniformGenerator(n_peers + n_super_peers)) { int i; int n_peers_in_group[n_semantic_groups]; net = &network; // group_selection_generator = new ZipfLawCategorySelectionGenerator(n_files, // n_semantic_groups, ALPHA); // group_selection_generator = new ZipfLawGenerator(n_semantic_groups); group_selection_generator = new FileDefinedCategorySelectionGenerator( data_file_name); vector dummy; // cout << "dupa: " << n_semantic_groups << endl; RandomNumberGenerator *file_selection_generator = new FileDefinedCategoryGenerator(ALPHA, data_file_name); for (i = 0; i < n_semantic_groups; i++) { n_peers_in_group[i] = 0; // cout << "__i_b" << i << endl; SemanticGroup *group = new SemanticGroup(i + 1, dummy, file_selection_generator, // new BalancedZipfLawCategoryGenerator(n_files, i + 1, // n_semantic_groups, ALPHA), NULL); // cout << "__i_e" << i << endl; semantic_groups.push_back(group); // group->initializePeers(); } // ((FileDefinedCategoryGenerator *) file_selection_generator)->getNext(10); // cout << "SyntheticDataSimulation1" << endl; i = 0; vector::const_iterator iter; for (iter = network.getPeers().begin(); iter != network.getPeers().end(); iter++) { // (*iter)->search(0); int category = group_selection_generator->getNext(); if (i == 0) category = 1; i++; // cout << "category: " << category << endl; semantic_groups[category - 1]->addPeer(*iter); n_peers_in_group[category - 1]++; (*iter)->setSemanticGroup(semantic_groups[category - 1]); } // cout << "SyntheticDataSimulation2" << endl; double sum = 0.; for (i = 1; i <= n_semantic_groups; i++) sum += 1. / i; double cache_sizes_sum = network.getNSuperPeers() * FILE_REFERENCE_CACHE_SIZE; vector::const_iterator g_iter; i = 0; for (g_iter = semantic_groups.begin(); g_iter != semantic_groups.end(); g_iter++) { (*g_iter)->setPeerSelectionGenerator( new UniformGenerator(n_peers_in_group[i++])); (*g_iter)->initializePeers((int) (cache_sizes_sum / (((double) i) * sum))); // cout << "DUPA: " << cache_sizes_sum << " " << i << " " << sum << " " << // (cache_sizes_sum / ((double) i)) / sum << // cache_sizes_sum / (((double) i) * sum) << endl; } // cout << "testing" << endl; // semantic_groups[19]->test(); // cout << "done" << endl; // group_selection_generator = new UniformGenerator(n_semantic_groups); }; SyntheticDataSimulation::~SyntheticDataSimulation() { delete group_selection_generator; vector::const_iterator iter; for (iter = semantic_groups.begin(); iter != semantic_groups.end(); iter++) delete *iter; }; void SyntheticDataSimulation::start() { // * for (int i = 0; i < 10; i++) // * file_propagation_generator.propagateFiles(); // this->print(cout); cout << "SyntheticDataSimulation::start1" << endl; bool once = false; int j, k; Peer *peer_zero = NULL; j = 0; while ((peer_zero == NULL) || (peer_zero->getSemanticGroup()->getId() < 190)) peer_zero = (net->getPeers())[j++]; SuperPeer *super_peer_zero = (net->getSuperPeers())[0]; SuperPeer *super_peer_one = (net->getSuperPeers())[1]; cout << "id == " << super_peer_zero->getId() << endl; // super_peer_zero->setCacheSize(500); super_peer_zero->setDesiredLoad(MIN_SUPER_PEER_DESIRED_LOAD); super_peer_one->setDesiredLoad(MAX_SUPER_PEER_DESIRED_LOAD); peer_zero->deactivate(); for (int i = 0; i < N_PHASES; i++) { cout << "---------------- PHASE " << i << " -----------------" << endl; if (i == FAILURE_PHASE) { for (j = 0; j < (net->getNPeers() / 2); j++) net->deactivateRandomPeer(); for (j = 0; j < (net->getNSuperPeers() / 2); j++) net->deactivateRandomSuperPeer(); net->removeNonActive(); file_propagation_generator.propagateFiles(); file_propagation_generator.propagateFiles(); } if (i == PEER_JOINING_PHASE) { // cout << "PEER_JOINING_PHASE" << endl; peer_zero->activate(); for (j = 0; j < N_JOINING_PHASES; j++) { n_files_found_locally = n_files_found_remotely = n_files_missed = 0; int old_mode = execution_mode; execution_mode = STATIC_MODE; for (k = 0; k < N_JOINING_EVALUATION_PHASES; k++) peer_zero->search(); cout << "peer_zero n_files_found_locally " << n_files_found_locally << " n_files_found_remotely " << n_files_found_remotely << " n_files_missed " << n_files_missed << endl; execution_mode = old_mode; peer_zero->search(); } break; // peer_zero->deactivate(); } if (i % ADDITION_INVERSE_FREQUENCY == 0) { // cout << "Adding random files" << endl; file_propagation_generator.addRandomFiles(); // cout << "Propagating files" << endl; file_propagation_generator.propagateFiles(); } if (i % PROPAGATION_INVERSE_FREQUENCY == 0) { // cout << "Propagating files" << endl; file_propagation_generator.propagateFiles(); } // if (i % ADDITION_INVERSE_FREQUENCY == 0) // file_propagation_generator.addRandomFiles(); n_files_found_locally = n_files_found_remotely = n_files_missed = 0; for (j = 0; j < N_LOAD_CLASSES; j++) n_files_found_locally_load[j] = n_files_found_remotely_load[j] = 0; if (i == STATISTICS_RESET_PHASE) for (j = 0; j < nn_files; j++) n_found_locally[j] = n_found_remotely[j] = n_missed[j] = 0; // cout << "start1" << endl; // file_propagation_generator.propagateFiles(); // cout << "start2" << endl; vector::const_iterator iter; for (iter = semantic_groups.begin(); iter != semantic_groups.end(); iter++) { // cout << "Generating search for group: " << (*iter)->getId() << endl; (*iter)->generateSearch(); } /* for (int j = 0; j < N_SEARCHES_PER_PHASE; j++) { int group = group_selection_generator->getNext(); // cout << "start3: " << group << endl; // * vector::const_iterator iter; // * for (iter = semantic_groups.begin(); iter != semantic_groups.end(); // * iter++) // * (*iter)->generateSearch(); semantic_groups[group - 1]->generateSearch(); } */ // cout << "start4" << endl; if ((i > 49) && ((i % CACHE_CORRECTION_INVERSE_FREQUENCY) == 0)) { net->printLoadStatistics(cout); // cout << "super_peer_zero max_load " << // super_peer_zero->getMaxLoad() << " n_requests " << // super_peer_zero->getNRequests() << " cache_size " << // super_peer_zero->getCacheSize() << endl; // cout << "super_peer_one max_load " << // super_peer_one->getMaxLoad() << " n_requests " << // super_peer_one->getNRequests() << " cache_size " << // super_peer_one->getCacheSize() << endl; vector::const_iterator s_iter; for (s_iter = network.getSuperPeers().begin(); s_iter != network.getSuperPeers().end(); s_iter++) (*s_iter)->correctCacheSize(); } if ((i % LOAD_STATISTICS_PRINT_INVERSE_FREQUENCY) == 0) { vector::const_iterator iter; for (iter = (net->getSuperPeers()).begin(); iter != (net->getSuperPeers()).end(); iter++) cout << (*iter)->getId() << " desired_load: " << (*iter)->getDesiredLoad() << " service_rate: " << (*iter)->getServiceRate() << " n_requests: " << (*iter)->getNRequestsInWindow() << endl; } cout << "n_files_found_locally " << n_files_found_locally << " n_files_found_remotely " << n_files_found_remotely << " n_files_missed " << n_files_missed << endl; for (j = 0; j < N_LOAD_CLASSES; j++) cout << "desired_load " << (j + 1) / ((double) N_LOAD_CLASSES) << " n_files_found_locally_load " << n_files_found_locally_load[j] << " n_files_found_remotly_load " << n_files_found_remotely_load[j] << endl; n_global_requests = 0; if (i == 499) print(cout); } }; ostream& SyntheticDataSimulation::print(ostream& outs) { int superpeers_semgroups[network.getNSuperPeers()][semantic_groups.size()]; int i, j; for (i = 0; i < network.getNSuperPeers(); i++) for (j = 0; j < semantic_groups.size(); j++) superpeers_semgroups[i][j] = 0; outs << "--------------------- network ------------------------" << endl; cout << network; outs << endl << "----------------- semantic groups --------------------" << endl; vector::const_iterator iter; for (iter = semantic_groups.begin(); iter != semantic_groups.end(); iter++) cout << **iter << endl; outs << "-------------------- super peers ---------------------" << endl; vector &s_peers = network.getSuperPeers(); vector::const_iterator s_p_iter; for (s_p_iter = s_peers.begin(); s_p_iter != s_peers.end(); s_p_iter++) cout << **s_p_iter << endl; outs << "------------------------ peers -----------------------" << endl; vector &peers = network.getPeers(); vector::const_iterator p_iter; int superpeer_loads[network.getNSuperPeers()]; for (i = 0; i < network.getNSuperPeers(); i++) superpeer_loads[i] = 0; for (p_iter = peers.begin(); p_iter != peers.end(); p_iter++) { cout << **p_iter << endl; vector &neighbors = (*p_iter)->getNeighbors(); vector::const_iterator p_p_iter; for (p_p_iter = neighbors.begin(); p_p_iter != neighbors.end(); p_p_iter++) { superpeer_loads[(*p_p_iter)->getId() - 1]++; superpeers_semgroups[(*p_p_iter)->getId() - 1][(*p_iter)->getSemanticGroup()->getId() - 1]++; } } outs << endl << "----------- semantic groups vs superpeers ------------" << endl; i = 0; for (iter = semantic_groups.begin(); iter != semantic_groups.end(); iter++) { i++; for (p_iter = (*iter)->getPeers().begin(); p_iter != (*iter)->getPeers().end(); p_iter++) { cout << i << ":" << (*p_iter)->getId() << ":" << "{"; vector::const_iterator pp_iter; for (pp_iter = (*p_iter)->getNeighbors().begin(); pp_iter != (*p_iter)->getNeighbors().end(); pp_iter++) cout << (*pp_iter)->getId() << ","; cout << "}" << endl; } } outs << endl << "----------- superpeer loads ------------" << endl; for (i = 0; i < network.getNSuperPeers(); i++) { cout << i + 1 << " " << superpeer_loads[i] << endl; } for (i = 0; i < network.getNSuperPeers(); i++) { cout << i + 1 << " : "; for (j = 0; j < semantic_groups.size(); j++) cout << superpeers_semgroups[i][j] << " "; cout << endl; } outs << endl << "----- superpeer current loads and cache sizes -----" << endl; i = 0; for (s_p_iter = s_peers.begin(); s_p_iter != s_peers.end(); s_p_iter++) cout << ++i << " " << (*s_p_iter)->getNRequests() << " " << (*s_p_iter)->getCacheSize() << endl; }; ///////////////////////////////////////////////////////////////////////////// /////////////////////////// global functions //////////////////////////////// ///////////////////////////////////////////////////////////////////////////// void generateSyntheticData(int n_files, int n_categories, const char *output_file_name, int n_samplings) { cout << "generateSyntheticData(" << n_files << "," << n_categories << "," << output_file_name << "," << n_samplings << ")" << endl; int file_popularities[n_files]; RandomNumberGenerator *file_selection_generators[n_categories]; ZipfLawCategorySelectionGenerator category_selection_generator(n_files, n_categories, ALPHA); int i, category_id; for (i = 0; i < n_files; i++) file_popularities[i] = 1; for (i = 0; i < n_categories; i++) file_selection_generators[i] = new BalancedZipfLawCategoryGenerator(n_files, i + 1, n_categories, ALPHA); for (i = 0; i < n_samplings; i++) { category_id = category_selection_generator.getNext(); int file_id = file_selection_generators[category_id - 1]->getNext(); file_popularities[file_id - 1]++; } ofstream output(output_file_name, ios::out); if ((output.rdstate() & ofstream::failbit ) != 0) { cerr << "Error oppening file: " << output_file_name << endl; return; } int files_per_category = (int) n_files / n_categories; /* for (i = 0; i < n_files; i++) { // cout << (int) (1 + i / files_per_category) << " " << // file_popularities[i] << endl; category_id = (int) (1 + i / files_per_category); if (category_id > n_categories) category_id = n_categories; category_id = n_categories + 1 - category_id; output << category_id - 1 << " " << file_popularities[i] << endl; } */ for (i = n_files - 1; i >= 0; i--) { // cout << (int) (1 + i / files_per_category) << " " << // file_popularities[i] << endl; category_id = (int) (1 + i / files_per_category); if (category_id > n_categories) category_id = n_categories; category_id = n_categories + 1 - category_id; output << category_id - 1 << " " << file_popularities[i] << endl; } output.close(); }; ///////////////////////////////////////////////////////////////////////////// ////////////////////////////////// main ///////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// int main(int argc, char *argv[]) { if ((argc != 5) && (argc != 6) && (argc != 7)) { cerr << "usage: " << argv[0] << " [ []]\n"; exit(-1); } int n_peers = atoi(argv[1]); int n_super_peers = atoi(argv[2]); int n_files = atoi(argv[3]); int n_categories = atoi(argv[4]); int seed; int i; if (argc >= 6) { data_file_name = strdup(argv[5]); if (argc == 7) seed = atoi(argv[6]); else seed = time(NULL); } srandom(seed); // PermutationGenerator pg(10); // int *permutation = pg.getNextPermutation(); // for (i = 0; i < 10; i++) // cout << "permutation[" << i << "] == " << permutation[i] << endl; // return 0; // generateSyntheticData(n_files, n_categories, data_file_name, N_SAMPLINGS); // return 0; // MIN_SUPER_PEER_DESIRED_LOAD = 500 * CACHE_CORRECTION_INVERSE_FREQUENCY; // n_peers * PEER_NEIGHBOR_CACHE_SIZE / n_super_peers - // n_peers * PEER_NEIGHBOR_CACHE_SIZE / (2 * n_super_peers); // MAX_SUPER_PEER_MAX_LOAD = 3500 * CACHE_CORRECTION_INVERSE_FREQUENCY; // n_peers * PEER_NEIGHBOR_CACHE_SIZE / n_super_peers + // n_peers * PEER_NEIGHBOR_CACHE_SIZE / (2 * n_super_peers); // BalancedZipfLawCategoryGenerator bzlcg(100, 10, 10, .8); // for (i = 0; i < 100; i++) { // cout << bzlcg.getNext() << endl; // } // exit(-1); // ZipfLawCategoryGenerator zlcg(100, 1, 10, 1.0); // for (i = 0; i < 100; i++) { // cout << zlcg.getNext() << endl; // } /* ZipfLawCategorySelectionGenerator zlcsg(100, 10, ALPHA); for (i = 0; i < 100; i++) { cout << zlcsg.getNext() << endl; } */ /* PriorityQueue queue(10, 10); queue.incPriority(1.0); queue.print(cout) << endl; queue.incPriority(2.0); queue.print(cout) << endl; queue.incPriority(2.0); queue.print(cout) << endl; queue.incPriority(4.0); queue.print(cout) << endl; queue.incPriority(4.0); queue.print(cout) << endl; queue.incPriority(4.0); queue.print(cout) << endl; queue.incPriority(4.0); queue.print(cout) << endl; queue.incPriority(3.0); queue.print(cout) << endl; queue.incPriority(3.0); queue.print(cout) << endl; queue.incPriority(3.0); queue.print(cout) << endl; cout << endl; // queue.incPriority(1.0); for (i = 0; i < 100; i++) { cout << queue.selectRandomly() << endl; } */ // RandomNumberGenerator *gen; // = new FileDefinedCategorySelectionGenerator(data_file_name); // cout << "Loaded" << endl; // for (i = 0; i < 1000; i++) // cout << gen->getNext() << endl; // gen = new FileDefinedCategoryGenerator(ALPHA, data_file_name); // cout << ((FileDefinedCategoryGenerator *) gen)->getOptimalHitRatio(n_files, // n_categories) << endl; // for (i = 0; i < 10000; i++) // cout << ((FileDefinedCategoryGenerator *) gen)->getNext(10) << endl; // return 0; timer1.start(); SyntheticDataSimulation simulation(n_peers, n_super_peers, n_files, n_categories); n_found_locally = new int[n_files]; n_found_remotely = new int[n_files]; n_missed = new int[n_files]; for (i = 0; i < n_files; i++) n_found_locally[i] = n_found_remotely[i] = n_missed[i] = 0; // simulation.print(cout); simulation.start(); simulation.print(cout); double last_ratio = 1.; for (i = 0; i < n_files; i++) { if (n_found_locally[i] + n_found_remotely[i] != 0) last_ratio = ((double) n_found_locally[i]) / (n_found_locally[i] + n_found_remotely[i]); cout << i + 1 << " " << n_found_locally[i] << " " << n_found_remotely[i] << " " << last_ratio << " " << n_missed[i] << endl; } timer1.stop(); cout << "timer1: " << timer1.getTime() << " timer2: " << timer2.getTime() << " timer3: " << timer3.getTime() << " timer4: " << timer4.getTime() << " timer5: " << timer5.getTime() << endl; delete [] n_found_locally; delete [] n_found_remotely; // cout << seed << endl; // ZipfLawGenerator zlg(n_files); // printf("Power law generator constructed\n"); // FilesPopularities fp(n_files, plg); // printf("Files popularities constructed\n"); /* for (i = 1; i <= n_files + 1; i++) { int j = -1; while (j != i) { j = zlg.getNext(); // int *k = plg.getSequence(1); // j = k[0]; // delete [] k; cout << "zlg.getNext() == " << i << endl; } } return 0; */ // cout << "Zyje" << endl; // printf("Graph constructed\n"); return 0; }