Javolution 6.0.0 java
FractalMapImpl.java
Go to the documentation of this file.
1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2012 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */
9 package javolution.util.internal.map;
10 
17 @SuppressWarnings("rawtypes")
18 final class FractalMapImpl {
19 
20  static final int EMPTINESS_LEVEL = 2; // Can be 1 (load factor 0.5), 2 (load factor 0.25) or any greater value.
21  static final int INITIAL_BLOCK_CAPACITY = 2 << EMPTINESS_LEVEL;
22  static final int SHIFT = 10; // Number of hashcode bits per depth.
23  //private static final int MAX_BLOCK_CAPACITY = 1 << SHIFT;
24  private int count; // Number of entries different from null in this block.
25  private MapEntryImpl[] entries = new MapEntryImpl[INITIAL_BLOCK_CAPACITY]; // Entries value can be a sub-map.
26  private final int shift; // Zero if base map.
27 
28  public FractalMapImpl() {
29  this.shift = 0;
30  }
31 
32  public FractalMapImpl(int shift) {
33  this.shift = shift;
34  }
35 
38  @SuppressWarnings("unchecked")
39  public MapEntryImpl addEntry(MapEntryImpl newEntry, Object key, int hash) {
40  int i = indexOfKey(key, hash);
41  MapEntryImpl entry = entries[i];
42  if (entry != null) return entry; // Entry exists
43  entries[i] = newEntry;
44  newEntry.key = key;
45  newEntry.hash = hash;
46  // Check if we need to resize.
47  if ((++count << EMPTINESS_LEVEL) > entries.length) {
48  resize(entries.length << 1);
49  }
50  return newEntry;
51  }
52 
53  public void clear() {
54  entries = new MapEntryImpl[INITIAL_BLOCK_CAPACITY];
55  count = 0;
56  }
57 
59  public MapEntryImpl getEntry(Object key, int hash) {
60  return entries[indexOfKey(key, hash)];
61  }
62 
64  public MapEntryImpl removeEntry(Object key, int hash) {
65  int i = indexOfKey(key, hash);
66  MapEntryImpl oldEntry = entries[i];
67  if (oldEntry == null) return null; // Entry does not exist.
68  entries[i] = null;
69  // Since we have made a hole, adjacent keys might have to shift.
70  for (;;) {
71  // We use a step of 1 (improve caching through memory locality).
72  i = (i + 1) & (entries.length - 1);
73  MapEntryImpl entry = entries[i];
74  if (entry == null) break; // Done.
75  int correctIndex = indexOfKey(entry.key, entry.hash);
76  if (correctIndex != i) { // Misplaced.
77  entries[correctIndex] = entries[i];
78  entries[i] = null;
79  }
80  }
81  // Check if we need to resize.
82  if (((--count << (EMPTINESS_LEVEL + 1)) <= entries.length)
83  && (entries.length > INITIAL_BLOCK_CAPACITY)) {
84  resize(entries.length >> 1);
85  }
86  return oldEntry;
87  }
88 
91  private int indexOfKey(Object key, int hash) {
92  int mask = entries.length - 1;
93  int i = (hash >> shift) & mask;
94  while (true) {
95  MapEntryImpl entry = entries[i];
96  if (entry == null) return i;
97  if ((entry.hash == hash) && key.equals(entry.key)) return i;
98  i = (i + 1) & mask;
99  }
100  }
101 
102  // The capacity is a power of two such as:
103  // (count * 2**EMPTINESS_LEVEL) <= capacity < (count * 2**(EMPTINESS_LEVEL+1))
104  // TODO: Use submaps if max capacity reached.
105  private void resize(int newCapacity) {
106  MapEntryImpl[] newEntries = new MapEntryImpl[newCapacity];
107  int newMask = newEntries.length - 1;
108  for (int i = 0, n = entries.length; i < n; i++) {
109  MapEntryImpl entry = entries[i];
110  if (entry == null) continue;
111  int newIndex = entry.hash & newMask;
112  while (newEntries[newIndex] != null) { // Find empty slot.
113  newIndex = (newIndex + 1) & newMask;
114  }
115  newEntries[newIndex] = entry;
116  }
117  entries = newEntries;
118  }
119 }
javolution.util.internal.map.FractalMapImpl.shift
final int shift
Definition: FractalMapImpl.java:26
javolution.util.internal.map.MapEntryImpl
Definition: MapEntryImpl.java:16
javolution.util.internal.map.FractalMapImpl.removeEntry
MapEntryImpl removeEntry(Object key, int hash)
Definition: FractalMapImpl.java:64
javolution.util.internal.map.FractalMapImpl.FractalMapImpl
FractalMapImpl()
Definition: FractalMapImpl.java:28
javolution.util.internal.map.FractalMapImpl.indexOfKey
int indexOfKey(Object key, int hash)
Definition: FractalMapImpl.java:91
javolution.util.internal.map.MapEntryImpl.key
K key
Definition: MapEntryImpl.java:19
javolution.util.internal.map.FractalMapImpl
Definition: FractalMapImpl.java:18
javolution.util.internal.map.FractalMapImpl.resize
void resize(int newCapacity)
Definition: FractalMapImpl.java:105
javolution.util.internal.map.MapEntryImpl.hash
int hash
Definition: MapEntryImpl.java:18
javolution.util.internal.map.FractalMapImpl.count
int count
Definition: FractalMapImpl.java:24
javolution.util.internal.map.FractalMapImpl.clear
void clear()
Definition: FractalMapImpl.java:53
javolution.util.internal.map.FractalMapImpl.getEntry
MapEntryImpl getEntry(Object key, int hash)
Definition: FractalMapImpl.java:59
javolution.util.internal.map.FractalMapImpl.FractalMapImpl
FractalMapImpl(int shift)
Definition: FractalMapImpl.java:32