test_class.declarator: MAX_FILE_SIZE = 512 * 1024
test_class.modifier: public static final
test_class.original_string: public static final int MAX_FILE_SIZE = 512 * 1024;
test_class.type: int
test_class.var_name: MAX_FILE_SIZE
test_class.declarator: random = new Random()
test_class.modifier: private static final
test_class.original_string: private static final Random random = new Random();
test_class.type: Random
test_class.var_name: random
test_class.declarator: folder = new TemporaryFolder(new File("target"))
test_class.modifier: @Rule
      public
test_class.original_string: @Rule
      public TemporaryFolder folder = new TemporaryFolder(new File("target"));
test_class.type: TemporaryFolder
test_class.var_name: folder
test_class.declarator: tarFiles
test_class.modifier: protected
test_class.original_string: protected TarFiles tarFiles;
test_class.type: TarFiles
test_class.var_name: tarFiles
test_class.file: oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/file/tar/TarFilesTest.java
test_class.identifier: TarFilesTest
test_case.body: @Test
      public void testCleanup() throws Exception {
          UUID a = randomUUID();
          UUID b = randomUUID();
          UUID c = randomUUID();
          UUID d = randomUUID();
          UUID e = randomUUID();
  
          writeSegment(a);
          writeSegment(b);
          writeSegmentWithReferences(c, a, b);
          writeSegment(d);
          writeSegmentWithReferences(e, a, d);
  
          // Traverse graph of segments starting with `e`. Mark as reclaimable
          // every segment that are not traversed. The two segments `b` and `c`
          // will be reclaimed.
  
          CleanupResult result = tarFiles.cleanup(new CleanupContext() {
  
              @Override
              public Collection<UUID> initialReferences() {
                  return singletonList(e);
              }
  
              @Override
              public boolean shouldReclaim(UUID id, GCGeneration generation, boolean referenced) {
                  return !referenced;
              }
  
              @Override
              public boolean shouldFollow(UUID from, UUID to) {
                  return true;
              }
  
          });
  
          assertFalse(result.isInterrupted());
          assertFalse(result.getRemovableFiles().isEmpty());
          assertEquals(new HashSet<>(asList(c, b)), result.getReclaimedSegmentIds());
          assertTrue(result.getReclaimedSize() > 0);
      }
test_case.class_method_signature: TarFilesTest.testCleanup()
test_case.full_signature: @Test public void testCleanup()
test_case.identifier: testCleanup
test_case.invocations: randomUUID randomUUID randomUUID randomUUID randomUUID writeSegment writeSegment writeSegmentWithReferences writeSegment writeSegmentWithReferences cleanup singletonList assertFalse isInterrupted assertFalse isEmpty getRemovableFiles assertEquals asList getReclaimedSegmentIds assertTrue getReclaimedSize
test_case.modifiers: @Test public
test_case.parameters: ()
test_case.return: void
test_case.signature: void testCleanup()
focal_class.declarator: log = LoggerFactory.getLogger(TarFiles.class)
focal_class.modifier: private static final
focal_class.original_string: private static final Logger log = LoggerFactory.getLogger(TarFiles.class);
focal_class.type: Logger
focal_class.var_name: log
focal_class.declarator: FILE_NAME_PATTERN = Pattern.compile("(data)((0|[1-9][0-9]*)[0-9]{4})([a-z])?.tar")
focal_class.modifier: private static final
focal_class.original_string: private static final Pattern FILE_NAME_PATTERN = Pattern.compile("(data)((0|[1-9][0-9]*)[0-9]{4})([a-z])?.tar");
focal_class.type: Pattern
focal_class.var_name: FILE_NAME_PATTERN
focal_class.declarator: maxFileSize
focal_class.modifier: private final
focal_class.original_string: private final long maxFileSize;
focal_class.type: long
focal_class.var_name: maxFileSize
focal_class.declarator: archiveManager
focal_class.modifier: private
focal_class.original_string: private SegmentArchiveManager archiveManager;
focal_class.type: SegmentArchiveManager
focal_class.var_name: archiveManager
focal_class.declarator: lock = new ReentrantReadWriteLock()
focal_class.modifier: private final
focal_class.original_string: private final ReadWriteLock lock = new ReentrantReadWriteLock();
focal_class.type: ReadWriteLock
focal_class.var_name: lock
focal_class.declarator: readers
focal_class.modifier: private
focal_class.original_string: private Node readers;
focal_class.type: Node
focal_class.var_name: readers
focal_class.declarator: writer
focal_class.modifier: private
focal_class.original_string: private TarWriter writer;
focal_class.type: TarWriter
focal_class.var_name: writer
focal_class.declarator: shutdown
focal_class.modifier: private volatile
focal_class.original_string: private volatile boolean shutdown;
focal_class.type: boolean
focal_class.var_name: shutdown
focal_class.declarator: readerCount
focal_class.modifier: private final
focal_class.original_string: private final CounterStats readerCount;
focal_class.type: CounterStats
focal_class.var_name: readerCount
focal_class.declarator: segmentCount
focal_class.modifier: private final
focal_class.original_string: private final CounterStats segmentCount;
focal_class.type: CounterStats
focal_class.var_name: segmentCount
focal_class.file: oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/file/tar/TarFiles.java
focal_class.identifier: TarFiles
focal_class.interfaces: implements Closeable
focal_class.class_method_signature: TarFiles.reverse(Node n)
focal_class.full_signature: private static Node reverse(Node n)
focal_class.identifier: reverse
focal_class.modifiers: private static
focal_class.parameters: (Node n)
focal_class.return: Node
focal_class.signature: Node reverse(Node n)
focal_class.class_method_signature: TarFiles.iterable(final Node head)
focal_class.full_signature: private static Iterable<TarReader> iterable(final Node head)
focal_class.identifier: iterable
focal_class.modifiers: private static
focal_class.parameters: (final Node head)
focal_class.return: Iterable<TarReader>
focal_class.signature: Iterable<TarReader> iterable(final Node head)
focal_class.class_method_signature: TarFiles.collectFiles(SegmentArchiveManager archiveManager)
focal_class.full_signature: private static Map<Integer, Map<Character, String>> collectFiles(SegmentArchiveManager archiveManager)
focal_class.identifier: collectFiles
focal_class.modifiers: private static
focal_class.parameters: (SegmentArchiveManager archiveManager)
focal_class.return: Map<Integer, Map<Character, String>>
focal_class.signature: Map<Integer, Map<Character, String>> collectFiles(SegmentArchiveManager archiveManager)
focal_class.class_method_signature: TarFiles.builder()
focal_class.full_signature: public static Builder builder()
focal_class.identifier: builder
focal_class.modifiers: public static
focal_class.parameters: ()
focal_class.return: Builder
focal_class.signature: Builder builder()
focal_class.class_method_signature: TarFiles.getSegmentCount(TarReader reader)
focal_class.full_signature: private static int getSegmentCount(TarReader reader)
focal_class.identifier: getSegmentCount
focal_class.modifiers: private static
focal_class.parameters: (TarReader reader)
focal_class.return: int
focal_class.signature: int getSegmentCount(TarReader reader)
focal_class.class_method_signature: TarFiles.TarFiles(Builder builder)
focal_class.full_signature: private  TarFiles(Builder builder)
focal_class.identifier: TarFiles
focal_class.modifiers: private
focal_class.parameters: (Builder builder)
focal_class.signature:  TarFiles(Builder builder)
focal_class.class_method_signature: TarFiles.close()
focal_class.full_signature: @Override public void close()
focal_class.identifier: close
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void close()
focal_class.class_method_signature: TarFiles.toString()
focal_class.full_signature: @Override public String toString()
focal_class.identifier: toString
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: String
focal_class.signature: String toString()
focal_class.class_method_signature: TarFiles.size()
focal_class.full_signature: public long size()
focal_class.identifier: size
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: long
focal_class.signature: long size()
focal_class.class_method_signature: TarFiles.getSize(Node head)
focal_class.full_signature: private static int getSize(Node head)
focal_class.identifier: getSize
focal_class.modifiers: private static
focal_class.parameters: (Node head)
focal_class.return: int
focal_class.signature: int getSize(Node head)
focal_class.class_method_signature: TarFiles.readerCount()
focal_class.full_signature: public int readerCount()
focal_class.identifier: readerCount
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: int
focal_class.signature: int readerCount()
focal_class.class_method_signature: TarFiles.segmentCount()
focal_class.full_signature: public int segmentCount()
focal_class.identifier: segmentCount
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: int
focal_class.signature: int segmentCount()
focal_class.class_method_signature: TarFiles.flush()
focal_class.full_signature: public void flush()
focal_class.identifier: flush
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void flush()
focal_class.class_method_signature: TarFiles.containsSegment(long msb, long lsb)
focal_class.full_signature: public boolean containsSegment(long msb, long lsb)
focal_class.identifier: containsSegment
focal_class.modifiers: public
focal_class.parameters: (long msb, long lsb)
focal_class.return: boolean
focal_class.signature: boolean containsSegment(long msb, long lsb)
focal_class.class_method_signature: TarFiles.readSegment(long msb, long lsb)
focal_class.full_signature: public Buffer readSegment(long msb, long lsb)
focal_class.identifier: readSegment
focal_class.modifiers: public
focal_class.parameters: (long msb, long lsb)
focal_class.return: Buffer
focal_class.signature: Buffer readSegment(long msb, long lsb)
focal_class.class_method_signature: TarFiles.writeSegment(UUID id, byte[] buffer, int offset, int length, GCGeneration generation, Set<UUID> references, Set<String> binaryReferences)
focal_class.full_signature: public void writeSegment(UUID id, byte[] buffer, int offset, int length, GCGeneration generation, Set<UUID> references, Set<String> binaryReferences)
focal_class.identifier: writeSegment
focal_class.modifiers: public
focal_class.parameters: (UUID id, byte[] buffer, int offset, int length, GCGeneration generation, Set<UUID> references, Set<String> binaryReferences)
focal_class.return: void
focal_class.signature: void writeSegment(UUID id, byte[] buffer, int offset, int length, GCGeneration generation, Set<UUID> references, Set<String> binaryReferences)
focal_class.class_method_signature: TarFiles.internalNewWriter()
focal_class.full_signature: private void internalNewWriter()
focal_class.identifier: internalNewWriter
focal_class.modifiers: private
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void internalNewWriter()
focal_class.class_method_signature: TarFiles.newWriter()
focal_class.full_signature:  void newWriter()
focal_class.identifier: newWriter
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void newWriter()
focal_class.class_method_signature: TarFiles.cleanup(CleanupContext context)
focal_class.full_signature: public CleanupResult cleanup(CleanupContext context)
focal_class.identifier: cleanup
focal_class.modifiers: public
focal_class.parameters: (CleanupContext context)
focal_class.return: CleanupResult
focal_class.signature: CleanupResult cleanup(CleanupContext context)
focal_class.class_method_signature: TarFiles.getSegmentCount(Node head)
focal_class.full_signature: private static int getSegmentCount(Node head)
focal_class.identifier: getSegmentCount
focal_class.modifiers: private static
focal_class.parameters: (Node head)
focal_class.return: int
focal_class.signature: int getSegmentCount(Node head)
focal_class.class_method_signature: TarFiles.collectBlobReferences(Consumer<String> collector, Predicate<GCGeneration> reclaim)
focal_class.full_signature: public void collectBlobReferences(Consumer<String> collector, Predicate<GCGeneration> reclaim)
focal_class.identifier: collectBlobReferences
focal_class.modifiers: public
focal_class.parameters: (Consumer<String> collector, Predicate<GCGeneration> reclaim)
focal_class.return: void
focal_class.signature: void collectBlobReferences(Consumer<String> collector, Predicate<GCGeneration> reclaim)
focal_class.class_method_signature: TarFiles.getSegmentIds()
focal_class.full_signature: public Iterable<UUID> getSegmentIds()
focal_class.identifier: getSegmentIds
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: Iterable<UUID>
focal_class.signature: Iterable<UUID> getSegmentIds()
focal_class.class_method_signature: TarFiles.getGraph(String fileName)
focal_class.full_signature: public Map<UUID, Set<UUID>> getGraph(String fileName)
focal_class.identifier: getGraph
focal_class.modifiers: public
focal_class.parameters: (String fileName)
focal_class.return: Map<UUID, Set<UUID>>
focal_class.signature: Map<UUID, Set<UUID>> getGraph(String fileName)
focal_class.class_method_signature: TarFiles.getIndices()
focal_class.full_signature: public Map<String, Set<UUID>> getIndices()
focal_class.identifier: getIndices
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: Map<String, Set<UUID>>
focal_class.signature: Map<String, Set<UUID>> getIndices()
focal_class.class_method_signature: TarFiles.createFileReaper()
focal_class.full_signature: public FileReaper createFileReaper()
focal_class.identifier: createFileReaper
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: FileReaper
focal_class.signature: FileReaper createFileReaper()
focal_method.body: public CleanupResult cleanup(CleanupContext context) throws IOException {
          CleanupResult result = new CleanupResult();
          result.removableFiles = new ArrayList<>();
          result.reclaimedSegmentIds = new HashSet<>();
  
          Set<UUID> references;
          Node head;
  
          lock.writeLock().lock();
          lock.readLock().lock();
          try {
              try {
                  internalNewWriter();
              } finally {
                  lock.writeLock().unlock();
              }
              head = readers;
              references = new HashSet<>(context.initialReferences());
          } finally {
              lock.readLock().unlock();
          }
  
          Map<TarReader, TarReader> cleaned = new LinkedHashMap<>();
  
          for (TarReader reader : iterable(head)) {
              cleaned.put(reader, reader);
              result.reclaimedSize += reader.size();
          }
  
          Set<UUID> reclaim = newHashSet();
  
          for (TarReader reader : cleaned.keySet()) {
              if (shutdown) {
                  result.interrupted = true;
                  return result;
              }
              reader.mark(references, reclaim, context);
          }
  
          for (TarReader reader : cleaned.keySet()) {
              if (shutdown) {
                  result.interrupted = true;
                  return result;
              }
              cleaned.put(reader, reader.sweep(reclaim, result.reclaimedSegmentIds));
          }
  
          Node closeables;
          long reclaimed;
  
          Node swept;
          while (true) {
              closeables = null;
              reclaimed = 0;
  
              swept = null;
  
              // The following loops creates a modified version of `readers` and
              // saves it into `swept`. Some TAR readers in `readers` have been
              // swept by the previous code and must be replaced with a slimmer
              // TAR reader with the same index but a higher generation.
  
              for (TarReader reader : iterable(head)) {
                  if (cleaned.containsKey(reader)) {
  
                      // We distinguish three cases. First, the original TAR
                      // reader is unmodified. This happens with no content or not
                      // enough content could be swept from the original TAR
                      // reader. Second, some content could be swept from the
                      // original TAR reader and a new TAR reader with the same
                      // index and a higher generation was created. Third, all the
                      // content from the original TAR reader could be swept.
  
                      TarReader cleanedReader = cleaned.get(reader);
                      if (cleanedReader != null) {
  
                          // We are either in the first or in the second case.
                          // Save the TAR reader (either the original or the one
                          // with a higher generation) in the resulting linked list.
  
                          swept = new Node(cleanedReader, swept);
                          reclaimed += cleanedReader.size();
                      }
  
                      if (cleanedReader != reader) {
  
                          // We are either in the second or third case. Save the
                          // original TAR reader in a list of TAR readers that
                          // will be closed at the end of this methods.
  
                          closeables = new Node(reader, closeables);
                      }
                  } else {
  
                      // This reader was not involved in the mark-and-sweep. This
                      // might happen in iterations of this loop successive to the
                      // first, when we re-read `readers` and recompute `swept`
                      // all over again.
  
                      swept = new Node(reader, swept);
                  }
              }
  
              // `swept` is in the reverse order because we prepended new nodes
              // to it. We have to reverse it before we save it into `readers`.
  
              swept = reverse(swept);
  
              // Following is a compare-and-set operation. We based the
              // computation of `swept` of a specific value of `readers`. If
              // `readers` is still the same as the one we started with, we just
              // update `readers` and exit from the loop. Otherwise, we read the
              // value of `readers` and recompute `swept` based on this value.
  
              lock.writeLock().lock();
              try {
                  if (readers == head) {
                      readers = swept;
                      break;
                  } else {
                      head = readers;
                  }
              } finally {
                  lock.writeLock().unlock();
              }
          }
          readerCount.dec(getSize(head) - getSize(swept));
          segmentCount.dec(getSegmentCount(head) - getSegmentCount(swept));
  
          result.reclaimedSize -= reclaimed;
  
          for (TarReader closeable : iterable(closeables)) {
              try {
                  closeable.close();
              } catch (IOException e) {
                  log.warn("Unable to close swept TAR reader", e);
              }
              result.removableFiles.add(closeable.getFileName());
          }
  
          return result;
      }
focal_method.class_method_signature: TarFiles.cleanup(CleanupContext context)
focal_method.full_signature: public CleanupResult cleanup(CleanupContext context)
focal_method.identifier: cleanup
focal_method.invocations: lock writeLock lock readLock internalNewWriter unlock writeLock initialReferences unlock readLock iterable put size newHashSet keySet mark keySet put sweep iterable containsKey get size reverse lock writeLock unlock writeLock dec getSize getSize dec getSegmentCount getSegmentCount iterable close warn add getFileName
focal_method.modifiers: public
focal_method.parameters: (CleanupContext context)
focal_method.return: CleanupResult
focal_method.signature: CleanupResult cleanup(CleanupContext context)