📄 jdbmspace.java
字号:
* @param key Entry's key * @param timeout millis to wait * @return value or null */ public synchronized Object rd (Object key, long timeout) { Object obj; long now = System.currentTimeMillis(); long end = now + timeout; while ((obj = rdp (key)) == null && ((now = System.currentTimeMillis()) < end)) { try { this.wait (end - now); } catch (InterruptedException e) { } } return obj; } /** * @return aproximately queue size */ public long size (Object key) { try { Head head = (Head) htree.get (key); return (head != null) ? head.count : 0; } catch (IOException e) { throw new SpaceError (e); } } private void purge (Object key) throws IOException { Head head = (Head) htree.get (key); Ref ref, previousRef = null; if (head != null) { for (long recid = head.first; recid >= 0; ) { Ref r = (Ref) recman.fetch (recid, refSerializer); if (r.isExpired ()) { recman.delete (r.recid); recman.delete (recid); head.count--; if (previousRef == null) { head.first = r.next; } else { previousRef.next = r.next; recman.update ( head.last, previousRef, refSerializer ); } } else { previousRef = r; head.last = recid; } recid = r.next; } if (head.first == -1) { htree.remove (key); } else { htree.put (key, head); } } } public void run () { gc(); } /** * garbage collector. * removes expired entries */ public void gc () { final String GCKEY = "GC$" + Integer.toString (hashCode()); final long TIMEOUT = 24 * 3600 * 1000; Object obj; try { synchronized (this) { // avoid concurrent gc if (rdp (GCKEY) != null) return; out (GCKEY, new Boolean (true), TIMEOUT); } FastIterator iter = htree.keys (); try { while ( (obj = iter.next()) != null) { out (GCKEY, obj, TIMEOUT); Thread.yield (); } } catch (ConcurrentModificationException e) { // ignore, we may have better luck on next try } while ( (obj = inp (GCKEY)) != null) { synchronized (this) { purge (obj); recman.commit (); } Thread.yield (); } } catch (IOException e) { throw new SpaceError (e); } } public String getKeys () { StringBuffer sb = new StringBuffer(); try { FastIterator iter = htree.keys (); Object obj; while ( (obj = iter.next()) != null) { if (sb.length() > 0) sb.append (' '); sb.append (obj.toString()); } } catch (IOException e) { throw new SpaceError (e); } return sb.toString(); } private Ref getFirst (Object key, boolean remove) throws IOException { Head head = (Head) htree.get (key); Ref ref = null; if (head != null) { long recid; for (recid = head.first; recid >= 0; ) { Ref r = (Ref) recman.fetch (recid, refSerializer); if (r.isExpired ()) { recman.delete (r.recid); recman.delete (recid); recid = r.next; head.count--; } else { ref = r; if (remove) { recman.delete (recid); recid = ref.next; head.count--; } break; } } if (head.first != recid) { if (recid < 0) htree.remove (key); else { head.first = recid; htree.put (key, head); } } } return ref; } private void unlinkRef (long recid, Head head, Ref r, Ref previousRef, long previousRecId) throws IOException { recman.delete (r.recid); recman.delete (recid); head.count--; if (previousRef == null) head.first = r.next; else { previousRef.next = r.next; recman.update ( previousRecId, previousRef, refSerializer ); } } private Object getObject (Template tmpl, boolean remove) throws IOException { Object obj = null; Object key = tmpl.getKey(); Head head = (Head) htree.get (key); Ref ref, previousRef = null; long previousRecId = 0; int unlinkCount = 0; if (head != null) { for (long recid = head.first; recid >= 0; ) { Ref r = (Ref) recman.fetch (recid, refSerializer); if (r.isExpired ()) { unlinkRef (recid, head, r, previousRef, previousRecId); unlinkCount++; } else { Object o = recman.fetch (r.recid); if (o != null) { if (tmpl.equals (o)) { obj = o; if (remove) { unlinkRef ( recid, head, r, previousRef, previousRecId ); unlinkCount++; } break; } } previousRef = r; previousRecId = recid; } recid = r.next; } if (unlinkCount > 0) { if (head.first == -1) { htree.remove (key); } else { htree.put (key, head); } } } return obj; } static class Head implements Externalizable { public long first; public long last; public long count; static final long serialVersionUID = 2L; public Head () { super (); first = -1; last = -1; } public void writeExternal (ObjectOutput out) throws IOException { out.writeLong (first); out.writeLong (last); out.writeLong (count); } public void readExternal (ObjectInput in) throws IOException { first = in.readLong (); last = in.readLong (); count = in.readLong (); } public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()) + ":[first=" + first + ",last=" + last + "]"; } } static class Ref implements Serializer { long recid; long expires; long next; static final long serialVersionUID = 1L; public Ref () { super(); } public Ref (long recid, long expires) { super(); this.recid = recid; this.expires = expires; this.next = -1; } public boolean isExpired () { return expires < System.currentTimeMillis (); } public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()) + ":[recid=" + recid + ",next=" + next + ",expired=" + isExpired () + "]"; } public byte[] serialize (Object obj) throws IOException { Ref d = (Ref) obj; byte[] buf = new byte [24]; putLong (buf, 0, d.recid); putLong (buf, 8, d.next); putLong (buf,16, d.expires); return buf; } public Object deserialize (byte[] serialized) throws IOException { Ref d = new Ref (); d.recid = getLong (serialized, 0); d.next = getLong (serialized, 8); d.expires = getLong (serialized, 16); return d; } } static void putLong (byte[] b, int off, long val) { b[off+7] = (byte) (val >>> 0); b[off+6] = (byte) (val >>> 8); b[off+5] = (byte) (val >>> 16); b[off+4] = (byte) (val >>> 24); b[off+3] = (byte) (val >>> 32); b[off+2] = (byte) (val >>> 40); b[off+1] = (byte) (val >>> 48); b[off+0] = (byte) (val >>> 56); } static long getLong (byte[] b, int off) { return ((b[off+7] & 0xFFL) << 0) + ((b[off+6] & 0xFFL) << 8) + ((b[off+5] & 0xFFL) << 16) + ((b[off+4] & 0xFFL) << 24) + ((b[off+3] & 0xFFL) << 32) + ((b[off+2] & 0xFFL) << 40) + ((b[off+1] & 0xFFL) << 48) + ((b[off+0] & 0xFFL) << 56); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -