📄 cm.java
字号:
LOG.debug("Removing expired record :" + fn); } try { remove(dn, fn); } catch (IOException e) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Failed to remove record", e); } } } return expiration; } catch (DBException de) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("failed to get " + dn + "/" + fn, de); } return -1; } } /** * Figures out expiration * * @param record record * @return expiration in ms */ private static long calcExpiration(Record record) { if (record == null) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Record is null returning expiration of -1"); } return -1; } Long exp = (Long) record.getMetaData(Record.EXPIRATION); Long life = (Long) record.getMetaData(Record.LIFETIME); long expiresin = life.longValue() - System.currentTimeMillis(); if (expiresin <= 0) { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Record expired" + " lifetime : " + life.longValue() + " expiration: " + exp.longValue() + " expires in: " + expiresin); LOG.debug("Record expires on :" + new Date(life.longValue())); } return -1; } else { if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Record lifetime: " + life.longValue() + " expiration: " + exp.longValue() + " expires in: " + expiresin); LOG.debug("Record expires on :" + new Date(life.longValue())); } return Math.min(expiresin, exp.longValue()); } } /** * Returns the inputStream of a specified file, in a specified dir * * @param dn directory name * @param fn file name * @return The inputStream value * @exception IOException if an I/O error occurs */ public InputStream getInputStream(String dn, String fn) throws IOException { Key key = new Key(dn + "/" + fn); try { Record record = cacheDB.readRecord(key); if (record == null) { return null; } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Restored record for " + key); } Value val = record.getValue(); if (val != null) { return val.getInputStream(); } else { return null; } } catch (DBException de) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Failed to restore record for " + key, de); } IOException failure = new IOException("Failed to restore record for " + key); failure.initCause(de); throw failure; } } /** * Remove a file * * @param dn directory name * @param fn file name * @throws IOException if an I/O error occurs */ public synchronized void remove(String dn, String fn) throws IOException { try { if (fn == null) { return; } Key key = new Key(dn + "/" + fn); Record record = cacheDB.readRecord(key); long removePos = cacheDB.findValue(key); cacheDB.deleteRecord(key); if (record != null) { try { InputStream is = record.getValue().getInputStream(); Advertisement adv = AdvertisementFactory.newAdvertisement(MimeMediaType.XMLUTF8, is); Map indexables = getIndexfields(adv.getIndexFields(), (StructuredDocument) adv.getDocument(MimeMediaType.XMLUTF8)); indexer.removeFromIndex(addKey(dn, indexables), removePos); // add it to deltas to expire it in srdi addDelta(dn, indexables, 0); if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("removed " + record); } } catch (Exception e) { // bad bits we are done if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("failed to remove " + dn + "/" + fn, e); } } } } catch (DBException de) { // entry does not exist if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("failed to remove " + dn + "/" + fn); } } } /** * Restore a saved StructuredDocument. * * @param dn directory name * @param fn file name * @return StructuredDocument containing the file * @throws IOException if an I/O error occurs * was not possible. */ public StructuredDocument restore(String dn, String fn) throws IOException { InputStream is = getInputStream(dn, fn); return StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, is); } /** * Restore an advetisement into a byte array. * * @param dn directory name * @param fn file name * @return byte [] containing the file * @throws IOException if an I/O error occurs */ public synchronized byte[] restoreBytes(String dn, String fn) throws IOException { try { Key key = new Key(dn + "/" + fn); Record record = cacheDB.readRecord(key); if (record == null) { return null; } if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("restored " + record); } Value val = record.getValue(); if (val != null) { return val.getData(); } else { return null; } } catch (DBException de) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("failed to restore " + dn + "/" + fn, de); } IOException failure = new IOException("failed to restore " + dn + "/" + fn); failure.initCause(de); throw failure; } } /** * Stores a StructuredDocument in specified dir, and file name * * @param dn directory name * @param fn file name * @param adv Advertisement to store * @exception IOException if an I/O error occurs */ public void save(String dn, String fn, Advertisement adv) throws IOException { save(dn, fn, adv, DiscoveryService.INFINITE_LIFETIME, DiscoveryService.NO_EXPIRATION); } /** * Stores a StructuredDocument in specified dir, and file name, and * associated doc timeouts * * @param dn directory name * @param fn file name * @param adv Advertisement to save * @param lifetime Document (local) lifetime in relative ms * @param expiration Document (global) expiration time in relative ms * @exception IOException Thrown if there is a problem saving the document. */ public synchronized void save(String dn, String fn, Advertisement adv, long lifetime, long expiration) throws IOException { try { if (expiration < 0 || lifetime <= 0) { throw new IllegalArgumentException("Bad expiration or lifetime."); } StructuredDocument doc; try { doc = (StructuredDocument) adv.getDocument(MimeMediaType.XMLUTF8); } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } else { IOException failure = new IOException("Advertisement couldn't be saved"); failure.initCause(e); throw failure; } } Key key = new Key(dn + "/" + fn); // save the new version ByteArrayOutputStream baos = new ByteArrayOutputStream(); doc.sendToStream(baos); baos.close(); Value value = new Value(baos.toByteArray()); baos = null; Long oldLife = null; Record record = cacheDB.readRecord(key); if (record != null) { // grab the old lifetime oldLife = (Long) record.getMetaData(Record.LIFETIME); } long absoluteLifetime = TimeUtils.toAbsoluteTimeMillis(lifetime); if (oldLife != null) { if (absoluteLifetime < oldLife.longValue()) { // make sure we don't override the original value if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug( "Overriding attempt to decrease adv lifetime from : " + new Date(oldLife.longValue()) + " to :" + new Date(absoluteLifetime)); } absoluteLifetime = oldLife.longValue(); } } // make sure expiration does not exceed lifetime if (expiration > lifetime) { expiration = lifetime; } long pos = cacheDB.writeRecord(key, value, absoluteLifetime, expiration); Map indexables = getIndexfields(adv.getIndexFields(), doc); Map keyedIdx = addKey(dn, indexables); if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug("Indexing " + keyedIdx + " at " + pos); } indexer.addToIndex(keyedIdx, pos); if (LOG.isEnabledFor(Level.DEBUG)) { // too noisy // LOG.debug("Wrote " + key + " = " + value); LOG.debug("Stored " + indexables + " at " + pos); } if( expiration > 0 ) { // Update for SRDI with our caches lifetime only if we are prepared to share the advertisement with others. addDelta(dn, indexables, TimeUtils.toRelativeTimeMillis(absoluteLifetime)); } } catch (DBException de) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Failed to write " + dn + "/" + fn + " " + lifetime + " " + expiration, de); } IOException failure = new IOException("Failed to write " + dn + "/" + fn + " " + lifetime + " " + expiration); failure.initCause(de); throw failure; } } /** * Store some bytes in specified dir, and file name, and * associated doc timeouts * * @param dn directory name * @param fn file name * @param data byte array to save * @param lifetime Document (local) lifetime in relative ms * @param expiration Document (global) expiration time in relative ms * @exception IOException Thrown if there is a problem saving the document. */ public synchronized void save(String dn, String fn, byte[] data, long lifetime, long expiration) throws IOException { try { if (expiration < 0 || lifetime <= 0) { throw new IllegalArgumentException("Bad expiration or lifetime."); } Key key = new Key(dn + "/" + fn); Value value = new Value(data); Long oldLife = null; Record record = cacheDB.readRecord(key); if (record != null) { // grab the old lifetime oldLife = (Long) record.getMetaData(Record.LIFETIME); } // save the new version long absoluteLifetime = TimeUtils.toAbsoluteTimeMillis(lifetime); if (oldLife != null) { if (absoluteLifetime < oldLife.longValue()) { // make sure we don't override the original value if (LOG.isEnabledFor(Level.DEBUG)) { LOG.debug( "Overriding attempt to decrease adv lifetime from : " + new Date(oldLife.longValue()) + " to :" + new Date(absoluteLifetime)); } absoluteLifetime = oldLife.longValue(); } } // make sure expiration does not exceed lifetime if (expiration > lifetime) { expiration = lifetime; } cacheDB.writeRecord(key, value, absoluteLifetime, expiration); } catch (DBException de) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Failed to write " + dn + "/" + fn + " " + lifetime + " " + expiration, de); } IOException failure = new IOException("Failed to write " + dn + "/" + fn + " " + lifetime + " " + expiration); failure.initCause(de); throw failure; } } private static Map getIndexfields(String[] fields, StructuredDocument doc) { Map map = new HashMap(); if (doc == null) { if (LOG.isEnabledFor(Level.WARN)) { LOG.warn("Null document"); } return map; } if (fields == null) { return map; } for (int i = 0; i < fields.length; i++) { Enumeration en = doc.getChildren(fields[i]); while (en.hasMoreElements()) { String val = (String) ((Element) en.nextElement()).getValue(); if (val != null) { map.put(fields[i], val.toUpperCase()); } } } return map; } /* adds a primary index 'dn' to indexables */ private static Map addKey(String dn, Map map) { if (map == null) { return null; } Map tmp = new HashMap(); if (map.size() > 0) { Iterator it = map.keySet().iterator(); while (it != null && it.hasNext()) { String name = (String) it.next(); tmp.put(dn + name, map.get(name)); } } return tmp; } private static final class EntriesCallback implements BTreeCallback { private BTreeFiler cacheDB = null; private int threshold; private Vector results; private String key; EntriesCallback(BTreeFiler cacheDB, Vector results, String key, int threshold) { this.cacheDB = cacheDB; this.results = results; this.key = key; this.threshold = threshold; } /** * {@inheritDoc} */ public boolean indexInfo(Value val, long pos) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -