示例#1
0
  private MarshalledEntry<K, V> _load(Object key, boolean loadValue, boolean loadMetadata) {
    final FileEntry fe;
    resizeLock.readLock().lock();
    try {
      synchronized (entries) {
        // lookup FileEntry of the key
        fe = entries.get(key);
        if (fe == null) return null;

        // Entries are removed due to expiration from {@link SingleFileStore#purge}
        if (fe.isExpired(timeService.wallClockTime())) {
          return null;
        } else {
          // lock entry for reading before releasing entries monitor
          fe.lock();
        }
      }
    } finally {
      resizeLock.readLock().unlock();
    }

    org.infinispan.commons.io.ByteBuffer valueBb = null;
    org.infinispan.commons.io.ByteBuffer metadataBb = null;

    // If we only require the key, then no need to read disk
    if (!loadValue && !loadMetadata) {
      try {
        return ctx.getMarshalledEntryFactory().newMarshalledEntry(key, valueBb, metadataBb);
      } finally {
        fe.unlock();
      }
    }

    final byte[] data;
    try {
      // load serialized data from disk
      data = new byte[fe.keyLen + fe.dataLen + (loadMetadata ? fe.metadataLen : 0)];
      // The entry lock will prevent clear() from truncating the file at this point
      channel.read(ByteBuffer.wrap(data), fe.offset + KEY_POS);
    } catch (Exception e) {
      throw new PersistenceException(e);
    } finally {
      // No need to keep the lock for deserialization.
      // FileEntry is immutable, so its members can't be changed by another thread.
      fe.unlock();
    }

    if (trace) log.tracef("Read entry %s at %d:%d", key, fe.offset, fe.actualSize());
    ByteBufferFactory factory = ctx.getByteBufferFactory();
    org.infinispan.commons.io.ByteBuffer keyBb = factory.newByteBuffer(data, 0, fe.keyLen);
    if (loadValue) {
      valueBb = factory.newByteBuffer(data, fe.keyLen, fe.dataLen);
    }
    if (loadMetadata && fe.metadataLen > 0) {
      metadataBb = factory.newByteBuffer(data, fe.keyLen + fe.dataLen, fe.metadataLen);
    }
    return ctx.getMarshalledEntryFactory().newMarshalledEntry(keyBb, valueBb, metadataBb);
  }
示例#2
0
  @Override
  public void purge(Executor threadPool, final PurgeListener task) {
    long now = timeService.wallClockTime();
    List<KeyValuePair<Object, FileEntry>> entriesToPurge =
        new ArrayList<KeyValuePair<Object, FileEntry>>();
    synchronized (entries) {
      for (Iterator<Map.Entry<K, FileEntry>> it = entries.entrySet().iterator(); it.hasNext(); ) {
        Map.Entry<K, FileEntry> next = it.next();
        FileEntry fe = next.getValue();
        if (fe.isExpired(now)) {
          it.remove();
          entriesToPurge.add(new KeyValuePair<Object, FileEntry>(next.getKey(), fe));
        }
      }
    }

    resizeLock.readLock().lock();
    try {
      for (Iterator<KeyValuePair<Object, FileEntry>> it = entriesToPurge.iterator();
          it.hasNext(); ) {
        KeyValuePair<Object, FileEntry> next = it.next();
        FileEntry fe = next.getValue();
        if (fe.isExpired(now)) {
          it.remove();
          try {
            free(fe);
          } catch (Exception e) {
            throw new PersistenceException(e);
          }
          if (task != null) task.entryPurged(next.getKey());
        }
      }

      // Disk space optimizations
      synchronized (freeList) {
        processFreeEntries();
      }
    } finally {
      resizeLock.readLock().unlock();
    }
  }
示例#3
0
 /**
  * The base class implementation calls {@link #load(Object)} for this, we can do better because we
  * keep all keys in memory.
  */
 @Override
 public boolean contains(Object key) {
   FileEntry entry = entries.get(key);
   return entry != null && !entry.isExpired(timeService.wallClockTime());
 }