+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_crush_BINARYTREE_H
-#define CEPH_crush_BINARYTREE_H
-
-#include <cassert>
-#include <iostream>
-#include <map>
-#include <vector>
-using std::map;
-using std::vector;
-
-#include "include/buffer.h"
-
-namespace crush {
-
- class BinaryTree {
- private:
- // tree def
- int root_node; // 0 for empty tree.
- int alloc;
- vector<int> node_nested; // all existing nodes in this map
- vector<float> node_weight; // and this one
- vector<int> node_complete; // only nodes with all possible children
-
- public:
- BinaryTree() : root_node(0), alloc(0) {}
-
- void _encode(bufferlist& bl) {
- bl.append((char*)&root_node, sizeof(root_node));
- bl.append((char*)&alloc, sizeof(alloc));
- ::_encode(node_nested, bl);
- ::_encode(node_weight, bl);
- ::_encode(node_complete, bl);
- }
- void _decode(bufferlist& bl, int& off) {
- bl.copy(off, sizeof(root_node), (char*)&root_node);
- off += sizeof(root_node);
- bl.copy(off, sizeof(alloc), (char*)&alloc);
- off += sizeof(alloc);
- ::_decode(node_nested, bl, off);
- ::_decode(node_weight, bl, off);
- ::_decode(node_complete, bl, off);
- }
-
- // accessors
- bool empty() const { return root_node == 0; }
- bool exists(int n) const { return n < alloc && node_nested[n]; }
- int nested(int n) const { return exists(n) ? node_nested[n]:0; }
- float weight(int n) const { return exists(n) ? node_weight[n]:0; }
- bool complete(int n) const { return exists(n) ? node_complete[n]:false; }
-
- int root() const { return root_node; }
-
- void realloc(int n) {
- /*
- while (alloc <= n) {
- node_nested.push_back(0);
- node_weight.push_back(0);
- node_complete.push_back(0);
- alloc++;
- }
- */
- if (alloc <= n) {
- int add = n - alloc + 1;
- node_nested.insert(node_nested.end(), add, 0);
- node_weight.insert(node_weight.end(), add, 0);
- node_complete.insert(node_complete.end(), add, 0);
- alloc = n+1;
- }
- }
-
- // tree navigation
- bool terminal(int n) const { return n & 1; } // odd nodes are leaves.
- int height(int n) const {
- assert(n);
- int h = 0;
- while ((n & 1) == 0) {
- assert(n > 0);
- h++; n = n >> 1;
- }
- return h;
- }
- int left(int n) const {
- int h = height(n);
- //cout << "left of " << n << " is " << (n - (1 << h)) << std::endl;
- return n - (1 << (h-1));
- }
- int right(int n) const {
- int h = height(n);
- //cout << "right of " << n << " is " << (n + (1 << h)) << std::endl;
- return n + (1 << (h-1));
- }
- bool on_right(int n, int h = -1) const {
- if (h < 0) h = height(n);
- return n & (1 << (h+1));
- }
- bool on_left(int n) const { return !on_right(n); }
- int parent(int n) const {
- int h = height(n);
- if (on_right(n, h))
- return n - (1<<h);
- else
- return n + (1<<h);
- }
-
- // modifiers
- void adjust_node_weight(int n, float w) {
- assert(exists(n));
- node_weight[n] += w;
-
- int p = n;
- while (p != root_node) {
- p = parent(p);
- node_weight[p] += w;
- }
- }
-
- void remove_node(int n) {
- assert(exists(n));
-
- // erase node
- node_nested[n] = 0;
- node_weight[n] = 0;
-
- // adjust parents (!complete, -weight)
- int p = n;
- while (p != root_node) {
- p = parent(p);
-
- node_complete[p] = 0;
- node_weight[p] = weight(left(p)) + weight(right(p));
- node_nested[p]--;
-
- if (nested(p) == 0) {
- node_weight[p] = 0;
- node_nested[p] = 0;
- }
- }
-
- // hose root?
- while (!terminal(root_node) &&
- (nested(left(root_node)) == 0 ||
- nested(right(root_node)) == 0)) {
- // root now one child..
- node_weight[root_node] = 0;
- node_nested[root_node] = 0;
- if (nested(left(root_node)) == 0)
- root_node = right(root_node);
- else
- root_node = left(root_node);
- }
-
- if (terminal(root_node) &&
- nested(root_node) == 0) {
- // empty!
- node_weight[root_node] = 0;
- node_nested[root_node] = 0;
- root_node = 0;
- }
-
- }
-
- int add_node_root(float w) {
- return add_node(w, true);
- }
-
- int add_node(float w, bool force_root=false) {
- int n;
- if (!root_node) {
- // empty tree!
- root_node = n = 1;
- } else {
- // existing tree.
- // expand tree?
- if (force_root || complete(root_node)) {
- // add new root
- int newroot = parent(root_node);
- realloc(newroot);
- node_weight[newroot] = node_weight[root_node];
- node_nested[newroot] = nested(root_node);
-
- // go right or left?
- if (left(newroot) == root_node)
- n = right(newroot);
- else
- n = left(newroot);
- root_node = newroot;
-
- // then go left until terminal
- while (!terminal(n))
- n = left(n);
- }
- else {
- // tree isn't complete.
- n = root_node;
- while (!terminal(n)) {
- if (!exists(left(n)) || !complete(left(n))) {
- // left isn't complete
- n = left(n);
- } else {
- assert(!exists(right(n)) || !complete(right(n)));
- // right isn't complete
- n = right(n);
- }
- }
- }
- }
-
- // create at n
- //cout << "creating " << n << std::endl;
- realloc(n);
- node_weight[n] = w;
- node_nested[n] = 1;
- node_complete[n] = 1;
-
- // ancestors: create, adjust weight, complete as appropriate
- int p = n;
- while (p != root_node) {
- p = parent(p);
- realloc(p);
-
- // complete?
- if (!complete(p) &&
- complete(left(p)) &&
- complete(right(p)))
- node_complete[p] = 1;
-
- // weight (and implicitly create)
- node_weight[p] += w;
- node_nested[p]++;
- }
-
- return n;
-
- }
-
-
- };
-
-
- // print it out
- inline void print_binary_tree_node(ostream& out, const BinaryTree& tree, int n, int i) {
- for (int t=i; t>0; t--) out << " ";
- if (tree.root() == n)
- out << "root ";
- else {
- if (tree.on_left(n))
- out << "left ";
- else
- out << "right ";
- }
- out << n << " : nested " << tree.nested(n) << " weight " << tree.weight(n);
- if (tree.complete(n)) out << " complete";
- out << std::endl;
- if (!tree.terminal(n)) {
- if (tree.exists(tree.left(n)))
- print_binary_tree_node(out, tree, tree.left(n), i+2);
- if (tree.exists(tree.right(n)))
- print_binary_tree_node(out, tree, tree.right(n), i+2);
- }
- }
-
- inline ostream& operator<<(ostream& out, const BinaryTree& tree) {
- if (tree.empty())
- return out << "tree is empty";
- print_binary_tree_node(out, tree, tree.root(), 0);
- return out;
- }
-
-}
-
-#endif
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_crush_BUCKET_H
-#define CEPH_crush_BUCKET_H
-
-#include "BinaryTree.h"
-#include "Hash.h"
-
-#include <list>
-#include <vector>
-#include <map>
-#include <set>
-using namespace std;
-
-#include <math.h>
-
-#include "include/buffer.h"
-
-namespace crush {
-
-
- const int CRUSH_BUCKET_UNIFORM = 1;
- const int CRUSH_BUCKET_TREE = 2;
- const int CRUSH_BUCKET_LIST = 3;
- const int CRUSH_BUCKET_STRAW = 4;
-
- /** abstract bucket **/
- class Bucket {
- protected:
- int id;
- int parent;
- int type;
- float weight;
-
- public:
- Bucket(int _type,
- float _weight) :
- id(0), parent(0),
- type(_type),
- weight(_weight) { }
-
- Bucket(bufferlist& bl, int& off) {
- bl.copy(off, sizeof(id), (char*)&id);
- off += sizeof(id);
- bl.copy(off, sizeof(parent), (char*)&parent);
- off += sizeof(parent);
- bl.copy(off, sizeof(type), (char*)&type);
- off += sizeof(type);
- bl.copy(off, sizeof(weight), (char*)&weight);
- off += sizeof(weight);
- }
-
- virtual ~Bucket() { }
-
- virtual const char *get_bucket_type() const = 0;
- virtual bool is_uniform() const = 0;
-
- int get_id() const { return id; }
- int get_type() const { return type; }
- float get_weight() const { return weight; }
- int get_parent() const { return parent; }
- virtual int get_size() const = 0;
-
- void set_id(int i) { id = i; }
- void set_parent(int p) { parent = p; }
- void set_weight(float w) { weight = w; }
-
- virtual void get_items(vector<int>& i) const = 0;
- virtual float get_item_weight(int item) const = 0;
- virtual void add_item(int item, float w, bool back=false) = 0;
- virtual void adjust_item_weight(int item, float w) = 0;
- virtual void set_item_weight(int item, float w) {
- adjust_item_weight(item, w - get_item_weight(item));
- }
-
- virtual int choose_r(int x, int r, Hash& h) const = 0;
-
- virtual void _encode(bufferlist& bl) = 0;
- };
-
-
-
-
- /** uniform bucket **/
- class UniformBucket : public Bucket {
- protected:
- public:
- vector<int> items;
- int item_type;
- float item_weight;
-
- // primes
- vector<unsigned> primes;
-
- int get_prime(int j) const {
- return primes[ j % primes.size() ];
- }
- void make_primes() {
- if (items.empty()) return;
-
- //cout << "make_primes " << get_id() << " " << items.size() << endl;
- Hash h(123+get_id());
- primes.clear();
-
- // start with odd number > num_items
- unsigned x = items.size() + 1; // this is the minimum!
- x += h(items.size()) % (3*items.size()); // bump it up some
- x |= 1; // make it odd
-
- while (primes.size() < items.size()) {
- unsigned j;
- for (j=2; j*j<=x; j++)
- if (x % j == 0) break;
- if (j*j > x) {
- primes.push_back(x);
- //cout << "prime " << x << endl;
- }
- x += 2;
- }
- }
-
- public:
- UniformBucket(int _type, int _item_type) :
- Bucket(_type, 0),
- item_type(_item_type) { }
- UniformBucket(int _type, int _item_type,
- float _item_weight, vector<int>& _items) :
- Bucket(_type, _item_weight*_items.size()),
- item_type(_item_type),
- item_weight(_item_weight) {
- items = _items;
- make_primes();
- }
-
- UniformBucket(bufferlist& bl, int& off) : Bucket(bl, off) {
- bl.copy(off, sizeof(item_type), (char*)&item_type);
- off += sizeof(item_type);
- bl.copy(off, sizeof(item_weight), (char*)&item_weight);
- off += sizeof(item_weight);
- ::_decode(items, bl, off);
- make_primes();
- }
-
- void _encode(bufferlist& bl) {
- char t = CRUSH_BUCKET_UNIFORM;
- bl.append((char*)&t, sizeof(t));
- bl.append((char*)&id, sizeof(id));
- bl.append((char*)&parent, sizeof(parent));
- bl.append((char*)&type, sizeof(type));
- bl.append((char*)&weight, sizeof(weight));
-
- bl.append((char*)&item_type, sizeof(item_type));
- bl.append((char*)&item_weight, sizeof(item_weight));
-
- ::_encode(items, bl);
- }
-
- const char *get_bucket_type() const { return "uniform"; }
- bool is_uniform() const { return true; }
-
- int get_size() const { return items.size(); }
-
- // items
- void get_items(vector<int>& i) const {
- i = items;
- }
- int get_item_type() const { return item_type; }
- float get_item_weight(int item) const { return item_weight; }
-
- void add_item(int item, float w, bool back=false) {
- if (items.empty())
- item_weight = w;
- items.push_back(item);
- weight += item_weight;
- make_primes();
- }
-
- void adjust_item_weight(int item, float w) {
- assert(0);
- }
-
- int choose_r(int x, int r, Hash& hash) const {
- //cout << "uniformbucket.choose_r(" << x << ", " << r << ")" << endl;
- //if (r >= get_size()) cout << "warning: r " << r << " >= " << get_size() << " uniformbucket.size" << endl;
-
- unsigned v = hash(x, get_id());// % get_size();
- unsigned p = get_prime( hash(get_id(), x) ); // choose a prime based on hash(x, get_id(), 2)
- unsigned s = (x + v + (r+1)*p) % get_size();
- return items[s];
- }
-
- };
-
-
-
-
-
- // list bucket.. RUSH_P sorta
-
- class ListBucket : public Bucket {
- protected:
- list<int> items;
- list<float> item_weight;
- list<float> sum_weight;
-
- public:
- ListBucket(int _type) : Bucket(_type, 0) { }
-
- ListBucket(bufferlist& bl, int& off) : Bucket(bl, off) {
- ::_decode(items, bl, off);
- ::_decode(item_weight, bl, off);
- ::_decode(sum_weight, bl, off);
- }
-
- void _encode(bufferlist& bl) {
- char t = CRUSH_BUCKET_LIST;
- bl.append((char*)&t, sizeof(t));
- bl.append((char*)&id, sizeof(id));
- bl.append((char*)&parent, sizeof(parent));
- bl.append((char*)&type, sizeof(type));
- bl.append((char*)&weight, sizeof(weight));
-
- ::_encode(items, bl);
- ::_encode(item_weight, bl);
- ::_encode(sum_weight, bl);
- }
-
- const char *get_bucket_type() const { return "list"; }
- bool is_uniform() const { return false; }
-
- int get_size() const { return items.size(); }
-
- void get_items(vector<int>& i) const {
- for (list<int>::const_iterator it = items.begin();
- it != items.end();
- it++)
- i.push_back(*it);
- }
- float get_item_weight(int item) const {
- list<int>::const_iterator i = items.begin();
- list<float>::const_iterator w = item_weight.begin();
- while (i != items.end()) {
- if (*i == item) return *w;
- i++; w++;
- }
- assert(0);
- return 0;
- }
-
- void add_item(int item, float w, bool back=false) {
- if (back) {
- items.push_back(item);
- item_weight.push_back(w);
- sum_weight.clear();
- float s = 0.0;
- for (list<float>::reverse_iterator i = item_weight.rbegin();
- i != item_weight.rend();
- i++) {
- s += *i;
- sum_weight.push_front(s);
- }
- weight += w;
- assert(weight == s);
- } else {
- items.push_front(item);
- item_weight.push_front(w);
- weight += w;
- sum_weight.push_front(weight);
- }
- }
-
- void adjust_item_weight(int item, float dw) {
- // find it
- list<int>::iterator p = items.begin();
- list<float>::iterator pw = item_weight.begin();
- list<float>::iterator ps = sum_weight.begin();
-
- while (*p != item) {
- *ps += dw;
- p++; pw++; ps++; // next!
- assert(p != items.end());
- }
-
- assert(*p == item);
- *pw += dw;
- *ps += dw;
- }
-
-
- int choose_r(int x, int r, Hash& h) const {
- //cout << "linearbucket.choose_r(" << x << ", " << r << ")" << endl;
-
- list<int>::const_iterator p = items.begin();
- list<float>::const_iterator pw = item_weight.begin();
- list<float>::const_iterator ps = sum_weight.begin();
-
- while (p != items.end()) {
- const int item = *p;
- const float iw = *pw;
- const float tw = *ps;
- const float f = (float)(h(x, item, r, get_id()) % 10000) * tw / 10000.0;
- //cout << "item " << item << " iw = " << iw << " tw = " << tw << " f = " << f << endl;
- if (f < iw) {
- //cout << "linearbucket.choose_r(" << x << ", " << r << ") = " << item << endl;
- return item;
- }
- p++; pw++; ps++; // next!
- }
- assert(0);
- return 0;
- }
-
-
- };
-
-
-
-
- // mixed bucket, based on RUSH_T type binary tree
-
- class TreeBucket : public Bucket {
- protected:
- //vector<float> item_weight;
-
- // public:
- BinaryTree tree;
- map<int,int> node_item; // node id -> item
- vector<int> node_item_vec; // fast version of above
- map<int,int> item_node; // item -> node id
- map<int,float> item_weight;
-
- public:
- TreeBucket(int _type) : Bucket(_type, 0) { }
-
- TreeBucket(bufferlist& bl, int& off) : Bucket(bl, off) {
- tree._decode(bl, off);
-
- ::_decode(node_item, bl, off);
- ::_decode(node_item_vec, bl, off);
- ::_decode(item_node, bl, off);
- ::_decode(item_weight, bl, off);
- }
-
- void _encode(bufferlist& bl) {
- char t = CRUSH_BUCKET_TREE;
- bl.append((char*)&t, sizeof(t));
- bl.append((char*)&id, sizeof(id));
- bl.append((char*)&parent, sizeof(parent));
- bl.append((char*)&type, sizeof(type));
- bl.append((char*)&weight, sizeof(weight));
-
- tree._encode(bl);
-
- ::_encode(node_item, bl);
- ::_encode(node_item_vec, bl);
- ::_encode(item_node, bl);
- ::_encode(item_weight, bl);
- }
-
- const char *get_bucket_type() const { return "tree"; }
- bool is_uniform() const { return false; }
-
- int get_size() const { return node_item.size(); }
-
- // items
- void get_items(vector<int>& i) const {
- for (map<int,int>::const_iterator it = node_item.begin();
- it != node_item.end();
- it++)
- i.push_back(it->second);
- }
- float get_item_weight(int i) const {
- assert(item_weight.count(i));
- return ((map<int,float>)item_weight)[i];
- }
-
-
- void add_item(int item, float w, bool back=false) {
- item_weight[item] = w;
- weight += w;
-
- unsigned n = tree.add_node(w);
- node_item[n] = item;
- item_node[item] = n;
-
- while (node_item_vec.size() <= n)
- node_item_vec.push_back(0);
- node_item_vec[n] = item;
- }
-
- void adjust_item_weight(int item, float dw) {
- // adjust my weight
- weight += dw;
- item_weight[item] += dw;
-
- // adjust tree weights
- tree.adjust_node_weight(item_node[item], dw);
- }
-
- int choose_r(int x, int r, Hash& h) const {
- //cout << "mixedbucket.choose_r(" << x << ", " << r << ")" << endl;
- int n = tree.root();
- while (!tree.terminal(n)) {
- // pick a point in [0,w)
- float w = tree.weight(n);
- float f = (float)(h(x, n, r, get_id()) % 10000) * w / 10000.0;
-
- // left or right?
- int l = tree.left(n);
- if (tree.exists(l) &&
- f < tree.weight(l))
- n = l;
- else
- n = tree.right(n);
- }
- //assert(node_item.count(n));
- //return ((map<int,int>)node_item)[n];
- return node_item_vec[n];
- }
- };
-
-
-
-
-
- // straw bucket.. new thing!
-
- class StrawBucket : public Bucket {
- protected:
- map<int, float> item_weight;
- map<int, float> item_straw;
-
- list<int> _items;
- list<float> _straws;
-
- public:
- StrawBucket(int _type) : Bucket(_type, 0) { }
-
- StrawBucket(bufferlist& bl, int& off) : Bucket(bl, off) {
- ::_decode(item_weight, bl, off);
- calc_straws();
- }
-
- void _encode(bufferlist& bl) {
- char t = CRUSH_BUCKET_TREE;
- bl.append((char*)&t, sizeof(t));
- bl.append((char*)&id, sizeof(id));
- bl.append((char*)&parent, sizeof(parent));
- bl.append((char*)&type, sizeof(type));
- bl.append((char*)&weight, sizeof(weight));
-
- ::_encode(item_weight, bl);
- }
-
- const char *get_bucket_type() const { return "straw"; }
- bool is_uniform() const { return false; }
-
- int get_size() const { return item_weight.size(); }
-
-
- // items
- void get_items(vector<int>& i) const {
- for (map<int,float>::const_iterator it = item_weight.begin();
- it != item_weight.end();
- it++)
- i.push_back(it->first);
- }
- float get_item_weight(int item) const {
- assert(item_weight.count(item));
- return ((map<int,float>)item_weight)[item];
- }
-
- void add_item(int item, float w, bool back=false) {
- item_weight[item] = w;
- weight += w;
- calc_straws();
- }
-
- void adjust_item_weight(int item, float dw) {
- //cout << "adjust " << item << " " << dw << endl;
- weight += dw;
- item_weight[item] += dw;
- calc_straws();
- }
-
-
- /* calculate straw lengths.
- this is kind of ugly. not sure if there's a closed form way to calculate this or not!
- */
- void calc_straws() {
- //cout << get_id() << ": calc_straws ============" << endl;
-
- item_straw.clear();
- _items.clear();
- _straws.clear();
-
- // reverse sort by weight; skip zero weight items
- map<float, set<int> > reverse;
- for (map<int, float>::iterator p = item_weight.begin();
- p != item_weight.end();
- p++) {
- //cout << get_id() << ":" << p->first << " " << p->second << endl;
- if (p->second > 0) {
- //p->second /= minw;
- reverse[p->second].insert(p->first);
- }
- }
-
- /* 1:2:7
- item_straw[0] = 1.0;
- item_straw[1] = item_straw[0]*sqrt(1.0/.6);
- item_straw[2] = item_straw[1]*2.0;
- */
-
- // work from low to high weights
- float straw = 1.0;
- float numleft = item_weight.size();
- float wbelow = 0.0;
- float lastw = 0.0;
-
- map<float, set<int> >::iterator next = reverse.begin();
- //while (next != reverse.end()) {
- while (1) {
- //cout << "hi " << next->first << endl;
- map<float, set<int> >::iterator cur = next;
-
- // set straw length for this set
- for (set<int>::iterator s = cur->second.begin();
- s != cur->second.end();
- s++) {
- item_straw[*s] = straw;
- //cout << "straw " << *s << " w " << item_weight[*s] << " -> " << straw << endl;
- _items.push_back(*s);
- _straws.push_back(straw);
- }
-
- next++;
- if (next == reverse.end()) break;
-
- wbelow += (cur->first-lastw) * numleft;
- //cout << "wbelow " << wbelow << endl;
-
- numleft -= 1.0 * (float)cur->second.size();
- //cout << "numleft now " << numleft << endl;
-
- float wnext = numleft * (next->first - cur->first);
- //cout << "wnext " << wnext << endl;
-
- float pbelow = wbelow / (wbelow+wnext);
- //cout << "pbelow " << pbelow << endl;
-
- straw *= pow((double)(1.0/pbelow), (double)1.0/numleft);
-
- lastw = cur->first;
- }
- //cout << "============" << endl;
- }
-
- int choose_r(int x, int r, Hash& h) const {
- //cout << "strawbucket.choose_r(" << x << ", " << r << ")" << endl;
-
- float high_draw = -1;
- int high = 0;
-
- list<int>::const_iterator pi = _items.begin();
- list<float>::const_iterator ps = _straws.begin();
- while (pi != _items.end()) {
- const int item = *pi;
- const float rnd = (float)(h(x, item, r) % 1000000) / 1000000.0;
- const float straw = *ps * rnd;
-
- if (high_draw < 0 ||
- straw > high_draw) {
- high = *pi;
- high_draw = straw;
- }
-
- pi++;
- ps++;
- }
- return high;
- }
- };
-
-
-
-
-
- inline Bucket* decode_bucket(bufferlist& bl, int& off) {
- char t;
- bl.copy(off, sizeof(t), (char*)&t);
- off += sizeof(t);
-
- switch (t) {
- case CRUSH_BUCKET_UNIFORM:
- return new UniformBucket(bl, off);
- case CRUSH_BUCKET_LIST:
- return new ListBucket(bl, off);
- case CRUSH_BUCKET_TREE:
- return new TreeBucket(bl, off);
- case CRUSH_BUCKET_STRAW:
- return new StrawBucket(bl, off);
- default:
- assert(0);
- }
- return 0;
- }
-
-
-
-}
-
-
-
-
-
-
-
-
-#endif
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-
-// Robert Jenkins' function for mixing 32-bit values
-// http://burtleburtle.net/bob/hash/evahash.html
-// a, b = random bits, c = input and output
-#define hashmix(a,b,c) \
- a=a-b; a=a-c; a=a^(c>>13); \
- b=b-c; b=b-a; b=b^(a<<8); \
- c=c-a; c=c-b; c=c^(b>>13); \
- a=a-b; a=a-c; a=a^(c>>12); \
- b=b-c; b=b-a; b=b^(a<<16); \
- c=c-a; c=c-b; c=c^(b>>5); \
- a=a-b; a=a-c; a=a^(c>>3); \
- b=b-c; b=b-a; b=b^(a<<10); \
- c=c-a; c=c-b; c=c^(b>>15);
-
-namespace crush {
-
- class Hash {
- int seed;
-
- public:
- int get_seed() { return seed; }
- void set_seed(int s) { seed = s; }
-
- Hash(int s) {
- unsigned int hash = 1315423911;
- int x = 231232;
- int y = 1232;
- hashmix(s, x, hash);
- hashmix(y, s, hash);
- seed = s;
- }
-
- inline int operator()(int a) {
- unsigned int hash = seed ^ a;
- int b = a;
- int x = 231232;
- int y = 1232;
- hashmix(b, x, hash);
- hashmix(y, a, hash);
- return (hash & 0x7FFFFFFF);
- }
-
- inline int operator()(int a, int b) {
- unsigned int hash = seed ^ a ^ b;
- int x = 231232;
- int y = 1232;
- hashmix(a, b, hash);
- hashmix(x, a, hash);
- hashmix(b, y, hash);
- return (hash & 0x7FFFFFFF);
- }
-
- inline int operator()(int a, int b, int c) {
- unsigned int hash = seed ^ a ^ b ^ c;
- int x = 231232;
- int y = 1232;
- hashmix(a, b, hash);
- hashmix(c, x, hash);
- hashmix(y, a, hash);
- hashmix(b, x, hash);
- hashmix(y, c, hash);
- return (hash & 0x7FFFFFFF);
- }
-
- inline int operator()(int a, int b, int c, int d) {
- unsigned int hash = seed ^a ^ b ^ c ^ d;
- int x = 231232;
- int y = 1232;
- hashmix(a, b, hash);
- hashmix(c, d, hash);
- hashmix(a, x, hash);
- hashmix(y, b, hash);
- hashmix(c, x, hash);
- hashmix(y, d, hash);
- return (hash & 0x7FFFFFFF);
- }
-
- inline int operator()(int a, int b, int c, int d, int e) {
- unsigned int hash = seed ^ a ^ b ^ c ^ d ^ e;
- int x = 231232;
- int y = 1232;
- hashmix(a, b, hash);
- hashmix(c, d, hash);
- hashmix(e, x, hash);
- hashmix(y, a, hash);
- hashmix(b, x, hash);
- hashmix(y, c, hash);
- hashmix(d, x, hash);
- hashmix(y, e, hash);
- return (hash & 0x7FFFFFFF);
- }
- };
-
-}
-
-
-
-#if 0
-
-
- //return myhash(a) ^ seed;
- return myhash(a, seed);
- }
- int operator()(int a, int b) {
- //return myhash( myhash(a) ^ myhash(b) ^ seed );
- return myhash(a, b, seed);
- }
- int operator()(int a, int b, int c) {
- //return myhash( myhash(a ^ seed) ^ myhash(b ^ seed) ^ myhash(c ^ seed) ^ seed );
- return myhash(a, b, c, seed);
- }
- int operator()(int a, int b, int c, int d) {
- //return myhash( myhash(a ^ seed) ^ myhash(b ^ seed) ^ myhash(c ^ seed) ^ myhash(d ^ seed) ^ seed );
- return myhash(a, b, c, d, seed);
- }
-
- // ethan's rush hash?
- if (0)
- return (n ^ 0xdead1234) * (884811920 * 3 + 1);
-
- if (1) {
-
- // before
- hash ^= ((hash << 5) + (n&255) + (hash >> 2));
- hashmix(a, b, hash);
- n = n >> 8;
- hash ^= ((hash << 5) + (n&255) + (hash >> 2));
- hashmix(a, b, hash);
- n = n >> 8;
- hash ^= ((hash << 5) + (n&255) + (hash >> 2));
- hashmix(a, b, hash);
- n = n >> 8;
- hash ^= ((hash << 5) + (n&255) + (hash >> 2));
- hashmix(a, b, hash);
- n = n >> 8;
-
- //return hash;
- return (hash & 0x7FFFFFFF);
- }
-
- // JS
- // a little better than RS
- // + jenkin's mixing thing (which sucks on its own but helps tons here)
- // best so far
- if (1) {
- unsigned int hash = 1315423911;
- int a = 231232;
- int b = 1232;
-
- for(unsigned int i = 0; i < 4; i++)
- {
- hash ^= ((hash << 5) + (n&255) + (hash >> 2));
- hashmix(a, b, hash);
- n = n >> 8;
- }
-
- return (hash & 0x7FFFFFFF);
- }
-
-
- // Robert jenkins' 96 bit mix
- // sucks
- if (0) {
- int c = n;
- int a = 12378912;
- int b = 2982827;
- a=a-b; a=a-c; a=a^(c>>13);
- b=b-c; b=b-a; b=b^(a<<8);
- c=c-a; c=c-b; c=c^(b>>13);
- a=a-b; a=a-c; a=a^(c>>12);
- b=b-c; b=b-a; b=b^(a<<16);
- c=c-a; c=c-b; c=c^(b>>5);
- a=a-b; a=a-c; a=a^(c>>3);
- b=b-c; b=b-a; b=b^(a<<10);
- c=c-a; c=c-b; c=c^(b>>15);
- return c;
- }
- // robert jenkins 32-bit
- // sucks
- if (0) {
- n += (n << 12);
- n ^= (n >> 22);
- n += (n << 4);
- n ^= (n >> 9);
- n += (n << 10);
- n ^= (n >> 2);
- n += (n << 7);
- n ^= (n >> 12);
- return n;
- }
-
- // djb2
- if (0) {
- unsigned int hash = 5381;
- for (int i=0; i<4; i++) {
- hash = ((hash << 5) + hash) + ((n&255) ^ 123);
- n = n >> 8;
- }
- return hash;
- }
-
-
- // SDBM
- if (1) {
- unsigned int hash = 0;
-
- for(unsigned int i = 0; i < 4; i++)
- {
- hash = (n&255) + (hash << 6) + (hash << 16) - hash;
- n = n >> 8;
- }
-
- return (hash & 0x7FFFFFFF);
- }
-
- // PJW
- // horrid
- if (0) {
- unsigned int BitsInUnsignedInt = (unsigned int)(sizeof(unsigned int) * 8);
- unsigned int ThreeQuarters = (unsigned int)((BitsInUnsignedInt * 3) / 4);
- unsigned int OneEighth = (unsigned int)(BitsInUnsignedInt / 8);
- unsigned int HighBits = (unsigned int)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
- unsigned int hash = 0;
- unsigned int test = 0;
-
- for(unsigned int i = 0; i < 4; i++)
- {
- hash = (hash << OneEighth) + (n&255);
-
- if((test = hash & HighBits) != 0)
- {
- hash = (( hash ^ (test >> ThreeQuarters)) & (~HighBits));
- }
- n = n >> 8;
- }
-
- return (hash & 0x7FFFFFFF);
- }
-
- // RS Hash function, from Robert Sedgwicks Algorithms in C book, w/ some changes.
- if (0) {
- unsigned int b = 378551;
- unsigned int a = 63689;
- unsigned int hash = 0;
-
- for(unsigned int i=0; i<4; i++)
- {
- hash = hash * a + (n&0xff);
- a = a * b;
- n = n >> 8;
- }
-
- return (hash & 0x7FFFFFFF);
- }
-
- // DJB
- // worse than rs
- if (0) {
- unsigned int hash = 5381;
-
- for(unsigned int i = 0; i < 4; i++)
- {
- hash = ((hash << 5) + hash) + (n&255);
- n = n >> 8;
- }
-
- return (hash & 0x7FFFFFFF);
- }
-
- // AP
- // even worse
- if (1) {
- unsigned int hash = 0;
-
- for(unsigned int i = 0; i < 4; i++)
- {
- hash ^= ((i & 1) == 0) ? ( (hash << 7) ^ (n&255) ^ (hash >> 3)) :
- (~((hash << 11) ^ (n&255) ^ (hash >> 5)));
- n = n >> 8;
- }
-
- return (hash & 0x7FFFFFFF);
- }
-
-
-#endif
+++ /dev/null
-// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
-// vim: ts=8 sw=2 smarttab
-/*
- * Ceph - scalable distributed file system
- *
- * Copyright (C) 2004-2006 Sage Weil <sage@newdream.net>
- *
- * This is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License version 2.1, as published by the Free Software
- * Foundation. See file COPYING.
- *
- */
-
-#ifndef CEPH_crush_CRUSH_H
-#define CEPH_crush_CRUSH_H
-
-#include <iostream>
-#include <list>
-#include <vector>
-#include <set>
-#include <map>
-using std::set;
-using std::map;
-using std::vector;
-using std::list;
-#include <ext/hash_map>
-#include <ext/hash_set>
-using namespace __gnu_cxx;
-
-
-#include "Bucket.h"
-
-#include "include/buffer.h"
-
-
-namespace crush {
-
-
- // *** RULES ***
-
- class RuleStep {
- public:
- int cmd;
- vector<int> args;
-
- RuleStep(int c) : cmd(c) {}
- RuleStep(int c, int a) : cmd(c) {
- args.push_back(a);
- }
- RuleStep(int c, int a, int b) : cmd(c) {
- args.push_back(a);
- args.push_back(b);
- }
- RuleStep(int o, int a, int b, int c) : cmd(o) {
- args.push_back(a);
- args.push_back(b);
- args.push_back(c);
- }
-
- void _encode(bufferlist& bl) {
- bl.append((char*)&cmd, sizeof(cmd));
- ::_encode(args, bl);
- }
- void _decode(bufferlist& bl, int& off) {
- bl.copy(off, sizeof(cmd), (char*)&cmd);
- off += sizeof(cmd);
- ::_decode(args, bl, off);
- }
- };
-
-
- // Rule operations
- const int CRUSH_RULE_TAKE = 0;
- const int CRUSH_RULE_CHOOSE = 1; // first n by default
- const int CRUSH_RULE_CHOOSE_FIRSTN = 1;
- const int CRUSH_RULE_CHOOSE_INDEP = 2;
- const int CRUSH_RULE_EMIT = 3;
-
- class Rule {
- public:
- vector< RuleStep > steps;
-
- void _encode(bufferlist& bl) {
- int n = steps.size();
- bl.append((char*)&n, sizeof(n));
- for (int i=0; i<n; i++)
- steps[i]._encode(bl);
- }
- void _decode(bufferlist& bl, int& off) {
- steps.clear();
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- steps.push_back(RuleStep(0));
- steps[i]._decode(bl, off);
- }
- }
- };
-
-
-
-
- // *** CRUSH ***
-
- class Crush {
- protected:
- map<int, Bucket*> buckets;
- int bucketno;
- Hash h;
-
- hash_map<int, int> parent_map; // what bucket each leaf/bucket lives in
-
- public:
- map<int, Rule> rules;
-
- //map<int,int> collisions;
- //map<int,int> bumps;
-
- void _encode(bufferlist& bl) {
- // buckets
- int n = buckets.size();
- bl.append((char*)&n, sizeof(n));
- for (map<int, Bucket*>::const_iterator it = buckets.begin();
- it != buckets.end();
- it++) {
- bl.append((char*)&it->first, sizeof(it->first));
- it->second->_encode(bl);
- }
- bl.append((char*)&bucketno, sizeof(bucketno));
-
- // hash
- int s = h.get_seed();
- bl.append((char*)&s, sizeof(s));
-
- //::_encode(out, bl);
- //::_encode(overload, bl);
-
- // rules
- n = rules.size();
- bl.append((char*)&n, sizeof(n));
- for(map<int, Rule>::iterator it = rules.begin();
- it != rules.end();
- it++) {
- bl.append((char*)&it->first, sizeof(it->first));
- it->second._encode(bl);
- }
-
- }
-
- void _decode(bufferlist& bl, int& off) {
- int n;
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- int bid;
- bl.copy(off, sizeof(bid), (char*)&bid);
- off += sizeof(bid);
- Bucket *b = decode_bucket(bl, off);
- buckets[bid] = b;
- }
- bl.copy(off, sizeof(bucketno), (char*)&bucketno);
- off += sizeof(bucketno);
-
- int s;
- bl.copy(off, sizeof(s), (char*)&s);
- off += sizeof(s);
- h.set_seed(s);
-
- //::_decode(out, bl, off);
- //::_decode(overload, bl, off);
-
- // rules
- bl.copy(off, sizeof(n), (char*)&n);
- off += sizeof(n);
- for (int i=0; i<n; i++) {
- int r;
- bl.copy(off, sizeof(r), (char*)&r);
- off += sizeof(r);
- rules[r]._decode(bl,off);
- }
-
- // index
- build_parent_map();
- }
-
- void build_parent_map() {
- parent_map.clear();
-
- // index every bucket
- for (map<int, Bucket*>::iterator bp = buckets.begin();
- bp != buckets.end();
- ++bp) {
- // index bucket items
- vector<int> items;
- bp->second->get_items(items);
- for (vector<int>::iterator ip = items.begin();
- ip != items.end();
- ++ip)
- parent_map[*ip] = bp->first;
- }
- }
-
-
-
- public:
- Crush(int seed=123) : bucketno(-1), h(seed) {}
- ~Crush() {
- // hose buckets
- for (map<int, Bucket*>::iterator it = buckets.begin();
- it != buckets.end();
- it++) {
- delete it->second;
- }
- }
-
- int print(ostream& out, int root, int indent=0) {
- for (int i=0; i<indent; i++) out << " ";
- Bucket *b = buckets[root];
- assert(b);
- out << b->get_weight() << "\t" << b->get_id() << "\t";
- for (int i=0; i<indent; i++) out << " ";
- out << b->get_bucket_type() << ": ";
-
- vector<int> items;
- b->get_items(items);
-
- if (buckets.count(items[0])) {
- out << std::endl;
- for (unsigned i=0; i<items.size(); i++)
- print(out, items[i], indent+1);
- } else {
- out << "[";
- for (unsigned i=0; i<items.size(); i++) {
- if (i) out << " ";
- out << items[i];
- }
- out << "]";
- }
- return 0;
- }
-
-
- int add_bucket( Bucket *b ) {
- int n = bucketno;
- bucketno--;
- b->set_id(n);
- buckets[n] = b;
- return n;
- }
-
- void add_item(int parent, int item, float w, bool back=false) {
- // add item
- assert(!buckets[parent]->is_uniform());
- Bucket *p = buckets[parent];
-
- p->add_item(item, w, back);
-
- // set item's parent
- Bucket *n = buckets[item];
- if (n)
- n->set_parent(parent);
-
- // update weights
- while (buckets.count(p->get_parent())) {
- int child = p->get_id();
- p = buckets[p->get_parent()];
- p->adjust_item_weight(child, w);
- }
- }
-
-
- /*
- this is a hack, fix me! weights should be consistent throughout hierarchy!
-
- */
- void set_bucket_weight(int item, float w) {
- Bucket *b = buckets[item];
- float adj = w - b->get_weight();
-
- while (buckets.count(b->get_parent())) {
- Bucket *p = buckets[b->get_parent()];
- p->adjust_item_weight(b->get_id(), adj);
- b = p;
- }
- }
-
-
- /*
- * choose numrep distinct items of type type
- */
- void choose(int x,
- int numrep,
- int type,
- Bucket *inbucket,
- vector<int>& outvec,
- bool firstn,
- set<int>& outset, map<int,float>& overloadmap,
- bool forcefeed=false,
- int forcefeedval=-1) {
- int off = outvec.size();
-
- // for each replica
- for (int rep=0; rep<numrep; rep++) {
- int outv = -1; // my result
-
- // forcefeed?
- if (forcefeed) {
- forcefeed = false;
- outvec.push_back(forcefeedval);
- continue;
- }
-
- // keep trying until we get a non-out, non-colliding item
- int ftotal = 0;
- bool skip_rep = false;
-
- while (1) {
- // start with the input bucket
- Bucket *in = inbucket;
-
- // choose through intervening buckets
- int flocal = 0;
- bool retry_rep = false;
-
- while (1) {
- // r may be twiddled to (try to) avoid past collisions
- int r = rep;
- if (in->is_uniform()) {
- // uniform bucket; be careful!
- if (firstn || numrep >= in->get_size()) {
- // uniform bucket is too small; just walk thru elements
- r += ftotal; // r' = r + f_total (first n)
- } else {
- // make sure numrep is not a multple of bucket size
- int add = numrep*flocal; // r' = r + n*f_local
- if (in->get_size() % numrep == 0) {
- add += add/in->get_size(); // shift seq once per pass through the bucket
- }
- r += add;
- }
- } else {
- // mixed bucket; just make a distinct-ish r sequence
- if (firstn)
- r += ftotal; // r' = r + f_total
- else
- r += numrep * flocal; // r' = r + n*f_local
- }
-
- // choose
- outv = in->choose_r(x, r, h);
-
- // did we get the type we want?
- int itemtype = 0; // 0 is terminal type
- Bucket *newin = 0; // remember bucket we hit
- if (in->is_uniform()) {
- itemtype = ((UniformBucket*)in)->get_item_type();
- } else {
- if (buckets.count(outv)) { // another bucket
- newin = buckets[outv];
- itemtype = newin->get_type();
- }
- }
- if (itemtype == type) { // this is what we want!
- // collision?
- bool collide = false;
- for (int prep=0; prep<rep; prep++) {
- if (outvec[off+prep] == outv) {
- collide = true;
- break;
- }
- }
-
- // ok choice?
- bool bad = false;
- if (type == 0 && outset.count(outv))
- bad = true;
- if (overloadmap.count(outv)) {
- float f = (float)(h(x, outv) % 1000) / 1000.0;
- if (f > overloadmap[outv])
- bad = true;
- }
-
- if (collide || bad) {
- ftotal++;
- flocal++;
-
- if (collide && flocal < 3)
- continue; // try locally a few times!
-
- if (ftotal >= 10) {
- // ok fine, just ignore dup. FIXME.
- skip_rep = true;
- break;
- }
-
- retry_rep = true;
- }
-
- break; // ok then!
- }
-
- // next
- in = newin;
- }
-
- if (retry_rep) continue; // try again
-
- break;
- }
-
- // skip this rep? (e.g. too many collisions, we give up)
- if (skip_rep) continue;
-
- // output this value
- outvec.push_back(outv);
- } // for rep
-
- // double check!
- if (0) {
- for (unsigned i=1; i<outvec.size(); i++)
- for (unsigned j=0; j<i; j++)
- assert(outvec[i] != outvec[j]);
- }
- }
-
-
- void do_rule(Rule& rule, int x, vector<int>& result,
- set<int>& outset, map<int,float>& overloadmap,
- int forcefeed=-1) {
- //int numresult = 0;
- result.clear();
-
- // determine hierarchical context for forcefeed (if any)
- list<int> force_stack;
- if (forcefeed >= 0 && parent_map.count(forcefeed)) {
- int t = forcefeed;
- while (1) {
- force_stack.push_front(t);
- //cout << "push " << t << " onto force_stack" << std::endl;
- if (parent_map.count(t) == 0) break; // reached root, presumably.
- //cout << " " << t << " parent is " << parent_map[t] << std::endl;
- t = parent_map[t];
- }
- }
-
- // working vector
- vector<int> w; // working variable
-
- // go through each statement
- for (vector<RuleStep>::iterator pc = rule.steps.begin();
- pc != rule.steps.end();
- pc++) {
- // move input?
-
- // do it
- switch (pc->cmd) {
- case CRUSH_RULE_TAKE:
- {
- const int arg = pc->args[0];
- //cout << "take " << arg << std::endl;
-
- if (!force_stack.empty()) {
- assert(force_stack.front() == arg);
- force_stack.pop_front();
- }
-
- w.clear();
- w.push_back(arg);
- }
- break;
-
- case CRUSH_RULE_CHOOSE_FIRSTN:
- case CRUSH_RULE_CHOOSE_INDEP:
- {
- const bool firstn = pc->cmd == CRUSH_RULE_CHOOSE_FIRSTN;
- const int numrep = pc->args[0];
- const int type = pc->args[1];
-
- //cout << "choose " << numrep << " of type " << type << std::endl;
-
- assert(!w.empty());
-
- // reset output
- vector<int> out;
-
- // forcefeeding?
- bool forcing = false;
- int forceval = -1;
- if (!force_stack.empty()) {
- forceval = force_stack.front();
- force_stack.pop_front();
- //cout << "priming out with " << forceval << std::endl;
- forcing = true;
- } else if (forcefeed >= 0 && type == 0) {
- //cout << "forcing context-less " << forcefeed << std::endl;
- forceval = forcefeed;
- forcefeed = -1;
- forcing = true;
- }
-
- // do each row independently
- for (vector<int>::iterator i = w.begin();
- i != w.end();
- i++) {
- assert(buckets.count(*i));
- Bucket *b = buckets[*i];
- choose(x, numrep, type, b, out, firstn,
- outset, overloadmap,
- forcing,
- forceval);
- forcing = false; // only once
- } // for inrow
-
- // put back into w
- w.swap(out);
- out.clear();
- }
- break;
-
- case CRUSH_RULE_EMIT:
- {
- for (unsigned i=0; i<w.size(); i++)
- result.push_back(w[i]);
- //result[numresult++] = w[i];
- w.clear();
- }
- break;
-
- default:
- assert(0);
- }
- }
-
- }
-
-
- };
-
-}
-
-#endif
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, map<int, vector<int> >& placement)
-{
- vector<int> v(numrep);
- map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
-
- placement[x] = v;
-
- //cout << v << "\t" << ocount << endl;
- }
-
- if (0)
- for (map<int,int>::iterator it = ocount.begin();
- it != ocount.end();
- it++)
- cout << it->first << "\t" << it->second << endl;
-
-}
-
-
-float testmovement(int n, float f, int buckettype)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
- int ndisks = 0;
-
- // bucket
- Bucket *b;
- if (buckettype == 0)
- b = new TreeBucket(1);
- else if (buckettype == 1 || buckettype == 2)
- b = new ListBucket(1);
- else if (buckettype == 3)
- b = new StrawBucket(1);
- else if (buckettype == 4)
- b = new UniformBucket(0,0);
-
- for (int i=0; i<n; i++)
- b->add_item(ndisks++,1);
-
- c.add_bucket(b);
- int root = b->get_id();
-
- //c.print(cout,root);
-
- // rule
- int numrep = 2;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
- //c.overload[10] = .1;
-
-
- int pg_per = 1000;
- int numpg = pg_per*ndisks/numrep;
-
- vector<int> ocount(ndisks);
-
- /*
- cout << ndisks << " disks, " << endl;
- cout << pg_per << " pgs per disk" << endl;
- cout << numpg << " logical pgs" << endl;
- cout << "numrep is " << numrep << endl;
- */
- map<int, vector<int> > placement1, placement2;
-
- //c.print(cout, root);
-
-
- // ORIGINAL
- place(c, rule, numpg, numrep, placement1);
-
- int olddisks = ndisks;
-
- // add item
- if (buckettype == 2) {
- // start over!
- ndisks = 0;
- b = new ListBucket(1);
- for (int i=0; i<=n; i++)
- b->add_item(ndisks++,1);
- c.add_bucket(b);
- root = b->get_id();
-
- rule.steps.clear();
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
- }
- else
- b->add_item(ndisks++, 1);
-
-
- // ADDED
- //c.print(cout, root);
- place(c, rule, numpg, numrep, placement2);
-
- int moved = 0;
- for (int x=1; x<=numpg; x++)
- if (placement1[x] != placement2[x])
- for (int j=0; j<numrep; j++)
- if (placement1[x][j] != placement2[x][j])
- moved++;
-
- int total = numpg*numrep;
- float actual = (float)moved / (float)(total);
- float ideal = (float)(ndisks-olddisks) / (float)(ndisks);
- float fac = actual/ideal;
- //cout << add << "\t" << olddisks << "\t" << ndisks << "\t" << moved << "\t" << total << "\t" << actual << "\t" << ideal << "\t" << fac << endl;
- cout << "\t" << fac;
- return fac;
-}
-
-
-int main()
-{
- //cout << "// " << depth << ", modifydepth " << modifydepth << ", branching " << branching << ", disks " << n << endl;
- cout << "n\ttree\tlhead\tltail\tstraw\tuniform" << endl;
-
- //for (int s=2; s<=64; s+= (s<4?1:(s<16?2:4))) {
- for (int s=2; s<=64; s+= (s<4?1:4)) {
- float f = 1.0 / (float)s;
- //cout << f << "\t" << s;
- cout << s;
- for (int buckettype=0; buckettype<5; buckettype++)
- testmovement(s, f, buckettype);
- cout << endl;
- }
-}
-
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- 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(1, 0, 10, disks);
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- return b;
- } else {
- // mixed
- //Bucket *b = new MixedBucket(h+1);
- Bucket *b = new StrawBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-float go(int dep)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- if (0) {
- for (int d=0; d<dep; d++)
- wid.push_back(10);
- }
- if (1) {
- if (dep == 0)
- wid.push_back(1000);
- if (dep == 1) {
- wid.push_back(1);
- wid.push_back(1000);
- }
- if (dep == 2) {
- wid.push_back(5);
- wid.push_back(5);
- wid.push_back(8);
- wid.push_back(5);
- }
- }
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
- if (0) {
- MixedBucket *b = new MixedBucket(1);
- for (int i=0; i<10000; i++)
- b->add_item(ndisks++, 10);
- root = c.add_bucket(b);
- }
- if (0) {
- vector<int> disks;
- for (int i=0; i<10000; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 10000, disks);
- Hash h(123);
- b->make_primes(h);
- root = c.add_bucket(b);
- }
-
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- //cout << pg_per << " pgs per disk" << endl;
- // cout << numpg << " logical pgs" << endl;
- //cout << "numrep is " << numrep << endl;
-
-
- int place = 100000;
- 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;
- //cout << avg << "\t";
-
- tvar += var;
- tvarnum++;
- }
-
- tvar /= tvarnum;
-
- //cout << "total variance " << tvar << endl;
-
- return tvar;
-}
-
-
-int main()
-{
- for (int d=0; d<=2; d++) {
- float var = go(d);
- //cout << "## depth = " << d << endl;
- cout << d << "\t" << var << "\t" << sqrt(var) << endl;
- }
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-int buckettype = 0;
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- 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(1, 0, 1, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- buckets[h].push_back(b);
- return b;
- } else {
- // mixed
- //Bucket *b = new TreeBucket(h+1);
- //Bucket *b = new ListBucket(h+1);
- //Bucket *b = new StrawBucket(h+1);
- Bucket *b;
- if (buckettype == 0)
- b = new TreeBucket(h+1);
- else if (buckettype == 1 || buckettype == 2)
- b = new ListBucket(h+1);
- else if (buckettype == 3)
- b = new StrawBucket(h+1);
-
- c.add_bucket(b);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, buckets, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- n->set_parent(b->get_id());
- }
- buckets[h].push_back(b);
- //cout << b->get_id() << " mixedbucket with " << wid[h] << " at " << h << endl;
- return b;
- }
-}
-
-int make_hierarchy(Crush& c, vector<int>& wid, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, buckets, ndisks);
- return b->get_id();
-}
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, map<int, vector<int> >& placement)
-{
- vector<int> v(numrep);
- map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
- }
- }
-
- placement[x] = v;
-
- //cout << v << "\t" << ocount << endl;
- }
-
- if (0)
- for (map<int,int>::iterator it = ocount.begin();
- it != ocount.end();
- it++)
- cout << it->first << "\t" << it->second << endl;
-
-}
-
-
-float testmovement(int depth, int branching, int udisks, int add, int modifydepth)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- wid.push_back(udisks);
- for (int d=1; d<depth; d++)
- wid.push_back(branching);
-
- map< int, list<Bucket*> > buckets;
-
- root = make_hierarchy(c, wid, buckets, ndisks);
-
- //c.print(cout,root);
-
- // rule
- int numrep = 2;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- cout << pg_per << " pgs per disk" << endl;
- cout << numpg << " logical pgs" << endl;
- cout << "numrep is " << numrep << endl;
- */
- map<int, vector<int> > placement1, placement2;
-
- //c.print(cout, root);
-
-
- // ORIGINAL
- place(c, rule, numpg, numrep, placement1);
-
- int olddisks = ndisks;
-
- // add disks
- //cout << " adding " << add << " disks" << endl;
- vector<int> disks;
- for (int i=0; i<add; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- //b->make_primes(h);
-
- //Bucket *o = buckets[2].back();
- Bucket *o;
- if (buckettype == 2)
- o = buckets[modifydepth].front();
- else
- o = buckets[modifydepth].back();
-
- c.add_bucket(b);
- //cout << " adding under " << o->get_id() << endl;
- c.add_item(o->get_id(), b->get_id(), b->get_weight());
- //((MixedBucket*)o)->add_item(b->get_id(), b->get_weight());
- //newbucket = b;
-
-
- // ADDED
- //c.print(cout, root);
- place(c, rule, numpg, numrep, placement2);
-
- int moved = 0;
- for (int x=1; x<=numpg; x++)
- if (placement1[x] != placement2[x])
- for (int j=0; j<numrep; j++)
- if (placement1[x][j] != placement2[x][j])
- moved++;
-
- int total = numpg*numrep;
- float actual = (float)moved / (float)(total);
- float ideal = (float)(ndisks-olddisks) / (float)(ndisks);
- float fac = actual/ideal;
- //cout << add << "\t" << olddisks << "\t" << ndisks << "\t" << moved << "\t" << total << "\t" << actual << "\t" << ideal << "\t" << fac << endl;
- cout << "\t" << fac;
- return fac;
-}
-
-
-int main()
-{
-
- int udisks = 10;
- int add = udisks;
-
- //int depth = 3;
- //int branching = 25;
- int depth = 4;
- int branching = 9;
-
- int modifydepth = 1;
- int bfac = (int)(sqrt((double)branching));
- int n = (int)(udisks * pow((float)branching, (float)depth-1));
-
- cout << "// depth " << depth << ", modifydepth " << modifydepth << ", branching " << branching << ", disks " << n << endl;
- cout << "n\ttree\tlhead\tltail\tstraw" << endl;
- for (int add = udisks; add <= n; add *= bfac) {
- cout << add;
- for (buckettype=0; buckettype<4; buckettype++)
- testmovement(depth, branching, udisks, add, modifydepth);
- cout << endl;
- }
-}
-
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-int buckettype = 2; // 0 = mixed, 1 = linear, 2 = straw
-
-int big_one_skip = 255;
-int big_one_size;
-Bucket *big_one = 0;
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- if (h == 0) {
- // uniform
- Hash hash(123);
- vector<int> disks;
-
- int s = wid[h];
- if (big_one_skip > 0)
- big_one_skip--;
- if (!big_one_skip && !big_one)
- s = big_one_size;
-
-
- for (int i=0; i<s; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- if (!big_one_skip && !big_one) big_one = b;
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks " << disks.size()<< endl;
- buckets[h].push_back(b);
- return b;
- } else {
- // mixed
- Bucket *b;
- if (buckettype == 0)
- b = new TreeBucket(h+1);
- else if (buckettype == 1)
- b = new ListBucket(h+1);
- else if (buckettype == 2)
- b = new StrawBucket(h+1);
- c.add_bucket(b);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, buckets, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- n->set_parent(b->get_id());
- }
- buckets[h].push_back(b);
- //cout << b->get_id() << " mixedbucket with " << wid[h] << " at " << h << endl;
- return b;
- }
-}
-
-int make_hierarchy(Crush& c, vector<int>& wid, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, buckets, ndisks);
- return b->get_id();
-}
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, map<int, vector<int> >& placement)
-{
- vector<int> v(numrep);
- map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
-
- placement[x] = v;
-
- //cout << v << "\t" << ocount << endl;
- }
-
- if (0)
- for (map<int,int>::iterator it = ocount.begin();
- it != ocount.end();
- it++)
- cout << it->first << "\t" << it->second << endl;
-
-}
-
-
-float testmovement(int depth, int branching, int udisks, int add)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- wid.push_back(udisks);
- for (int d=1; d<depth; d++)
- wid.push_back(branching + ((d==2)?1:0));
-
- map< int, list<Bucket*> > buckets;
-
- big_one_size = add;
- big_one = 0;
-
- //cout << "making tree" << endl;
- root = make_hierarchy(c, wid, buckets, ndisks);
-
- //c.print(cout, root);
-
-
- // rule
- int numrep = 2;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- cout << pg_per << " pgs per disk" << endl;
- cout << numpg << " logical pgs" << endl;
- cout << "numrep is " << numrep << endl;
- */
- map<int, vector<int> > placement1, placement2;
-
- //c.print(cout, root);
-
- int olddisks = ndisks;
-
-
- place(c, rule, numpg, numrep, placement1);
-
- if (1) {
- // remove disks
- assert(big_one);
- c.adjust_item(big_one->get_id(), 0);
- }
-
- int newdisks = ndisks - add;
-
- //c.print(cout, root);
- place(c, rule, numpg, numrep, placement2);
-
- int moved = 0;
- for (int x=1; x<=numpg; x++)
- if (placement1[x] != placement2[x])
- for (int j=0; j<numrep; j++)
- if (placement1[x][j] != placement2[x][j])
- moved++;
-
- int total = numpg*numrep;
- float actual = (float)moved / (float)(total);
- //float ideal = (float)(newdisks-olddisks) / (float)(ndisks);
- float ideal = (float)(olddisks-newdisks) / (float)(olddisks);
- float fac = actual/ideal;
- cout << add << "\t" << olddisks << "\t" << ndisks << "\t" << moved << "\t" << total << "\t" << actual << "\t" << ideal << "\t" << fac << endl;
- return fac;
-}
-
-
-int main()
-{
-
- int udisks = 10;
- int ndisks = 10;
- int depth = 4;
- int branching = 9;
- int add = udisks;
-
- //cout << "\t" << n;
- // cout << endl;
-
- buckettype = 2; // 0 = tree, 1 = linear, 2 = straw
-
- int n = udisks * pow((float)branching, (float)depth-1);
- for (int add = udisks; add <= n; add *= 3) {
- big_one_skip = 0;
- big_one_skip = 9;
- testmovement(depth, branching, udisks, add);
- }
-
- /*
- cout << "##" << endl;
- for (map<int, map<float,float> >::iterator i = r.begin();
- i != r.end();
- i++) {
- cout << i->first;
- for (map<float,float>::iterator j = i->second.begin();
- j != i->second.end();
- j++)
- cout << "\t" << j->first << "\t" << j->second;
- cout << endl;
- }
- */
-}
-
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-int buckettype = 0;
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- 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(1, 0, 1, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- buckets[h].push_back(b);
- return b;
- } else {
- // mixed
- //Bucket *b = new TreeBucket(h+1);
- //Bucket *b = new ListBucket(h+1);
- //Bucket *b = new StrawBucket(h+1);
- Bucket *b;
- if (buckettype == 0)
- b = new TreeBucket(h+1);
- else if (buckettype == 1 || buckettype == 2)
- b = new ListBucket(h+1);
- else if (buckettype == 3)
- b = new StrawBucket(h+1);
-
- c.add_bucket(b);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, buckets, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- n->set_parent(b->get_id());
- }
- buckets[h].push_back(b);
- //cout << b->get_id() << " mixedbucket with " << wid[h] << " at " << h << endl;
- return b;
- }
-}
-
-int make_hierarchy(Crush& c, vector<int>& wid, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, buckets, ndisks);
- return b->get_id();
-}
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, map<int, vector<int> >& placement)
-{
- vector<int> v(numrep);
- map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
- }
- }
-
- placement[x] = v;
-
- //cout << v << "\t" << ocount << endl;
- }
-
- if (0)
- for (map<int,int>::iterator it = ocount.begin();
- it != ocount.end();
- it++)
- cout << it->first << "\t" << it->second << endl;
-
-}
-
-
-float testmovement(int depth, int branching, int udisks, int add, int modifydepth)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- wid.push_back(udisks);
- for (int d=1; d<depth; d++)
- wid.push_back(branching);
-
- map< int, list<Bucket*> > buckets;
-
- root = make_hierarchy(c, wid, buckets, ndisks);
-
- //c.print(cout,root);
-
- // rule
- int numrep = 2;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- cout << pg_per << " pgs per disk" << endl;
- cout << numpg << " logical pgs" << endl;
- cout << "numrep is " << numrep << endl;
- */
- map<int, vector<int> > placement1, placement2;
-
- //c.print(cout, root);
-
-
- // ORIGINAL
- place(c, rule, numpg, numrep, placement1);
-
- int olddisks = ndisks;
-
- // add disks
- //cout << " adding " << add << " disks" << endl;
- vector<int> disks;
- for (int i=0; i<add; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- //b->make_primes(h);
-
- //Bucket *o = buckets[2].back();
- Bucket *o;
- if (buckettype == 2)
- o = buckets[modifydepth].front();
- else
- o = buckets[modifydepth].back();
-
- c.add_bucket(b);
- //cout << " adding under " << o->get_id() << endl;
- c.add_item(o->get_id(), b->get_id(), b->get_weight(), buckettype == 2);
- //((MixedBucket*)o)->add_item(b->get_id(), b->get_weight());
- //newbucket = b;
-
-
- // ADDED
- //c.print(cout, root);
- place(c, rule, numpg, numrep, placement2);
-
- int moved = 0;
- for (int x=1; x<=numpg; x++)
- if (placement1[x] != placement2[x])
- for (int j=0; j<numrep; j++)
- if (placement1[x][j] != placement2[x][j])
- moved++;
-
- int total = numpg*numrep;
- float actual = (float)moved / (float)(total);
- float ideal = (float)(ndisks-olddisks) / (float)(ndisks);
- float fac = actual/ideal;
- //cout << add << "\t" << olddisks << "\t" << ndisks << "\t" << moved << "\t" << total << "\t" << actual << "\t" << ideal << "\t" << fac << endl;
- cout << "\t" << fac;
- return fac;
-}
-
-
-int main()
-{
-
- int udisks = 10;
- int add = udisks;
-
- //int depth = 3;
- //int branching = 25;
- int depth = 2;
- int branching = 9*9*9;
-
- int modifydepth = 1;
- int bfac = (int)(sqrt((double)branching));
- bfac = 3;
- int n = (int)(udisks * pow((float)branching, (float)depth-1));
-
- cout << "// depth " << depth << ", modifydepth " << modifydepth << ", branching " << branching << ", disks " << n << endl;
- cout << "n\ttree\tlhead\tltail\tstraw" << endl;
- for (int add = udisks; add <= n; add *= bfac) {
- cout << add;
- for (buckettype=0; buckettype<3; buckettype++)
- testmovement(depth, branching, udisks, add, modifydepth);
- cout << endl;
- }
-}
-
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include "../../common/Clock.h"
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Clock g_clock;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- if (h == 0) {
- // uniform
- Hash hash(123);
- vector<int> disks;
- for (int i=0; i<wid[h]; i++)
- disks.push_back(ndisks++);
- float w = 10;//((ndisks-1)/100+1)*10;
- UniformBucket *b = new UniformBucket(1, 0, w, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks weight " << w << endl;
- return b;
- } else {
- // mixed
- Bucket *b = new TreeBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-
-float go(int dep, int failpc)
-{
- Hash h(73232313);
-
- //int overloadcutoff = (int)((float)10000.0 / (float)utilization);
-
- //cout << "util " << utilization << " cutoff " << overloadcutoff << endl;
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- for (int d=0; d<dep; d++)
- wid.push_back(10);
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
-
- //cout << ndisks << " disks" << endl;
-
-
- int numf = ndisks * failpc / 100;
-
-
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
- //c.overload[10] = .1;
-
- int pg_per_base = 100;//20;
- int pg_med = 10*pg_per_base;
- int pg_per = pg_per_base*5.5;//100;
- int numpg = pg_per*ndisks/numrep;
-
- vector<int> ocount(ndisks);
- //cout << ndisks << " disks, " << 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 tavg[10];
- float tvar[10];
- for (int j=0;j<10;j++) {
- tvar[j] = 0;
- tavg[j] = 0;
- }
- int tvarnum = 0;
- float trvar = 0.0;
-
- float overloadsum = 0.0;
- float adjustsum = 0.0;
- float afteroverloadsum = 0.0;
- float aslowdown = 0.0;
- int chooses = 0;
- int xs = 1;
- for (int t=0; t<times; t++) {
- vector<int> v(numrep);
-
- c.out.clear();
-
- for (int z=0; z<ndisks; z++) ocount[z] = 0;
-
- utime_t t1a = g_clock.now();
- for (int x=xs; x<numpg+xs; x++) {
- c.do_rule(rule, x, v);
- //chooses += numrep;
- for (int i=0; i<v.size(); i++) {
- //if (v[i] >= ndisks) cout << "v[i] " << i << " is " << v[i] << " .. x = " << x << endl;
- //assert(v[i] < ndisks);
- ocount[v[i]]++;
- }
- }
- utime_t t1b = g_clock.now();
-
- // add in numf failed disks
- for (int f = 0; f < numf; f++) {
- int d = rand() % ndisks;
- while (c.out.count(d)) d = rand() % ndisks;
- c.out.insert(d);
- }
-
- utime_t t3a = g_clock.now();
- for (int x=xs; x<numpg+xs; x++) {
- c.do_rule(rule, x, v);
- //cout << "v = " << v << endl;// " " << v[0] << " " << v[1] << " " << v[2] << endl;
-
- for (int i=0; i<v.size(); i++) {
- //int d = b.choose_r(x, i, h);
- //v[i] = d;
- ocount[v[i]]++;
- }
-
- //cout << v << "\t" << ocount << endl;
- }
- xs += numpg;
-
- utime_t t3b = g_clock.now();
-
- t1b -= t1a;
- double t1 = (double)t1b;
- t3b -= t3a;
- double t3 = (double)t3b;
- double slowdown = t3/t1;
- //cout << "slowdown " << slowdown << endl;
- aslowdown += slowdown;
-
- //cout << "collisions: " << c.collisions << endl;
- //cout << "r bumps: " << c.bumps << endl;
-
- // stair var calc
- int n = ndisks/10;
- float avg[10];
- float var[10];
- for (int i=0;i<10;i++) {
- int s = n*i;
- avg[i] = 0.0;
- int nf = 0;
- for (int j=0; j<n; j++) {
- if (c.out.count(j+s)) { nf++; continue; }
- avg[i] += ocount[j+s];
- }
- avg[i] /= (n-nf);//ocount.size();
- var[i] = 0.0;
- for (int j=0; j<n; j++) {
- if (c.out.count(j+s)) continue;
- var[i] += (ocount[j+s] - avg[i]) * (ocount[j+s] - avg[i]);
- }
- var[i] /= (n-nf);//ocount.size();
-
- tvar[i] += var[i];
- tavg[i] += avg[i];
- }
- //cout << "avg " << avg << " var " << var << " sd " << sqrt(var) << endl;
-
- tvarnum++;
-
- // flat var calc
- int na = ndisks - numf; // num active
- float ravg = 0.0;
- for (int i=0;i<ndisks;i++) {
- if (c.out.count(i)) continue;
- ravg += ocount[i];
- }
- ravg /= (float)na;
- float rvar = 0.0;
- for (int i=0; i<ndisks; i++) {
- if (c.out.count(i)) continue;
- rvar += (ravg-(float)ocount[i])*(ravg-(float)ocount[i]);
- }
- rvar /= (float)na;
-
- trvar += rvar;
- }
-
-
- trvar /= (float)tvarnum;
-
- //overloadsum /= tvarnum;
- //adjustsum /= tvarnum;
- float avar = 0.0;
- for (int j=0;j<10;j++) {
- tvar[j] /= tvarnum;
- tavg[j] /= tvarnum;
- avar += tvar[j];
- }
- avar /= 10;
- avar = sqrt(avar);
- avar /= /*5.5 **/ (float)pg_per_base;
- //afteroverloadsum /= tvarnum;
- aslowdown /= tvarnum;
-
- //int collisions = c.collisions[0] + c.collisions[1] + c.collisions[2] + c.collisions[3];
- //float crate = (float) collisions / (float)chooses;
- //cout << "collisions: " << c.collisions << endl;
-
-
- //cout << "total variance " << tvar << endl;
- //cout << " overlaod " << overloadsum << endl;
-
- cout << failpc
- << "\t" << numf
- //<< "\t" << adjustsum
- //<< "\t" << afteroverloadsum
- << "\t" << aslowdown
- << "\t" << trvar
- << "\t" << sqrt(trvar) / (float)pg_per_base
- << "\t..\t" << avar
- << "\t-";
-
- for (int i=0;i<10;i++)
- cout << "\t" << tavg[i] << "\t" << sqrt(tvar[i]);// << "\t" << tvar[i]/tavg[i];
-
- cout << endl;
- return tvar[0];
-}
-
-
-int main()
-{
- for (int pc = 0; pc < 90; pc += 5) {
- float var = go(3, pc);
- }
-
-
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- 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(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(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-Bucket *make_random(Crush& c, int wid, int height, int& ndisks)
-{
- int w = rand() % (wid-1) + 2;
-
- if (height == 0) {
- // uniform
- Hash hash(123);
- vector<int> disks;
- for (int i=0; i<w; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 10, disks);
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- return b;
- } else {
- // mixed
- int h = rand() % height + 1;
- MixedBucket *b = new MixedBucket(h+1);
- for (int i=0; i<w; i++) {
- Bucket *n = make_random(c, wid, h-1, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- }
- c.add_bucket(b);
- //cout << h << " mixedbucket with " << wid[h] << endl;
- return b;
- }
-
-}
-
-
-float go(int dep, int overloadcutoff)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- for (int d=0; d<dep; d++)
- wid.push_back(10);
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
- if (0) {
- Bucket *r = make_random(c, 20, 4, ndisks);
- root = r->get_id();
- //c.print(cout, root);
- }
- if (0) {
- MixedBucket *b = new MixedBucket(1);
- for (int i=0; i<10000; i++)
- b->add_item(ndisks++, 10);
- root = c.add_bucket(b);
- }
- if (0) {
- vector<int> disks;
- for (int i=0; i<10000; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 10000, disks);
- Hash h(123);
- b->make_primes(h);
- root = c.add_bucket(b);
- }
- //cout << ndisks << " disks" << endl;
-
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << 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;
-
- float overloadsum = 0.0;
- float adjustsum = 0.0;
- float afteroverloadsum = 0.0;
- int chooses = 0;
- int xs = 1;
- for (int t=0; t<times; t++) {
- vector<int> v(numrep);
-
- c.overload.clear();
-
- for (int z=0; z<ndisks; z++) ocount[z] = 0;
-
- for (int x=xs; x<numpg+xs; x++) {
-
- //cout << H(x) << "\t" << h(x) << endl;
- c.do_rule(rule, x, v);
- chooses += numrep;
- //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;
- }
-
- // overloaded?
- int overloaded = 0;
- int adjusted = 0;
- for (int i=0; i<ocount.size(); i++) {
- if (ocount[i] > overloadcutoff)
- overloaded++;
-
- if (ocount[i] > 100+(overloadcutoff-100)/2) {
- adjusted++;
- c.overload[i] = 100.0 / (float)ocount[i];
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- ocount[i] = 0;
- }
- //cout << overloaded << " overloaded" << endl;
- overloadsum += (float)overloaded / (float)ndisks;
- adjustsum += (float)adjusted / (float)ndisks;
-
-
- for (int x=xs; x<numpg+xs; 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;
- }
- xs += numpg;
-
- int still = 0;
- for (int i=0; i<ocount.size(); i++) {
- if (ocount[i] > overloadcutoff) {
- still++;
- //c.overload[ocount[i]] = 100.0 / (float)ocount[i];
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- }
- //if (still) cout << "overload was " << overloaded << " now " << still << endl;
- afteroverloadsum += (float)still / (float)ndisks;
-
- //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++;
- }
-
- overloadsum /= tvarnum;
- adjustsum /= tvarnum;
- tvar /= tvarnum;
- afteroverloadsum /= tvarnum;
-
- int collisions = c.collisions[0] + c.collisions[1] + c.collisions[2] + c.collisions[3];
- float crate = (float) collisions / (float)chooses;
- //cout << "collisions: " << c.collisions << endl;
-
-
- //cout << "total variance " << tvar << endl;
- //cout << " overlaod " << overloadsum << endl;
-
- cout << overloadcutoff << "\t" << (10000.0 / (float)overloadcutoff) << "\t" << tvar << "\t" << overloadsum << "\t" << adjustsum << "\t" << afteroverloadsum << "\t" << crate << endl;
- return tvar;
-}
-
-
-int main()
-{
- for (int d=140; d>100; d -= 5) {
- float var = go(3,d);
- //cout << "## depth = " << d << endl;
- //cout << d << "\t" << var << endl;
- }
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- 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(1, 0, 10, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- return b;
- } else {
- // mixed
- Bucket *b = new TreeBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-float go(int dep)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- if (1) {
- for (int d=0; d<dep; d++)
- wid.push_back(10);
- }
- if (0) {
- if (dep == 0)
- wid.push_back(1000);
- if (dep == 1) {
- wid.push_back(1);
- wid.push_back(1000);
- }
- if (dep == 2) {
- wid.push_back(5);
- wid.push_back(5);
- wid.push_back(8);
- wid.push_back(5);
- }
- }
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
-
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- //cout << pg_per << " pgs per disk" << endl;
- // cout << numpg << " logical pgs" << endl;
- //cout << "numrep is " << numrep << endl;
-
-
- int place = 100000;
- int times = place / numpg;
- if (!times) times = 1;
-
- cout << "#looping " << times << " times" << endl;
-
- float tvar = 0;
- int tvarnum = 0;
- float tavg = 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;
- }
- }
-
- //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();
-
- if (times < 10)
- cout << "avg " << avg << " evar " << sqrt(avg) << " sd " << sqrt(var) << endl;
- //cout << avg << "\t";
-
- tvar += var;
- tavg += avg;
- tvarnum++;
- }
-
- tavg /= tvarnum;
- tvar /= tvarnum;
-
- cout << "total variance " << sqrt(tvar) << " expected " << sqrt(tavg) << endl;
-
- return tvar;
-}
-
-
-int main()
-{
- for (int d=2; d<=5; d++) {
- float var = go(d);
- //cout << "## depth = " << d << endl;
- //cout << d << "\t" << var << "\t" << sqrt(var) << endl;
- }
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- if (h == 0) {
- // uniform
- Hash hash(123);
- vector<int> disks;
- for (int i=0; i<wid[h]; i++)
- disks.push_back(ndisks++);
- float w = ((ndisks-1)/100+1)*10;
- UniformBucket *b = new UniformBucket(1, 0, w, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks weight " << w << endl;
- return b;
- } else {
- // mixed
- Bucket *b = new TreeBucket(h+1);
- //Bucket *b = new StrawBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-
-float go(int dep, int overloadcutoff)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- for (int d=0; d<dep; d++)
- wid.push_back(10);
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
- //c.overload[10] = .1;
-
-
- int pg_per_base = 10;
- int pg_per = pg_per_base*5.5;//100;
- int numpg = pg_per*ndisks/numrep;
-
- vector<int> ocount(ndisks);
- //cout << ndisks << " disks, " << endl;
- //cout << pg_per << " pgs per disk" << endl;
- // cout << numpg << " logical pgs" << endl;
- //cout << "numrep is " << numrep << endl;
-
-
- int place = 100000;
- int times = place / numpg;
- if (!times) times = 1;
-
-
- //cout << "looping " << times << " times" << endl;
-
- float tavg[10];
- float tvar[10];
- for (int j=0;j<10;j++) {
- tvar[j] = 0;
- tavg[j] = 0;
- }
- int tvarnum = 0;
-
- float overloadsum = 0.0;
- float adjustsum = 0.0;
- float afteroverloadsum = 0.0;
- int chooses = 0;
- int xs = 1;
- for (int t=0; t<times; t++) {
- vector<int> v(numrep);
-
- c.overload.clear();
-
- for (int z=0; z<ndisks; z++) ocount[z] = 0;
-
- for (int x=xs; x<numpg+xs; x++) {
-
- //cout << H(x) << "\t" << h(x) << endl;
- c.do_rule(rule, x, v);
- chooses += numrep;
- //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;
- }
-
- // overloaded?
- int overloaded = 0;
- int adjusted = 0;
- for (int i=0; i<ocount.size(); i++) {
- int target = (i/100+1)*10;
- int cutoff = target * overloadcutoff / 100;
- int adjoff = target + (cutoff - target)*3/4;
- if (ocount[i] > cutoff)
- overloaded++;
-
- if (ocount[i] > adjoff) {
- adjusted++;
- c.overload[i] = (float)target / (float)ocount[i];
- //cout << "setting overload " << i << " to " << c.overload[i] << endl;
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- ocount[i] = 0;
- }
- //cout << overloaded << " overloaded" << endl;
- overloadsum += (float)overloaded / (float)ndisks;
- adjustsum += (float)adjusted / (float)ndisks;
-
-
-
- if (1) {
- // second pass
- for (int x=xs; x<numpg+xs; 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;
- }
- }
-
- //cout << v << "\t" << ocount << endl;
- }
-
- for (int i=0; i<ocount.size(); i++) {
- int target = (i/100+1)*10;
- int cutoff = target * overloadcutoff / 100;
- int adjoff = cutoff;//target + (cutoff - target)*3/4;
-
- if (ocount[i] >= adjoff) {
- adjusted++;
- if (c.overload.count(i) == 0) {
- c.overload[i] = 1.0;
- adjusted++;
- }
- //else cout << "(re)adjusting " << i << endl;
- c.overload[i] *= (float)target / (float)ocount[i];
- //cout << "setting overload " << i << " to " << c.overload[i] << endl;
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- ocount[i] = 0;
- }
- }
-
- for (int x=xs; x<numpg+xs; 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;
- }
- }
- //cout << v << "\t" << ocount << endl;
- }
- xs += numpg;
-
- int still = 0;
- for (int i=0; i<ocount.size(); i++) {
- int target = (i/100+1)*10;
- int cutoff = target * overloadcutoff / 100;
- int adjoff = target + (cutoff - target)/3;
-
- if (ocount[i] > cutoff) {
- still++;
- //c.overload[ocount[i]] = 100.0 / (float)ocount[i];
- if (c.overload.count(i)) cout << "[adjusted] ";
- cout << "disk " << i << " has " << ocount[i] << endl;
- }
- }
- //if (still) cout << "overload was " << overloaded << " now " << still << endl;
- afteroverloadsum += (float)still / (float)ndisks;
-
- //cout << "collisions: " << c.collisions << endl;
- //cout << "r bumps: " << c.bumps << endl;
-
- int n = ndisks/10;
- float avg[10];
- float var[10];
- for (int i=0;i<10;i++) {
- int s = n*i;
- avg[i] = 0.0;
- for (int j=0; j<n; j++)
- avg[i] += ocount[j+s];
- avg[i] /= n;//ocount.size();
- var[i] = 0.0;
- for (int j=0; j<n; j++)
- var[i] += (ocount[j+s] - avg[i]) * (ocount[j+s] - avg[i]);
- var[i] /= n;//ocount.size();
-
- tvar[i] += var[i];
- tavg[i] += avg[i];
- }
- //cout << "avg " << avg << " var " << var << " sd " << sqrt(var) << endl;
-
- tvarnum++;
- }
-
- overloadsum /= tvarnum;
- adjustsum /= tvarnum;
- for (int j=0;j<10;j++) {
- tvar[j] /= tvarnum;
- tavg[j] /= tvarnum;
- }
- afteroverloadsum /= tvarnum;
-
- //int collisions = c.collisions[0] + c.collisions[1] + c.collisions[2] + c.collisions[3];
- //float crate = (float) collisions / (float)chooses;
- //cout << "collisions: " << c.collisions << endl;
-
-
- //cout << "total variance " << tvar << endl;
- //cout << " overlaod " << overloadsum << endl;
-
- cout << overloadcutoff << "\t" << (10000.0 / (float)overloadcutoff) << "\t" << overloadsum << "\t" << adjustsum << "\t" << afteroverloadsum;
- for (int i=0;i<10;i++)
- cout << "\t" << tavg[i] << "\t" << tvar[i];// << "\t" << tvar[i]/tavg[i];
- cout << endl;
- return tvar[0];
-}
-
-
-int main()
-{
- float var = go(3,200);
- for (int d=140; d>100; d -= 5) {
- float var = go(3,d);
- //cout << "## depth = " << d << endl;
- //cout << d << "\t" << var << endl;
- }
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- 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(1, 0, 1, disks);
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- buckets[h].push_back(b);
- return b;
- } else {
- // mixed
- MixedBucket *b = new MixedBucket(h+1);
- c.add_bucket(b);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, buckets, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- n->set_parent(b->get_id());
- }
- buckets[h].push_back(b);
- //cout << b->get_id() << " mixedbucket with " << wid[h] << " at " << h << endl;
- return b;
- }
-}
-
-int make_hierarchy(Crush& c, vector<int>& wid, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, buckets, ndisks);
- return b->get_id();
-}
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, map<int, vector<int> >& placement)
-{
- vector<int> v(numrep);
- map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
-
- placement[x] = v;
-
- //cout << v << "\t" << ocount << endl;
- }
-
- if (0)
- for (map<int,int>::iterator it = ocount.begin();
- it != ocount.end();
- it++)
- cout << it->first << "\t" << it->second << endl;
-
-}
-
-
-float testmovement(int depth, int branching, int udisks)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- wid.push_back(udisks);
- for (int d=1; d<depth; d++)
- wid.push_back(branching);
-
- map< int, list<Bucket*> > buckets;
-
- if (1) {
- root = make_hierarchy(c, wid, buckets, ndisks);
- }
- if (0) {
- MixedBucket *b = new MixedBucket(1);
- for (int i=0; i<10000; i++)
- b->add_item(ndisks++, 10);
- root = c.add_bucket(b);
- }
- if (0) {
- vector<int> disks;
- for (int i=0; i<10000; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- Hash h(123);
- b->make_primes(h);
- root = c.add_bucket(b);
- }
-
-
-
- // rule
- int numrep = 2;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- cout << pg_per << " pgs per disk" << endl;
- cout << numpg << " logical pgs" << endl;
- cout << "numrep is " << numrep << endl;
- */
- map<int, vector<int> > placement1, placement2;
-
- //c.print(cout, root);
-
- place(c, rule, numpg, numrep, placement1);
-
- if (1) {
- // failed
-
- //for (int i=500; i<1000; i++)
- //c.failed.insert(i);
- c.failed.insert(0);
- }
-
- int olddisks = ndisks;
-
- if (1) {
- int n = udisks;
- //cout << " adding " << n << " disks" << endl;
- vector<int> disks;
- for (int i=0; i<n; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- Hash h(123);
- b->make_primes(h);
- Bucket *o = buckets[1].back();
- c.add_bucket(b);
- //cout << " adding under " << o->get_id() << endl;
- c.add_item(o->get_id(), b->get_id(), b->get_weight());
- //((MixedBucket*)o)->add_item(b->get_id(), b->get_weight());
- }
-
- //c.print(cout, root);
- place(c, rule, numpg, numrep, placement2);
-
- int moved = 0;
- for (int x=1; x<=numpg; x++) {
- if (placement1[x] != placement2[x]) {
- for (int j=0; j<numrep; j++)
- if (placement1[x][j] != placement2[x][j])
- moved++;
-
- }
- }
-
- float f = (float)moved / (float)(numpg*numrep);
- float ideal = (float)(ndisks-olddisks) / (float)(ndisks);
- float fac = f/ideal;
- //cout << moved << " moved or " << f << ", ideal " << ideal << ", factor of " << fac << endl;
- return fac;
-}
-
-
-int main()
-{
-
- int udisks = 10;
- int ndisks = 10;
- for (int depth = 2; depth <= 4; depth++) {
- vector<float> v;
- cout << depth;
- for (int branching = 3; branching < 16; branching += 1) {
- float fac = testmovement(depth, branching, udisks);
- v.push_back(fac);
- int n = udisks * pow((float)branching, (float)depth-1);
- cout << "\t" << n;
- cout << "\t" << fac;
- }
- //for (int i=0; i<v.size(); i++)
- //cout << "\t" << v[i];
- cout << endl;
-
- }
-
-}
-
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- 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(1, 0, 1, disks);
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- buckets[h].push_back(b);
- return b;
- } else {
- // mixed
- MixedBucket *b = new MixedBucket(h+1);
- c.add_bucket(b);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, buckets, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- n->set_parent(b->get_id());
- }
- buckets[h].push_back(b);
- //cout << b->get_id() << " mixedbucket with " << wid[h] << " at " << h << endl;
- return b;
- }
-}
-
-int make_hierarchy(Crush& c, vector<int>& wid, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, buckets, ndisks);
- return b->get_id();
-}
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, map<int, set<int> >& placement)
-{
- vector<int> v(numrep);
- map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
- }
- placement[v[i]].insert(x);
- }
- if (bad)
- cout << "bad set " << x << ": " << v << endl;
-
-
- //cout << v << "\t" << ocount << endl;
- }
-
- if (0)
- for (map<int,int>::iterator it = ocount.begin();
- it != ocount.end();
- it++)
- cout << it->first << "\t" << it->second << endl;
-
-}
-
-
-float testmovement(int depth, int branching, int udisks)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- wid.push_back(udisks);
- for (int d=1; d<depth; d++)
- wid.push_back(branching);
-
- map< int, list<Bucket*> > buckets;
-
- if (1) {
- root = make_hierarchy(c, wid, buckets, ndisks);
- }
- if (0) {
- MixedBucket *b = new MixedBucket(1);
- for (int i=0; i<10000; i++)
- b->add_item(ndisks++, 10);
- root = c.add_bucket(b);
- }
- if (0) {
- vector<int> disks;
- for (int i=0; i<10000; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- Hash h(123);
- b->make_primes(h);
- root = c.add_bucket(b);
- }
-
-
-
- // rule
- int numrep = 2;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << endl;
- cout << pg_per << " pgs per disk" << endl;
- cout << numpg << " logical pgs" << endl;
- cout << "numrep is " << numrep << endl;
- */
- map<int, set<int> > placement1, placement2;
-
- //c.print(cout, root);
-
- place(c, rule, numpg, numrep, placement1);
-
- float over = .5;
-
- if (1) {
- // failed
-
- //for (int i=500; i<1000; i++)
- //c.failed.insert(i);
- //c.failed.insert(0);
- c.overload[0] = over;
- }
-
- int olddisks = ndisks;
-
-
-
- if (0) {
- int n = udisks;
- //cout << " adding " << n << " disks" << endl;
- vector<int> disks;
- for (int i=0; i<n; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- Hash h(123);
- b->make_primes(h);
- Bucket *o = buckets[1].back();
- c.add_bucket(b);
- //cout << " adding under " << o->get_id() << endl;
- c.add_item(o->get_id(), b->get_id(), b->get_weight());
- //((MixedBucket*)o)->add_item(b->get_id(), b->get_weight());
- }
-
- //c.print(cout, root);
- place(c, rule, numpg, numrep, placement2);
-
- vector<int> moved(ndisks);
-
- //int moved = 0;
- for (int d=0; d<ndisks; d++) {
- for (set<int>::iterator it = placement1[d].begin();
- it != placement1[d].end();
- it++) {
- placement2[d].erase(*it);
- }
- }
-
- float avg = 0;
- for (int d=0; d<ndisks; d++) {
- moved[d] = placement2[d].size();
- avg += moved[d];
- }
- avg /= (float)ndisks;
- float var = 0;
- for (int d=0; d<ndisks; d++) {
- var += (moved[d]-avg)*(moved[d]-avg);
- }
- var /= (float)ndisks;
-
- float expected = over * 100.0 / (float)(ndisks-1);
-
- cout << ndisks << "\t" << expected << "\t" << avg << "\t" << var << endl;
- /*
- float f = (float)moved / (float)(numpg*numrep);
- float ideal = (float)(ndisks-olddisks) / (float)(ndisks);
- float fac = f/ideal;
- //cout << moved << " moved or " << f << ", ideal " << ideal << ", factor of " << fac << endl;
- return fac;
- */
-}
-
-
-int main()
-{
-
- int udisks = 10;
- int ndisks = 10;
- for (int depth = 2; depth <= 4; depth++) {
- vector<float> v;
- cout << depth;
- for (int branching = 3; branching < 16; branching += 1) {
- float fac = testmovement(depth, branching, udisks);
- v.push_back(fac);
- int n = udisks * pow((float)branching, (float)depth-1);
- //cout << "\t" << n;
- //cout << "\t" << fac;
- }
- //for (int i=0; i<v.size(); i++)
- //cout << "\t" << v[i];
- //cout << endl;
-
- }
-
-}
-
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include "../../common/Clock.h"
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Clock g_clock;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- if (h == 0) {
- // uniform
- Hash hash(123);
- vector<int> disks;
- for (int i=0; i<wid[h]; i++)
- disks.push_back(ndisks++);
- float w = ((ndisks-1)/100+1)*10;
- UniformBucket *b = new UniformBucket(1, 0, w, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks weight " << w << endl;
- return b;
- } else {
- // mixed
- Bucket *b = new TreeBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-
-float go(int dep, int utilization )
-{
- Hash h(73232313);
-
- int overloadcutoff = (int)((float)10000.0 / (float)utilization);
-
- //cout << "util " << utilization << " cutoff " << overloadcutoff << endl;
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- for (int d=0; d<dep; d++)
- wid.push_back(10);
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
-
- //cout << ndisks << " disks" << endl;
-
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
- //c.overload[10] = .1;
-
- int pg_per_base = 20;
- int pg_med = 10*pg_per_base;
- int pg_per = pg_per_base*5.5;//100;
- int numpg = pg_per*ndisks/numrep;
-
- vector<int> ocount(ndisks);
- //cout << ndisks << " disks, " << endl;
- //cout << pg_per << " pgs per disk" << endl;
- // cout << numpg << " logical pgs" << endl;
- //cout << "numrep is " << numrep << endl;
-
-
- int place = 100000;
- int times = place / numpg;
- if (!times) times = 1;
-
-
- //cout << "looping " << times << " times" << endl;
-
- float tavg[10];
- float tvar[10];
- for (int j=0;j<10;j++) {
- tvar[j] = 0;
- tavg[j] = 0;
- }
- int tvarnum = 0;
-
- float overloadsum = 0.0;
- float adjustsum = 0.0;
- float afteroverloadsum = 0.0;
- float aslowdown = 0.0;
- int chooses = 0;
- int xs = 1;
- for (int t=0; t<times; t++) {
- vector<int> v(numrep);
-
- c.overload.clear();
-
- for (int z=0; z<ndisks; z++) ocount[z] = 0;
-
-
- utime_t t1a = g_clock.now();
-
- for (int x=xs; x<numpg+xs; x++) {
-
- //cout << H(x) << "\t" << h(x) << endl;
- c.do_rule(rule, x, v);
- chooses += numrep;
- //cout << "v = " << v << endl;// " " << v[0] << " " << v[1] << " " << v[2] << endl;
-
- for (int i=0; i<numrep; i++) {
- //int d = b.choose_r(x, i, h);
- //v[i] = d;
- ocount[v[i]]++;
- }
-
- //cout << v << "\t" << ocount << endl;
- }
-
- utime_t t1b = g_clock.now();
-
- // overloaded?
- int overloaded = 0;
- int adjusted = 0;
- for (int i=0; i<ocount.size(); i++) {
- int target = (i/100+1)*pg_per_base;
- int cutoff = target * overloadcutoff / 100;
- int adjoff = target + (cutoff - target)*3/4;
- if (ocount[i] > cutoff)
- overloaded++;
-
- if (ocount[i] > adjoff) {
- adjusted++;
- c.overload[i] = (float)target / (float)ocount[i];
- //cout << "setting overload " << i << " to " << c.overload[i] << endl;
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- ocount[i] = 0;
- }
- //cout << overloaded << " overloaded" << endl;
- overloadsum += (float)overloaded / (float)ndisks;
- adjustsum += (float)adjusted / (float)ndisks;
-
-
-
- // keep adjusting!
- for (int bla=0; bla<5; bla++) {
- utime_t t2a = g_clock.now();
-
- // second pass
- for (int x=xs; x<numpg+xs; 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;
-
- for (int i=0; i<numrep; i++) {
- //int d = b.choose_r(x, i, h);
- //v[i] = d;
- ocount[v[i]]++;
- }
-
- //cout << v << "\t" << ocount << endl;
- }
-
- utime_t t2b = g_clock.now();
-
- int numover = 0;
- for (int i=0; i<ocount.size(); i++) {
- int target = (i/100+1)*pg_per_base;
- int cutoff = target * overloadcutoff / 100;
- int adjoff = cutoff;//target + (cutoff - target)*3/4;
-
- if (ocount[i] >= adjoff) {
- numover++;
- if (c.overload.count(i) == 0) {
- c.overload[i] = 1.0;
- adjusted++;
- }
- //else cout << "(re)adjusting " << i << endl;
- c.overload[i] *= (float)target / (float)ocount[i];
- //cout << "setting overload " << i << " to " << c.overload[i] << endl;
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- ocount[i] = 0;
- }
- if (!numover) break;
- cout << "readjusting" << endl;
- }
-
- utime_t t3a = g_clock.now();
-
- for (int x=xs; x<numpg+xs; 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;
-
- for (int i=0; i<numrep; i++) {
- //int d = b.choose_r(x, i, h);
- //v[i] = d;
- ocount[v[i]]++;
- }
-
- //cout << v << "\t" << ocount << endl;
- }
- xs += numpg;
-
- utime_t t3b = g_clock.now();
-
- t1b -= t1a;
- double t1 = (double)t1b;
- t3b -= t3a;
- double t3 = (double)t3b;
- double slowdown = t3/t1;
- //cout << "slowdown " << slowdown << endl;
- aslowdown += slowdown;
-
- int still = 0;
- for (int i=0; i<ocount.size(); i++) {
- int target = (i/100+1)*pg_per_base;
- int cutoff = target * overloadcutoff / 100;
- //int adjoff = target + (cutoff - target)/3;
-
- if (ocount[i] > cutoff) {
- still++;
- //c.overload[ocount[i]] = 100.0 / (float)ocount[i];
- if (c.overload.count(i)) cout << "[adjusted] ";
- cout << "disk " << i << " has " << ocount[i] << endl;
- }
- }
- //if (still) cout << "overload was " << overloaded << " now " << still << endl;
- afteroverloadsum += (float)still / (float)ndisks;
-
- //cout << "collisions: " << c.collisions << endl;
- //cout << "r bumps: " << c.bumps << endl;
-
- int n = ndisks/10;
- float avg[10];
- float var[10];
- for (int i=0;i<10;i++) {
- int s = n*i;
- avg[i] = 0.0;
- for (int j=0; j<n; j++)
- avg[i] += ocount[j+s];
- avg[i] /= n;//ocount.size();
- var[i] = 0.0;
- for (int j=0; j<n; j++)
- var[i] += (ocount[j+s] - avg[i]) * (ocount[j+s] - avg[i]);
- var[i] /= n;//ocount.size();
-
- tvar[i] += var[i];
- tavg[i] += avg[i];
- }
- //cout << "avg " << avg << " var " << var << " sd " << sqrt(var) << endl;
-
- tvarnum++;
- }
-
- overloadsum /= tvarnum;
- adjustsum /= tvarnum;
- float avar = 0.0;
- for (int j=0;j<10;j++) {
- tvar[j] /= tvarnum;
- tavg[j] /= tvarnum;
- avar += tvar[j];
- }
- avar /= 10;
- avar = sqrt(avar);
- avar /= 5.5 * (float)pg_per_base;
- afteroverloadsum /= tvarnum;
- aslowdown /= tvarnum;
-
- //int collisions = c.collisions[0] + c.collisions[1] + c.collisions[2] + c.collisions[3];
- //float crate = (float) collisions / (float)chooses;
- //cout << "collisions: " << c.collisions << endl;
-
-
- //cout << "total variance " << tvar << endl;
- //cout << " overlaod " << overloadsum << endl;
-
- cout << overloadcutoff << "\t" << utilization
- << "\t" << overloadsum << "\t" << adjustsum << "\t" << afteroverloadsum
- << "\t" << aslowdown << "\t" << avar << "\t-";
-
- for (int i=0;i<10;i++)
- cout << "\t" << tavg[i] << "\t" << tvar[i];// << "\t" << tvar[i]/tavg[i];
- cout << endl;
- return tvar[0];
-}
-
-
-int main()
-{
- float var = go(3,50);
- /* for (int d=70; d<100; d += 5) {
- float var = go(3,d);
- //cout << "## depth = " << d << endl;
- //cout << d << "\t" << var << endl;
- }*/
- go(3,96);
- go(3,97);
- go(3,98);
- go(3,99);
-
-
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- 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(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(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-Bucket *make_random(Crush& c, int wid, int height, int& ndisks)
-{
- int w = rand() % (wid-1) + 2;
-
- if (height == 0) {
- // uniform
- Hash hash(123);
- vector<int> disks;
- for (int i=0; i<w; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 10, disks);
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- return b;
- } else {
- // mixed
- int h = rand() % height + 1;
- MixedBucket *b = new MixedBucket(h+1);
- for (int i=0; i<w; i++) {
- Bucket *n = make_random(c, wid, h-1, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- }
- c.add_bucket(b);
- //cout << h << " mixedbucket with " << wid[h] << endl;
- return b;
- }
-
-}
-
-
-float go(int dep, int overloadcutoff)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- for (int d=0; d<dep; d++)
- wid.push_back(10);
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
- if (0) {
- Bucket *r = make_random(c, 20, 4, ndisks);
- root = r->get_id();
- //c.print(cout, root);
- }
- if (0) {
- MixedBucket *b = new MixedBucket(1);
- for (int i=0; i<10000; i++)
- b->add_item(ndisks++, 10);
- root = c.add_bucket(b);
- }
- if (0) {
- vector<int> disks;
- for (int i=0; i<10000; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 10000, disks);
- Hash h(123);
- b->make_primes(h);
- root = c.add_bucket(b);
- }
- //cout << ndisks << " disks" << endl;
-
-
-
- // rule
- int numrep = 1;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 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, " << 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;
-
- float overloadsum = 0.0;
- float adjustsum = 0.0;
- float afteroverloadsum = 0.0;
- int chooses = 0;
- int xs = 1;
- for (int t=0; t<times; t++) {
- vector<int> v(numrep);
-
- c.overload.clear();
-
- for (int z=0; z<ndisks; z++) ocount[z] = 0;
-
- for (int x=xs; x<numpg+xs; x++) {
-
- //cout << H(x) << "\t" << h(x) << endl;
- c.do_rule(rule, x, v);
- chooses += numrep;
- //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;
- }
-
- // overloaded?
- int overloaded = 0;
- int adjusted = 0;
- for (int i=0; i<ocount.size(); i++) {
- if (ocount[i] > overloadcutoff)
- overloaded++;
-
- if (ocount[i] > 100+(overloadcutoff-100)/2) {
- adjusted++;
- c.overload[i] = 100.0 / (float)ocount[i];
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- ocount[i] = 0;
- }
- //cout << overloaded << " overloaded" << endl;
- overloadsum += (float)overloaded / (float)ndisks;
- adjustsum += (float)adjusted / (float)ndisks;
-
-
- for (int x=xs; x<numpg+xs; 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;
- }
- xs += numpg;
-
- int still = 0;
- for (int i=0; i<ocount.size(); i++) {
- if (ocount[i] > overloadcutoff) {
- still++;
- //c.overload[ocount[i]] = 100.0 / (float)ocount[i];
- //cout << "disk " << i << " has " << ocount[i] << endl;
- }
- }
- //if (still) cout << "overload was " << overloaded << " now " << still << endl;
- afteroverloadsum += (float)still / (float)ndisks;
-
- //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++;
- }
-
- overloadsum /= tvarnum;
- adjustsum /= tvarnum;
- tvar /= tvarnum;
- afteroverloadsum /= tvarnum;
-
- int collisions = c.collisions[0] + c.collisions[1] + c.collisions[2] + c.collisions[3];
- float crate = (float) collisions / (float)chooses;
- //cout << "collisions: " << c.collisions << endl;
-
-
- //cout << "total variance " << tvar << endl;
- //cout << " overlaod " << overloadsum << endl;
-
- cout << overloadcutoff << "\t" << (10000.0 / (float)overloadcutoff) << "\t" << tvar << "\t" << overloadsum << "\t" << adjustsum << "\t" << afteroverloadsum << "\t" << crate << endl;
- return tvar;
-}
-
-
-int main()
-{
- for (int d=140; d>100; d -= 5) {
- float var = go(3,d);
- //cout << "## depth = " << d << endl;
- //cout << d << "\t" << var << endl;
- }
-}
+++ /dev/null
-
-#include "include/types.h"
-#include "include/Distribution.h"
-#include "osd/OSDMap.h"
-
-
-Distribution file_size_distn; //kb
-
-
-list<int> object_queue;
-int max_object_size = 1024*1024*100; //kb
-
-off_t no;
-
-int get_object() //kb
-{
- if (object_queue.empty()) {
- int max = file_size_distn.sample();
- no++;
- int filesize = max/2 + (rand() % 100) * max/200 + 1;
- //cout << "file " << filesize << endl;
- while (filesize > max_object_size) {
- object_queue.push_back(max_object_size);
- filesize -= max_object_size;
- }
- object_queue.push_back(filesize);
- }
- int s = object_queue.front();
- object_queue.pop_front();
- //cout << "object " << s << endl;
- return s;
-}
-
-void getdist(vector<off_t>& v, float& avg, float& var)
-{
- avg = 0.0;
- for (int i=0; i<v.size(); i++)
- avg += v[i];
- avg /= v.size();
-
- var = 0.0;
- for (int i=0; i<v.size(); i++)
- var += (v[i] - avg) * (v[i] - avg);
- var /= v.size();
-}
-
-
-void testpgs(int n, // numpg
- off_t pggb,
- float& avg,
- float& var,
- off_t& numo
- )
-{
- off_t dist = (off_t)n * 1024LL*1024LL * (off_t)pggb; //kb
- vector<off_t> pgs(n);
- off_t did = 0;
-
- no = 0;
- while (did < dist) {
- off_t s = get_object();
- pgs[rand()%n] += s;
- did += s;
- }
- while (!object_queue.empty())
- pgs[rand()%n] += get_object();
-
- numo = no;
- //cout << did/n << endl;
-
- //for (int i=0; i<n; i++) cout << pgs[i] << endl;
-
- getdist(pgs, avg, var);
- //cout << "avg " << avg << " var " << var << " dev " << sqrt(var) << endl;
-
-}
-
-
-
-int main()
-{
- /*
-
-// File Size
-//cate count_mean size_mean
-1b -0.5 0.65434375 0
-1k 0.5 19.0758125 0.00875
-512K 1.5 35.6566 2.85875
-1M 2.5 27.7271875 25.0084375
-2M 3.5 16.63503125 20.8046875
-4M 4.5 106.82384375 296.053125
-8M 5.5 81.493375 335.77625
-16M 6.5 14.13553125 185.9775
-32M 7.5 2.176 52.921875
-256M 8.5 0.655938 47.8066
-512M 9.5 0.1480625 57.83375
-2G 10.5 0.020125 19.2888
- */
- file_size_distn.add(1, 19.0758125+0.65434375);
- file_size_distn.add(512, 35.6566);
- file_size_distn.add(1024, 27.7271875);
- file_size_distn.add(2*1024, 16.63503125);
- file_size_distn.add(4*1024, 106.82384375);
- file_size_distn.add(8*1024, 81.493375);
- file_size_distn.add(16*1024, 14.13553125);
- file_size_distn.add(32*1024, 2.176);
- file_size_distn.add(256*1024, 0.655938);
- file_size_distn.add(512*1024, 0.1480625);
- file_size_distn.add(1*1024*1024, 0.020125); // actually 2, but 32bit
- file_size_distn.normalize();
-
-
- for (int pggb = 1; pggb < 16; pggb++) {
- cout << pggb;
- for (int max = 1; max <= 1024; max *= 2) {
- float avg, var, var2, var3;
- off_t no;
- max_object_size = max*1024;
- testpgs(100, pggb, avg, var, no);
- testpgs(100, pggb, avg, var2, no);
- testpgs(100, pggb, avg, var3, no);
- float dev = sqrt((var+var2+var3)/3.0);
- cout << "\t" << no << "\t" << max << "\t" << dev;
- }
- cout << endl;
- }
-
-
-
-
-}
+++ /dev/null
-
-
-#include "../crush.h"
-using namespace crush;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- 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(1, 0, 1, disks);
- b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- buckets[h].push_back(b);
- return b;
- } else {
- // mixed
- Bucket *b = new TreeBucket(h+1);
- c.add_bucket(b);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, buckets, ndisks);
- b->add_item(n->get_id(), n->get_weight());
- n->set_parent(b->get_id());
- }
- buckets[h].push_back(b);
- //cout << b->get_id() << " mixedbucket with " << wid[h] << " at " << h << endl;
- return b;
- }
-}
-
-int make_hierarchy(Crush& c, vector<int>& wid, map< int, list<Bucket*> >& buckets, int& ndisks)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, buckets, ndisks);
- return b->get_id();
-}
-
-
-void place(Crush& c, Rule& rule, int numpg, int numrep, vector<int>& ocount)
-{
- vector<int> v(numrep);
- //map<int,int> ocount;
-
- for (int x=1; x<=numpg; 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;
-
- //placement[x] = v;
-
- //cout << v << "\t" << ocount << endl;
- }
-
-
-}
-
-
-int main()//float testmovement(int depth, int branching, int udisks)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- wid.push_back(10);
- wid.push_back(2);
-
- map< int, list<Bucket*> > buckets;
- root = make_hierarchy(c, wid, buckets, ndisks);
-
- // add small bucket
- vector<int> disks;
- for (int i=0; i<3; i++)
- disks.push_back(ndisks++);
- UniformBucket *b = new UniformBucket(1, 0, 1, disks);
- b->make_primes(h);
- Bucket *o = buckets[1].back();
- c.add_bucket(b);
- //cout << " adding under " << o->get_id() << endl;
- c.add_item(o->get_id(), b->get_id(), b->get_weight());
-
-
- // rule
- int numrep = 6;
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
- //c.overload[10] = .1;
-
- int pg_per = 10000;
- int numpg = pg_per*ndisks/numrep;
-
- vector<int> ocount(ndisks);
-
- c.print(cout, root);
-
- place(c, rule, numpg, numrep, ocount);
-
- for (int i=0; i<ocount.size(); i++) {
- cout << "disk " << i << " = " << ocount[i] << endl;
- }
-
- return 0;
-}
-
-
+++ /dev/null
-
-#include "../../common/Clock.h"
-#include "../crush.h"
-using namespace crush;
-
-
-Clock g_clock;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-int numrep = 1;
-
-
-double go(int n, int bucket)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- Bucket *b;
- vector<int> items;
- if (bucket == 0) b = new UniformBucket(1,0,10,items);
- if (bucket == 1) b = new TreeBucket(1);
- if (bucket == 2) b = new ListBucket(1);
- if (bucket == 3) b = new StrawBucket(1);
-
- for (int d=0; d<n; d++)
- b->add_item(ndisks++, 1);
-
- //if (!bucket) ((UniformBucket*)b)->make_primes(h);
-
- root = c.add_bucket(b);
-
- // rule
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
-
- int place = 1000000;
-
-
- vector<int> v(numrep);
- set<int> out;
- map<int,float> overload;
-
- utime_t start = g_clock.now();
-
- for (int x=1; x <= place; x++)
- c.do_rule(rule, x, v, out, overload);
-
- utime_t end = g_clock.now();
-
- end -= start;
- double el = (double)end;
-
- //cout << "\t" << ndisks;
-
- return el;
-}
-
-
-int main()
-{
-
- for (int n=4; n<=50; n += 4) {
- cout << n;
- for (int b=0; b<4; b++) {
- double el = go(n,b);
- cout << "\t" << el;
- }
- cout << endl;
- }
-}
+++ /dev/null
-
-#include "../../common/Clock.h"
-#include "../crush.h"
-using namespace crush;
-
-
-Clock g_clock;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-int uniform = 10;
-int branching = 10;
-int buckettype = 0;
-int numrep = 1;
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- 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(1, 0, 10, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- return b;
- } else {
- // mixed
- Bucket *b;
- if (buckettype == 0)
- b = new TreeBucket(h+1);
- else if (buckettype == 1 || buckettype == 2)
- b = new ListBucket(h+1);
- else if (buckettype == 3)
- b = new StrawBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-double go(int dep, int per)
-{
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- if (1) {
- wid.push_back(uniform);
- for (int d=1; d<dep; d++)
- wid.push_back(per);
- }
- if (0) {
- if (dep == 0)
- wid.push_back(1000);
- if (dep == 1) {
- wid.push_back(1);
- wid.push_back(1000);
- }
- if (dep == 2) {
- wid.push_back(5);
- wid.push_back(5);
- wid.push_back(8);
- wid.push_back(5);
- }
- }
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
-
-
-
- // rule
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
-
- int place = 1000000;
-
-
- vector<int> v(numrep);
-
- utime_t start = g_clock.now();
-
- set<int> out;
- map<int,float> overload;
-
- for (int x=1; x <= place; x++)
- c.do_rule(rule, x, v, out, overload);
-
- utime_t end = g_clock.now();
-
- end -= start;
- double el = (double)end;
-
- //cout << "\t" << ndisks;
-
- return el;
-}
-
-
-int main()
-{
- uniform = branching = 8;
-
- cout << "// dep\tuniform\tbranch\tndisks" << endl;
-
- for (int d=2; d<=5; d++) {
- cout << d;// << "\t" << branching;
- cout << "\t" << uniform;
- cout << "\t" << branching;
-
- int n = 1;
- for (int i=0; i<d; i++)
- n *= branching;
- cout << "\t" << n;
-
- numrep = 2;
-
- // crush
- for (buckettype = 0; buckettype <= 3; buckettype++) {
- switch (buckettype) {
- case 0: cout << "\ttree"; break;
- case 1: cout << "\tlist"; break;
- case 2: continue;
- case 3: cout << "\tstraw"; break;
- }
-
- //for (numrep = 1; numrep <= 3; numrep++) {
- //cout << "\t" << numrep;
-
- double el = go(d, branching);
- cout << "\t" << el;
- }
-
- // rush
-
- buckettype = 0;
- cout << "\trush_T\t" << go(2, n/uniform);
-
- buckettype = 1;
- cout << "\trush_P\t" << go(2, n/uniform);
-
- cout << endl;
- }
-}
+++ /dev/null
-
-#include "../../common/Clock.h"
-#include "../crush.h"
-using namespace crush;
-
-
-Clock g_clock;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-int branching = 10;
-bool linear = false;
-int numrep = 1;
-
-Bucket *make_bucket(Crush& c, vector<int>& wid, int h, int& ndisks)
-{
- 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(1, 0, 10, disks);
- //b->make_primes(hash);
- c.add_bucket(b);
- //cout << h << " uniformbucket with " << wid[h] << " disks" << endl;
- return b;
- } else {
- // mixed
- Bucket *b;
- if (linear)
- b = new ListBucket(h+1);
- else
- b = new TreeBucket(h+1);
- for (int i=0; i<wid[h]; i++) {
- Bucket *n = make_bucket(c, wid, h-1, ndisks);
- 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)
-{
- Bucket *b = make_bucket(c, wid, wid.size()-1, ndisks);
- return b->get_id();
-}
-
-
-double go(int s)
-{
- int dep = 2;
- Hash h(73232313);
-
- // crush
- Crush c;
-
-
- // buckets
- int root = -1;
- int ndisks = 0;
-
- vector<int> wid;
- if (1) {
- //for (int d=0; d<dep; d++)
- wid.push_back(8);
- wid.push_back(s/8);
- }
- if (0) {
- if (dep == 0)
- wid.push_back(1000);
- if (dep == 1) {
- wid.push_back(1);
- wid.push_back(1000);
- }
- if (dep == 2) {
- wid.push_back(5);
- wid.push_back(5);
- wid.push_back(8);
- wid.push_back(5);
- }
- }
-
- if (1) {
- root = make_hierarchy(c, wid, ndisks);
- }
-
-
-
- // rule
- Rule rule;
- rule.steps.push_back(RuleStep(CRUSH_RULE_TAKE, root));
- rule.steps.push_back(RuleStep(CRUSH_RULE_CHOOSE, numrep, 0));
- rule.steps.push_back(RuleStep(CRUSH_RULE_EMIT));
-
-
- int place = 1000000;
-
-
- vector<int> v(numrep);
-
- utime_t start = g_clock.now();
-
- for (int x=1; x <= place; x++)
- c.do_rule(rule, x, v);
-
- utime_t end = g_clock.now();
-
- end -= start;
- double el = (double)end;
-
- cout << "\t" << ndisks;
-
- return el;
-}
-
-
-int main()
-{
- branching = 8;
-
- int d = 2;
- numrep = 2;
-
- for (int s = 64; s <= 32768; s *= 8) {
- cout << "t";
- linear = false;
- double el = go(s, d);
- cout << "\t" << el;
-
- cout << "\tp";
- linear = true;
- el = go(s, d);
- cout << "\t" << el;
-
- cout << endl;
- }
-}
+++ /dev/null
-
-#include "../../common/Clock.h"
-#include "../crush.h"
-using namespace crush;
-
-
-Clock g_clock;
-
-#include <math.h>
-
-#include <iostream>
-#include <vector>
-using namespace std;
-
-
-int branching = 10;
-bool linear = false;
-int numrep = 1;
-
-int main() {
-
- Bucket *b = new UniformBucket(1, 0);
- //b = new TreeBucket(1);
-}
-
+++ /dev/null
-
-
-#include "../Bucket.h"
-using namespace crush;
-
-#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;
-}
-
-
-int main()
-{
- Hash h(73);
-
- int ndisks = 0;
- int numrep = 3;
-
- StrawBucket mb(1);
- /*for (int i=0;i<10;i++)
- mb.add_item(ndisks++, 10);
- */
- mb.add_item(ndisks++, 1);
- mb.add_item(ndisks++, 1);
- mb.add_item(ndisks++, 10);
- mb.add_item(ndisks++, 10);
- mb.add_item(ndisks++, 100);
- mb.add_item(ndisks++, 1000);
-
- vector<int> ocount(ndisks);
-
- vector<int> v(numrep);
- int nplace = 0;
- for (int x=1; x<1000000; x++) {
- //cout << H(x) << "\t" << h(x) << endl;
- for (int i=0; i<numrep; i++) {
- int d = mb.choose_r(x, i, h);
- v[i] = d;
- ocount[d]++;
- nplace++;
- }
- //cout << v << "\t" << endl;//ocount << endl;
- }
-
- for (int i=0; i<ocount.size(); i++) {
- float f = ocount[i] / (float)nplace;
- cout << "disk " << i << " has " << ocount[i] << " " << f << endl;
- }
-
-}
+++ /dev/null
-
-#include <vector>
-#include <iostream>
-using namespace std;
-
-
-void getdist(vector<int>& v, float& avg, float& var)
-{
- avg = 0.0;
- for (int i=0; i<v.size(); i++)
- avg += v[i];
- avg /= v.size();
-
- var = 0.0;
- for (int i=0; i<v.size(); i++)
- var += (v[i] - avg) * (v[i] - avg);
- var /= v.size();
-}
-
-int main()
-{
- int n = 50;
- vector<int> a(n);
- vector<int> b(n);
-
- for (int i=0; i<n*n; i++)
- a[rand()%n]++;
-
- float aavg, avar;
- getdist(a, aavg, avar);
-
- for (int i=0; i<7*n*n; i++)
- b[rand()%n]++;
-
- float bavg, bvar;
- getdist(b, bavg, bvar);
-
- cout << "a avg " << aavg << " var " << avar << endl;
- cout << "b avg " << bavg << " var " << bvar << endl;
-
-
- vector<int> c(n);
- for (int i=0; i<n; i++)
- c[i] = a[i] * b[i];
-
- float cavg, cvar;
- getdist(c, cavg, cvar);
-
- cout << "c avg " << cavg << " var " << cvar << endl;
-
-}