-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathBlock.java
More file actions
282 lines (228 loc) · 8.33 KB
/
Block.java
File metadata and controls
282 lines (228 loc) · 8.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
package peersim.kademlia.das;
import java.math.BigInteger;
import java.util.Collection;
import java.util.Iterator;
import java.util.TreeSet;
import peersim.core.CommonState;
import peersim.core.Network;
import peersim.kademlia.KademliaCommonConfig;
public class Block implements Iterator<Sample>, Cloneable {
/** The square matrix of samples */
private Sample[][] blockSamples;
/** Block identifier */
private long blockId;
/** Row and column numbers used by the iterator */
private int row, column;
/** block square matrix dimension (number of samples per row/column) */
private int SIZE;
/** Maximum key in the keyspace of BITS length */
public static BigInteger MAX_KEY;
/** allow to call the service initializer only once */
private static boolean _ALREADY_INITIALISED = false;
/** gap between two samples in the keyspace */
public static BigInteger INTER_SAMPLE_GAP;
/** number of samples in a block */
private int numSamples;
// private TreeSet<BigInteger> samples;
private TreeSet<BigInteger> samplesByRow;
private TreeSet<BigInteger> samplesByColumn;
// private HashMap<BigInteger, BigInteger> sampleMap;
// Constructor with block id
public Block(long id) {
SIZE = 512;
this.numSamples = this.SIZE * this.SIZE;
_init();
samplesByRow = new TreeSet<>();
samplesByColumn = new TreeSet<>();
// sampleMap = new HashMap<>();
this.blockId = id;
blockSamples = new Sample[SIZE][SIZE];
row = column = 0;
for (int i = 1; i <= blockSamples.length; i++) {
for (int j = 1; j <= blockSamples[0].length; j++) {
blockSamples[i][j] = new Sample(blockId, i + 1, j + 1, this);
samplesByRow.add(blockSamples[i][j].getIdByRow());
samplesByColumn.add(blockSamples[i][j].getIdByColumn());
// sampleMap.put(blockSamples[i][j].getIdByColumn(), blockSamples[i][j].getIdByRow());
}
}
}
// Constructor specifying block id and matrix size
public Block(int size, long id) {
SIZE = size;
this.numSamples = this.SIZE * this.SIZE;
_init();
samplesByRow = new TreeSet<>();
samplesByColumn = new TreeSet<>();
// sampleMap = new HashMap<>();
this.blockId = id;
blockSamples = new Sample[SIZE][SIZE];
row = column = 0;
for (int i = 0; i < blockSamples.length; i++) {
for (int j = 0; j < blockSamples[0].length; j++) {
blockSamples[i][j] = new Sample(blockId, i + 1, j + 1, this);
samplesByRow.add(blockSamples[i][j].getIdByRow());
samplesByColumn.add(blockSamples[i][j].getIdByColumn());
// sampleMap.put(blockSamples[i][j].getIdByColumn(), blockSamples[i][j].getIdByRow());
}
}
}
// Constructor used when cloning
public Block(Sample[][] blockSamples, int size, long id) {
SIZE = size;
this.numSamples = this.SIZE * this.SIZE;
_init();
this.blockSamples = blockSamples;
row = column = 0;
this.blockId = id;
// samples = new TreeSet<>();
samplesByRow = new TreeSet<>();
samplesByColumn = new TreeSet<>();
for (int i = 0; i < blockSamples.length; i++) {
for (int j = 0; j < blockSamples[0].length; j++) {
blockSamples[i][j] = new Sample(blockId, i + 1, j + 1, this);
samplesByRow.add(blockSamples[i][j].getIdByRow());
samplesByColumn.add(blockSamples[i][j].getIdByColumn());
// sampleMap.put(blockSamples[i][j].getIdByColumn(), blockSamples[i][j].getIdByRow());
}
}
}
/**
* Replicate this object by returning an identical copy.<br>
* It is called by the initializer and do not fill any particular field.
*
* @return Object
*/
public Object clone() {
initIterator();
Block dolly = new Block(this.blockSamples, this.SIZE, this.blockId);
return dolly;
}
/** Compute the radius of the region containing the desired number of copies of each sample */
public BigInteger computeRegionRadius(int numberOfCopiesPerSample) {
/**
* Calculate the radius by dividing Id space by number of nodes in the network, and multiplying
* by number of copies per sample The result is divided by 2 to calculate the radius (instead of
* diameter)
*/
BigInteger radius =
MAX_KEY
.divide(BigInteger.valueOf(Network.size()))
.multiply(BigInteger.valueOf(numberOfCopiesPerSample));
// radius = radius.shiftRight(1);
return radius;
}
/** Returns the block id */
public long getBlockId() {
return this.blockId;
}
/* Returns all the block samples */
public Sample[][] getSamples() {
return this.blockSamples;
}
/* Returns the ids of n random selected samples */
public BigInteger[] getNRandomSamplesIds(int n) {
BigInteger[] samples = new BigInteger[n];
for (int i = 0; i < samples.length; i++) {
int r = CommonState.r.nextInt(SIZE);
int c = CommonState.r.nextInt(SIZE);
samples[i] = this.blockSamples[r][c].getId();
}
return samples;
}
/* Returns n random selected samples */
public Sample[] getNRandomSamples(int n) {
Sample[] samples = new Sample[n];
for (int i = 0; i < samples.length; i++) {
int r = CommonState.r.nextInt(SIZE);
int c = CommonState.r.nextInt(SIZE);
samples[i] = this.blockSamples[r][c];
}
return samples;
}
/* Returns the ids of n random selected samples */
public Sample getSample(int row, int column) {
return this.blockSamples[row][column];
}
@Override
public boolean hasNext() {
if (row < SIZE) return true;
return false;
}
@Override
public Sample next() {
Sample s = blockSamples[row][column];
column++;
if (column == SIZE) {
row++;
column = 0;
}
if (column > SIZE - 1) return null;
return s;
}
/*Resets the iterator pointers */
public void initIterator() {
column = row = 0;
}
/* Returns the block matrix size */
public int getSize() {
return this.SIZE;
}
/* Returns the total number of samples in the block */
public int getNumSamples() {
return this.numSamples;
}
/* Returns the total number of samples in the block */
public BigInteger[] getSamplesByRadius(BigInteger peerId, BigInteger radius) {
BigInteger top = peerId.add(radius);
BigInteger bottom = peerId.subtract(radius);
Collection<BigInteger> subSet = samplesByRow.subSet(bottom, true, top, true);
return (BigInteger[]) subSet.toArray(new BigInteger[0]);
}
/* Returns the ids of the samples within the radius to the peerId specified*/
public BigInteger[] getSamplesByRadiusByRow(BigInteger peerId, BigInteger radius) {
BigInteger top = peerId.add(radius);
BigInteger bottom = peerId.subtract(radius);
Collection<BigInteger> subSet = samplesByRow.subSet(bottom, true, top, true);
return (BigInteger[]) subSet.toArray(new BigInteger[0]);
}
/* Returns the ids of the samples within the radius to the peerId specified, using sample column id*/
public BigInteger[] getSamplesByRadiusByColumn(BigInteger peerId, BigInteger radius) {
BigInteger top = peerId.add(radius);
BigInteger bottom = peerId.subtract(radius);
Collection<BigInteger> subSet = samplesByColumn.subSet(bottom, true, top, true);
/*List<BigInteger> result = new ArrayList<>();
for (BigInteger sampleId : subSet) {
result.add(sampleMap.get(sampleId));
}
return (BigInteger[]) result.toArray(new BigInteger[0]);*/
return (BigInteger[]) subSet.toArray(new BigInteger[0]);
}
/* Returns the ids of the all the samples in a specific row*/
public BigInteger[] getSamplesIdsByRow(int row) {
BigInteger[] samples = new BigInteger[this.SIZE];
for (int i = 0; i < samples.length; i++) {
samples[i] = this.blockSamples[row - 1][i].getIdByRow();
}
return samples;
}
/* Returns the ids of the all the samples in a specific column*/
public BigInteger[] getSamplesIdsByColumn(int column) {
BigInteger[] samples = new BigInteger[this.SIZE];
for (int i = 0; i < samples.length; i++) {
samples[i] = this.blockSamples[i][column - 1].getIdByColumn();
}
return samples;
}
private void _init() {
// execute once
if (_ALREADY_INITIALISED) return;
MAX_KEY = BigInteger.ONE.shiftLeft(KademliaCommonConfig.BITS).subtract(BigInteger.ONE);
try {
INTER_SAMPLE_GAP = MAX_KEY.divide(BigInteger.valueOf(this.numSamples));
} catch (ArithmeticException e) {
e.printStackTrace();
}
_ALREADY_INITIALISED = true;
}
}