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 package org.archive.util.fingerprint;
26
27 import java.io.Serializable;
28 import java.util.logging.Logger;
29
30 import org.archive.util.AbstractLongFPSet;
31
32 /***
33 * Open-addressing in-memory hash set for holding primitive long fingerprints.
34 *
35 * @author Gordon Mohr
36 */
37 public class MemLongFPSet extends AbstractLongFPSet
38 implements LongFPSet, Serializable {
39
40
41 private static final long serialVersionUID = -4301879539092625698L;
42
43
44 private static Logger logger =
45 Logger.getLogger(MemLongFPSet.class.getName());
46 private static final int DEFAULT_CAPACITY_POWER_OF_TWO = 10;
47 private static final float DEFAULT_LOAD_FACTOR = 0.75f;
48 protected byte[] slots;
49 protected long[] values;
50
51 public MemLongFPSet() {
52 this(DEFAULT_CAPACITY_POWER_OF_TWO, DEFAULT_LOAD_FACTOR);
53 }
54
55 /***
56 * @param capacityPowerOfTwo The capacity as the exponent of a power of 2.
57 * e.g if the capacity is <code>4</code> this means <code>2^^4</code>
58 * entries.
59 * @param loadFactor The load factor as a fraction. This gives the amount
60 * of free space to keep in the Set.
61 */
62 public MemLongFPSet(int capacityPowerOfTwo, float loadFactor) {
63 super(capacityPowerOfTwo, loadFactor);
64 slots = new byte[1 << capacityPowerOfTwo];
65 for(int i = 0; i < (1 << capacityPowerOfTwo); i++) {
66 slots[i] = EMPTY;
67 }
68 values = new long[1 << capacityPowerOfTwo];
69 }
70
71 protected void setAt(long i, long val) {
72 slots[(int)i] = 1;
73 values[(int)i] = val;
74 }
75
76 protected long getAt(long i) {
77 return values[(int)i];
78 }
79
80 protected void makeSpace() {
81 grow();
82 }
83
84 private void grow() {
85
86 logger.info("Doubling fingerprinting slots to "
87 + (1 << this.capacityPowerOfTwo));
88 long[] oldValues = values;
89 byte[] oldSlots = slots;
90 capacityPowerOfTwo++;
91 values = new long[1 << capacityPowerOfTwo];
92 slots = new byte[1 << capacityPowerOfTwo];
93 for(int i = 0; i < (1 << capacityPowerOfTwo); i++) {
94 slots[i]=EMPTY;
95 }
96 count=0;
97 for(int i = 0; i< oldValues.length; i++) {
98 if(oldSlots[i]>=0) {
99 add(oldValues[i]);
100 }
101 }
102 }
103
104 protected void relocate(long val, long oldIndex, long newIndex) {
105 values[(int)newIndex] = values[(int)oldIndex];
106 slots[(int)newIndex] = slots[(int)oldIndex];
107 slots[(int)oldIndex] = EMPTY;
108 }
109
110 protected int getSlotState(long i) {
111 return slots[(int)i];
112 }
113
114 protected void clearAt(long index) {
115 slots[(int)index]=EMPTY;
116 values[(int)index]=0;
117 }
118
119 public boolean quickContains(long fp) {
120 return contains(fp);
121 }
122 }