-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSimpleStream.java
128 lines (107 loc) · 3.18 KB
/
SimpleStream.java
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
/**
* Expanding and contracting stack of longs
*/
public class SimpleStream {
private final int LONGS_PER_REGION;
private final int LOG2_LONGS_PER_REGION;
private final int SIXTYFOUR_MINUS_LOG2_LONGS_PER_REGION;
private long[][] regions;
private int topRegion, topPointer; // Last used element in the stack
private long nElements; // Total number of elements in the stream
/**
* @param longsPerRegion must be a power of two.
*/
public SimpleStream(int longsPerRegion) {
LONGS_PER_REGION=longsPerRegion;
LOG2_LONGS_PER_REGION=Utils.log2(longsPerRegion);
SIXTYFOUR_MINUS_LOG2_LONGS_PER_REGION=64-LOG2_LONGS_PER_REGION;
regions = new long[1][longsPerRegion];
topRegion=0; topPointer=-1;
nElements=0;
}
public void clear(boolean deallocate) {
if (deallocate) regions = new long[1][LONGS_PER_REGION];
topRegion=0; topPointer=-1;
nElements=0;
}
public void deallocate() {
int nRegions = regions.length;
for (int i=0; i<nRegions; i++) regions[i]=null;
regions=null;
}
public final long nElements() {
return nElements;
}
/**
* Appends $value$ to the stack, possibly expanding the stack. Expansion implies:
* (1) doubling the size of $regions$; (2) copying $regions.length$ pointers (using
* the internalized procedure $System.arraycopy$); (3) increasing the number of
* allocated bits by one region.
*/
public final void push(long value) {
if (topPointer==LONGS_PER_REGION-1) {
int nRegions = regions.length;
if (topRegion==nRegions-1) {
long[][] newRegions = new long[nRegions<<1][0];
System.arraycopy(regions,0,newRegions,0,nRegions);
regions=newRegions;
}
topRegion++;
regions[topRegion] = new long[LONGS_PER_REGION];
topPointer=0;
}
else topPointer++;
regions[topRegion][topPointer]=value;
nElements++;
}
/**
* Removes the last element from the top of the stack, possibly contracting the stack.
* The last unused region (if any) is immediately deallocated.
*/
public final void pop() {
nElements--;
if (topPointer==0) {
regions[topRegion]=null;
topRegion--;
topPointer=LONGS_PER_REGION-1;
}
else topPointer--;
}
/**
* Reads the $i$th element in the stack. The procedure assumes that $i$ is a valid
* index: no explicit check is performed.
*/
public final long getElementAt(long i) {
int pointer = (int)(i&Utils.shiftOnesRight[SIXTYFOUR_MINUS_LOG2_LONGS_PER_REGION]);
i>>>=LOG2_LONGS_PER_REGION;
return regions[(int)i][pointer];
}
/**
* Remark: assumes that $toIndex>=fromIndex$. No explicit check is performed.
*
* @param fromIndex rank of the first integer in the sequence of integers; the search
* includes this integer;
* @param toIndex rank of the last integer in the sequence of integers; the search
* does not include this integer;
* @return the rank of $key$ in the sequence of integers, or -1 if $key$ does not
* occur in the stream.
*/
public final long binarySearch(long fromIndex, long toIndex, long key) {
long a, z, m, value;
a=fromIndex;
z=toIndex-1;
do {
m=(z+a)>>1;
value=getElementAt(m);
if (key==value) {
z=a=m;
break;
}
else if (key<value) z=m-1;
else a=m+1;
}
while (z>a);
if (a==z) return a;
else return -1;
}
}