@Override
   public boolean acquireReadLock(String filename) {
      FileReadLockKey readLockKey = new FileReadLockKey(indexName, filename, affinitySegmentId);
      Integer lockValue = locksCache.get(readLockKey);
      boolean done = false;
      while (done == false) {
         if (lockValue != null) {
            int refCount = lockValue.intValue();
            if (refCount == 0) {
               // too late: in case refCount==0 the delete is being performed
               return false;
            }
            Integer newValue = Integer.valueOf(refCount + 1);
            done = locksCache.replace(readLockKey, lockValue, newValue);
            if ( ! done) {
               lockValue = locksCache.get(readLockKey);
            }
         } else {
            // readLocks are not stored, so if there's no value assume it's ==1, which means
            // existing file, not deleted, nobody else owning a read lock. but check for ambiguity
            lockValue = locksCache.putIfAbsent(readLockKey, 2);
            done = (null == lockValue);
            if (done) {
               // have to check now that the fileKey still exists to prevent the race condition of
               // T1 fileKey exists - T2 delete file and remove readlock - T1 putIfAbsent(readlock, 2)
               final FileCacheKey fileKey = new FileCacheKey(indexName, filename, affinitySegmentId);
               if (metadataCache.get(fileKey) == null) {
                  locksCache.withFlags(Flag.IGNORE_RETURN_VALUES).removeAsync(readLockKey);
                  return false;
               }
            }
         }
      }
      return true;
   }
@ Override public boolean acquireReadLock ( String filename ) { FileReadLockKey readLockKey = new FileReadLockKey ( indexName , filename , affinitySegmentId ) ; Integer lockValue = locksCache . get ( readLockKey ) ; boolean done = false ; while ( done == false ) { if ( lockValue != null ) { int refCount = lockValue . intValue ( ) ; if ( refCount == 0 ) { return false ; } Integer newValue = Integer . valueOf ( refCount + 1 ) ; done = locksCache . replace ( readLockKey , lockValue , newValue ) ; if ( ! done ) { lockValue = locksCache . get ( readLockKey ) ; } } else { lockValue = locksCache . putIfAbsent ( readLockKey , 2 ) ; done = ( null == lockValue ) ; if ( done ) { final FileCacheKey fileKey = new FileCacheKey ( indexName , filename , affinitySegmentId ) ; if ( metadataCache . get ( fileKey ) == null ) { locksCache . withFlags ( Flag . IGNORE_RETURN_VALUES ) . removeAsync ( readLockKey ) ; return false ; } } } } return true ; }
Acquires a readlock on all chunks for this file, to make sure chunks are not deleted while
iterating on the group. This is needed to avoid an eager lock on all elements.

If no value is found in the cache, a disambiguation procedure is needed: not value
might mean both "existing, no readlocks, no deletions in progress", but also "not existent file".
The first possibility is coded as no value to avoid storing readlocks in a permanent store,
which would unnecessarily slow down and provide unwanted long term storage of the lock;
so the value is treated as one if not found, but obviously it's also not found for non-existent
or concurrently deleted files.

@param filename the name of the "file" for which a readlock is requested

@see #deleteOrReleaseReadLock(String)