001: package org.garret.perst.impl;
002:
003: import org.garret.perst.*;
004:
005: public class StrongHashTable implements OidHashTable {
006: Entry table[];
007: static final float loadFactor = 0.75f;
008: int count;
009: int threshold;
010: boolean flushing;
011:
012: static final int MODIFIED_BUFFER_SIZE = 1024;
013: IPersistent[] modified;
014: int nModified;
015:
016: public StrongHashTable(int initialCapacity) {
017: threshold = (int) (initialCapacity * loadFactor);
018: if (initialCapacity != 0) {
019: table = new Entry[initialCapacity];
020: }
021: modified = new IPersistent[MODIFIED_BUFFER_SIZE];
022: }
023:
024: public synchronized boolean remove(int oid) {
025: Entry tab[] = table;
026: int index = (oid & 0x7FFFFFFF) % tab.length;
027: for (Entry e = tab[index], prev = null; e != null; prev = e, e = e.next) {
028: if (e.oid == oid) {
029: e.obj = null;
030: count -= 1;
031: if (prev != null) {
032: prev.next = e.next;
033: } else {
034: tab[index] = e.next;
035: }
036: return true;
037: }
038: }
039: return false;
040: }
041:
042: public synchronized void put(int oid, IPersistent obj) {
043: Entry tab[] = table;
044: int index = (oid & 0x7FFFFFFF) % tab.length;
045: for (Entry e = tab[index]; e != null; e = e.next) {
046: if (e.oid == oid) {
047: e.obj = obj;
048: return;
049: }
050: }
051: if (count >= threshold && !flushing) {
052: // Rehash the table if the threshold is exceeded
053: rehash();
054: tab = table;
055: index = (oid & 0x7FFFFFFF) % tab.length;
056: }
057:
058: // Creates the new entry.
059: tab[index] = new Entry(oid, obj, tab[index]);
060: count++;
061: }
062:
063: public synchronized IPersistent get(int oid) {
064: Entry tab[] = table;
065: int index = (oid & 0x7FFFFFFF) % tab.length;
066: for (Entry e = tab[index]; e != null; e = e.next) {
067: if (e.oid == oid) {
068: return e.obj;
069: }
070: }
071: return null;
072: }
073:
074: void rehash() {
075: int oldCapacity = table.length;
076: Entry oldMap[] = table;
077: int i;
078:
079: int newCapacity = oldCapacity * 2 + 1;
080: Entry newMap[] = new Entry[newCapacity];
081:
082: threshold = (int) (newCapacity * loadFactor);
083: table = newMap;
084:
085: for (i = oldCapacity; --i >= 0;) {
086: for (Entry old = oldMap[i]; old != null;) {
087: Entry e = old;
088: old = old.next;
089:
090: int index = (e.oid & 0x7FFFFFFF) % newCapacity;
091: e.next = newMap[index];
092: newMap[index] = e;
093: }
094: }
095: }
096:
097: public synchronized void flush() {
098: if (nModified < MODIFIED_BUFFER_SIZE) {
099: IPersistent[] mod = modified;
100: for (int i = nModified; --i >= 0;) {
101: IPersistent obj = mod[i];
102: if (obj.isModified()) {
103: obj.store();
104: }
105: }
106: } else {
107: Entry tab[] = table;
108: flushing = true;
109: for (int i = 0; i < tab.length; i++) {
110: for (Entry e = tab[i]; e != null; e = e.next) {
111: if (e.obj.isModified()) {
112: e.obj.store();
113: }
114: }
115: }
116: flushing = false;
117: if (count >= threshold) {
118: // Rehash the table if the threshold is exceeded
119: rehash();
120: }
121: }
122: nModified = 0;
123: }
124:
125: public synchronized void clear() {
126: Entry tab[] = table;
127: for (int i = 0; i < tab.length; i++) {
128: tab[i] = null;
129: }
130: count = 0;
131: nModified = 0;
132: }
133:
134: public synchronized void invalidate() {
135: for (int i = 0; i < table.length; i++) {
136: for (Entry e = table[i]; e != null; e = e.next) {
137: if (e.obj.isModified()) {
138: e.obj.invalidate();
139: }
140: }
141: table[i] = null;
142: }
143: count = 0;
144: nModified = 0;
145: }
146:
147: public synchronized void setDirty(IPersistent obj) {
148: if (nModified < MODIFIED_BUFFER_SIZE) {
149: modified[nModified++] = obj;
150: }
151: }
152:
153: public void clearDirty(IPersistent obj) {
154: }
155:
156: public int size() {
157: return count;
158: }
159:
160: public void preprocess() {
161: }
162:
163: static class Entry {
164: Entry next;
165: IPersistent obj;
166: int oid;
167:
168: Entry(int oid, IPersistent obj, Entry chain) {
169: next = chain;
170: this.oid = oid;
171: this.obj = obj;
172: }
173: }
174: }
|