mirror of
https://github.com/ceph/ceph
synced 2025-01-05 10:42:05 +00:00
07ac5d3e74
git-svn-id: https://ceph.svn.sf.net/svnroot/ceph@1068 29311d96-e01e-0410-9327-a35deaab8ce9
267 lines
5.9 KiB
C++
267 lines
5.9 KiB
C++
|
|
|
|
#include "../crush/crush.h"
|
|
using namespace crush;
|
|
|
|
#include <math.h>
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
using namespace std;
|
|
|
|
/*
|
|
ostream& operator<<(ostream& out, vector<int>& v)
|
|
{
|
|
out << "[";
|
|
for (int i=0; i<v.size(); i++) {
|
|
if (i) out << " ";
|
|
out << v[i];
|
|
}
|
|
out << "]";
|
|
return out;
|
|
}
|
|
*/
|
|
|
|
void make_disks(int n, int& no, vector<int>& d)
|
|
{
|
|
d.clear();
|
|
while (n) {
|
|
d.push_back(no);
|
|
no++;
|
|
n--;
|
|
}
|
|
}
|
|
|
|
|
|
Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks, int& nbuckets)
|
|
{
|
|
if (h == 0) {
|
|
// uniform
|
|
Hash hash(123);
|
|
vector<int> disks;
|
|
for (int i=0; i<wid[h]; i++)
|
|
disks.push_back(ndisks++);
|
|
UniformBucket *b = new UniformBucket(nbuckets--, 1, 0, 10, disks);
|
|
b->make_primes(hash);
|
|
c.add_bucket(b);
|
|
//cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
|
|
return b;
|
|
} else {
|
|
// mixed
|
|
MixedBucket *b = new MixedBucket(nbuckets--, h+1);
|
|
for (int i=0; i<wid[h]; i++) {
|
|
Bucket *n = make_bucket(c, wid, h-1, ndisks, nbuckets);
|
|
b->add_item(n->get_id(), n->get_weight());
|
|
}
|
|
c.add_bucket(b);
|
|
//cout << h << " mixedbucket with " << wid[h] << endl;
|
|
return b;
|
|
}
|
|
}
|
|
|
|
int make_hierarchy(Crush& c, vector<int>& wid, int& ndisks, int& nbuckets)
|
|
{
|
|
Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks, nbuckets);
|
|
return b->get_id();
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
{
|
|
Hash h(73232313);
|
|
|
|
// crush
|
|
Crush c;
|
|
|
|
|
|
// buckets
|
|
vector<int> disks;
|
|
int root = -1;
|
|
int nbuckets = -1;
|
|
int ndisks = 0;
|
|
|
|
if (0) {
|
|
make_disks(12, ndisks, disks);
|
|
UniformBucket ub1(-1, 1, 0, 30, disks);
|
|
ub1.make_primes(h);
|
|
cout << "ub1 primes are " << ub1.primes << endl;
|
|
c.add_bucket(&ub1);
|
|
|
|
make_disks(17, ndisks, disks);
|
|
UniformBucket ub2(-2, 1, 0, 30, disks);
|
|
ub2.make_primes(h);
|
|
cout << "ub2 primes are " << ub2.primes << endl;
|
|
c.add_bucket(&ub2);
|
|
|
|
make_disks(4, ndisks, disks);
|
|
UniformBucket ub3(-3, 1, 0, 30, disks);
|
|
ub3.make_primes(h);
|
|
cout << "ub3 primes are " << ub3.primes << endl;
|
|
c.add_bucket(&ub3);
|
|
|
|
make_disks(20, ndisks, disks);
|
|
MixedBucket umb1(-4, 1);
|
|
for (int i=0; i<20; i++)
|
|
umb1.add_item(disks[i], 30);
|
|
c.add_bucket(&umb1);
|
|
|
|
MixedBucket b(-100, 1);
|
|
//b.add_item(-2, ub1.get_weight());
|
|
b.add_item(-4, umb1.get_weight());
|
|
//b.add_item(-2, ub2.get_weight());
|
|
//b.add_item(-3, ub3.get_weight());
|
|
}
|
|
|
|
if (0) {
|
|
int bucket = -1;
|
|
MixedBucket *root = new MixedBucket(bucket--, 2);
|
|
|
|
for (int i=0; i<5; i++) {
|
|
MixedBucket *b = new MixedBucket(bucket--, 1);
|
|
|
|
int n = 5;
|
|
|
|
if (1) {
|
|
// add n buckets of n disks
|
|
for (int j=0; j<n; j++) {
|
|
|
|
MixedBucket *d = new MixedBucket(bucket--, 1);
|
|
|
|
make_disks(n, ndisks, disks);
|
|
for (int k=0; k<n; k++)
|
|
d->add_item(disks[k], 10);
|
|
|
|
//b->add_item(disks[j], 10);
|
|
c.add_bucket(d);
|
|
b->add_item(d->get_id(), d->get_weight());
|
|
}
|
|
|
|
c.add_bucket(b);
|
|
root->add_item(b->get_id(), b->get_weight());
|
|
} else {
|
|
// add n*n disks
|
|
make_disks(n*n, ndisks, disks);
|
|
for (int k=0; k<n*n; k++)
|
|
b->add_item(disks[k], 10);
|
|
|
|
c.add_bucket(b);
|
|
root->add_item(b->get_id(), b->get_weight());
|
|
}
|
|
}
|
|
|
|
c.add_bucket(root);
|
|
}
|
|
|
|
|
|
if (1) {
|
|
vector<int> wid;
|
|
for (int d=0; d<5; d++)
|
|
wid.push_back(10);
|
|
root = make_hierarchy(c, wid, ndisks, nbuckets);
|
|
}
|
|
|
|
|
|
|
|
// rule
|
|
int numrep = 1;
|
|
|
|
Rule rule;
|
|
if (0) {
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, -100));
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
|
|
}
|
|
if (1) {
|
|
/*
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, -4));
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, 2, 0));
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
|
|
*/
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, 1, 0));
|
|
rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
|
|
}
|
|
|
|
//c.overload[10] = .1;
|
|
|
|
|
|
int pg_per = 100;
|
|
int numpg = pg_per*ndisks/numrep;
|
|
|
|
vector<int> ocount(ndisks);
|
|
cout << ndisks << " disks, " << 1-nbuckets << " buckets" << endl;
|
|
cout << pg_per << " pgs per disk" << endl;
|
|
cout << numpg << " logical pgs" << endl;
|
|
cout << "numrep is " << numrep << endl;
|
|
|
|
|
|
int place = 1000000;
|
|
int times = place / numpg;
|
|
if (!times) times = 1;
|
|
|
|
cout << "looping " << times << " times" << endl;
|
|
|
|
float tvar = 0;
|
|
int tvarnum = 0;
|
|
|
|
int x = 0;
|
|
for (int t=0; t<times; t++) {
|
|
vector<int> v(numrep);
|
|
|
|
for (int z=0; z<ndisks; z++) ocount[z] = 0;
|
|
|
|
for (int xx=1; xx<numpg; xx++) {
|
|
x++;
|
|
|
|
//cout << H(x) << "\t" << h(x) << endl;
|
|
c.do_rule(rule, x, v);
|
|
//cout << "v = " << v << endl;// " " << v[0] << " " << v[1] << " " << v[2] << endl;
|
|
|
|
bool bad = false;
|
|
for (int i=0; i<numrep; i++) {
|
|
//int d = b.choose_r(x, i, h);
|
|
//v[i] = d;
|
|
ocount[v[i]]++;
|
|
for (int j=i+1; j<numrep; j++) {
|
|
if (v[i] == v[j])
|
|
bad = true;
|
|
}
|
|
}
|
|
if (bad)
|
|
cout << "bad set " << x << ": " << v << endl;
|
|
|
|
//cout << v << "\t" << ocount << endl;
|
|
}
|
|
|
|
/*
|
|
for (int i=0; i<ocount.size(); i++) {
|
|
cout << "disk " << i << " has " << ocount[i] << endl;
|
|
}
|
|
*/
|
|
|
|
cout << "collisions: " << c.collisions << endl;
|
|
cout << "r bumps: " << c.bumps << endl;
|
|
|
|
|
|
float avg = 0.0;
|
|
for (int i=0; i<ocount.size(); i++)
|
|
avg += ocount[i];
|
|
avg /= ocount.size();
|
|
float var = 0.0;
|
|
for (int i=0; i<ocount.size(); i++)
|
|
var += (ocount[i] - avg) * (ocount[i] - avg);
|
|
var /= ocount.size();
|
|
|
|
cout << "avg " << avg << " var " << var << " sd " << sqrt(var) << endl;
|
|
|
|
tvar += var;
|
|
tvarnum++;
|
|
}
|
|
|
|
tvar /= tvarnum;
|
|
|
|
cout << "total variance " << tvar << endl;
|
|
|
|
|
|
}
|