| 941 | } |
| 942 | |
| 943 | void |
| 944 | Cache::build_stripe_hash_table() |
| 945 | { |
| 946 | int num_stripes = globalVec_stripe.size(); |
| 947 | CacheStoreBlocks total; |
| 948 | unsigned int *forvol = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_stripes)); |
| 949 | unsigned int *gotvol = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_stripes)); |
| 950 | unsigned int *rnd = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_stripes)); |
| 951 | unsigned short *ttable = static_cast<unsigned short *>(ats_malloc(sizeof(unsigned short) * STRIPE_HASH_TABLE_SIZE)); |
| 952 | unsigned int *rtable_entries = static_cast<unsigned int *>(ats_malloc(sizeof(unsigned int) * num_stripes)); |
| 953 | unsigned int rtable_size = 0; |
| 954 | int i = 0; |
| 955 | uint64_t used = 0; |
| 956 | |
| 957 | // estimate allocation |
| 958 | for (auto &elt : globalVec_stripe) { |
| 959 | // printf("stripe length %" PRId64 "\n", elt->_len.count()); |
| 960 | rtable_entries[i] = static_cast<int64_t>(elt->_len) / Vol_hash_alloc_size; |
| 961 | rtable_size += rtable_entries[i]; |
| 962 | uint64_t x = elt->hash_id.fold(); |
| 963 | // seed random number generator |
| 964 | rnd[i] = static_cast<unsigned int>(x); |
| 965 | total += elt->_len; |
| 966 | i++; |
| 967 | } |
| 968 | i = 0; |
| 969 | for (auto &elt : globalVec_stripe) { |
| 970 | forvol[i] = total ? static_cast<int64_t>(STRIPE_HASH_TABLE_SIZE * elt->_len) / total : 0; |
| 971 | used += forvol[i]; |
| 972 | gotvol[i] = 0; |
| 973 | i++; |
| 974 | } |
| 975 | |
| 976 | // spread around the excess |
| 977 | int extra = STRIPE_HASH_TABLE_SIZE - used; |
| 978 | for (int i = 0; i < extra; i++) { |
| 979 | forvol[i % num_stripes]++; |
| 980 | } |
| 981 | |
| 982 | // initialize table to "empty" |
| 983 | for (int i = 0; i < STRIPE_HASH_TABLE_SIZE; i++) { |
| 984 | ttable[i] = STRIPE_HASH_EMPTY; |
| 985 | } |
| 986 | |
| 987 | // generate random numbers proportional to allocation |
| 988 | rtable_pair *rtable = static_cast<rtable_pair *>(ats_malloc(sizeof(rtable_pair) * rtable_size)); |
| 989 | int rindex = 0; |
| 990 | for (int i = 0; i < num_stripes; i++) { |
| 991 | for (int j = 0; j < static_cast<int>(rtable_entries[i]); j++) { |
| 992 | rtable[rindex].rval = next_rand(&rnd[i]); |
| 993 | rtable[rindex].idx = i; |
| 994 | rindex++; |
| 995 | } |
| 996 | } |
| 997 | assert(rindex == (int)rtable_size); |
| 998 | // sort (rand #, vol $ pairs) |
| 999 | qsort(rtable, rtable_size, sizeof(rtable_pair), cmprtable); |
| 1000 | unsigned int width = (1LL << 32) / STRIPE_HASH_TABLE_SIZE; |
no test coverage detected