Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 #include "P_Cluster.h"
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 bool machineClusterHash = true;
00046 bool boundClusterHash = false;
00047 bool randClusterHash = false;
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 inline unsigned short
00071 next_rnd15(unsigned int *p)
00072 {
00073   unsigned int seed = *p;
00074   seed = 1103515145 * seed + 12345;
00075   seed = seed & 0x7FFF;
00076   *p = seed;
00077   return seed;
00078 }
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 void
00089 build_hash_table_machine(ClusterConfiguration * c)
00090 {
00091   int left = CLUSTER_HASH_TABLE_SIZE;
00092   int m = 0;
00093   int i = 0;
00094   unsigned int rnd[CLUSTER_MAX_MACHINES];
00095   unsigned int mach[CLUSTER_MAX_MACHINES];
00096   int total = CLUSTER_HASH_TABLE_SIZE;
00097 
00098   for (i = 0; i < c->n_machines; i++) {
00099     int mine = total / (c->n_machines - i);
00100     mach[i] = mine;
00101     total -= mine;
00102   }
00103 
00104   
00105   
00106   
00107   for (m = 0; m < c->n_machines; m++)
00108     rnd[m] = (((c->machines[m]->ip >> 15) & 0x7FFF) ^ (c->machines[m]->ip & 0x7FFF))
00109       ^ (c->machines[m]->ip >> 30);
00110 
00111   
00112   
00113   for (i = 0; i < CLUSTER_HASH_TABLE_SIZE; i++)
00114     c->hash_table[i] = 255;
00115 
00116   
00117   
00118   
00119   m = 0;
00120   while (left) {
00121     if (!mach[m] && boundClusterHash) {
00122       m = (m + 1) % c->n_machines;
00123       continue;
00124     }
00125     do {
00126       if (randClusterHash) {
00127         i = ink_rand_r(&rnd[m]) % CLUSTER_HASH_TABLE_SIZE;
00128       } else
00129         i = next_rand(&rnd[m]) % CLUSTER_HASH_TABLE_SIZE;
00130     } while (c->hash_table[i] != 255);
00131     mach[m]--;
00132     c->hash_table[i] = m;
00133     left--;
00134     m = (m + 1) % c->n_machines;
00135   }
00136 }
00137 
00138 static void
00139 build_hash_table_bucket(ClusterConfiguration * c)
00140 {
00141   int i = 0;
00142   unsigned int rnd[CLUSTER_HASH_TABLE_SIZE];
00143   unsigned int mach[CLUSTER_MAX_MACHINES];
00144   int total = CLUSTER_HASH_TABLE_SIZE;
00145 
00146   for (i = 0; i < c->n_machines; i++) {
00147     int mine = total / (c->n_machines - i);
00148     mach[i] = mine;
00149     total -= mine;
00150   }
00151 
00152   for (i = 0; i < CLUSTER_HASH_TABLE_SIZE; i++)
00153     rnd[i] = i;
00154 
00155   for (i = 0; i < CLUSTER_HASH_TABLE_SIZE; i++) {
00156     unsigned char x = 0;
00157     do {
00158       if (randClusterHash) {
00159         x = ink_rand_r(&rnd[i]) % CLUSTER_MAX_MACHINES;
00160       } else
00161         x = next_rand(&rnd[i]) % CLUSTER_MAX_MACHINES;
00162     } while (x >= c->n_machines || (!mach[x] && boundClusterHash));
00163     mach[x]--;
00164     c->hash_table[i] = x;
00165   }
00166 }
00167 
00168 void
00169 build_cluster_hash_table(ClusterConfiguration * c)
00170 {
00171   if (machineClusterHash)
00172     build_hash_table_machine(c);
00173   else
00174     build_hash_table_bucket(c);
00175 }