001/* 002 * (C) Copyright 2015 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl-2.1.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo 016 */ 017 018package org.nuxeo.ecm.blob; 019 020import java.util.HashSet; 021import java.util.Set; 022 023import org.nuxeo.ecm.core.blob.binary.BinaryGarbageCollector; 024import org.nuxeo.ecm.core.blob.binary.BinaryManagerStatus; 025import org.nuxeo.ecm.core.blob.binary.CachingBinaryManager; 026 027/** 028 * @author <a href="mailto:ak@nuxeo.com">Arnaud Kervern</a> 029 * @since 7.10 030 */ 031public abstract class AbstractBinaryGarbageCollector<T extends CachingBinaryManager> implements BinaryGarbageCollector { 032 033 protected T binaryManager; 034 035 protected BinaryManagerStatus status; 036 037 protected volatile long startTime; 038 039 protected Set<String> marked; 040 041 protected AbstractBinaryGarbageCollector(T binaryManager) { 042 this.binaryManager = binaryManager; 043 } 044 045 @Override 046 public void start() { 047 if (startTime != 0) { 048 throw new RuntimeException("Already started"); 049 } 050 startTime = System.currentTimeMillis(); 051 status = new BinaryManagerStatus(); 052 marked = new HashSet<>(); 053 054 // XXX : we should be able to do better 055 // and only remove the cache entry that will be removed from S3 056 binaryManager.fileCache.clear(); 057 } 058 059 @Override 060 public void stop(boolean delete) { 061 if (startTime == 0) { 062 throw new RuntimeException("Not started"); 063 } 064 try { 065 Set<String> unmarked = getUnmarkedBlobs(); 066 marked = null; 067 068 if (delete) { 069 binaryManager.removeBinaries(unmarked); 070 } 071 } finally { 072 status.gcDuration = System.currentTimeMillis() - startTime; 073 startTime = 0; 074 } 075 } 076 077 public abstract Set<String> getUnmarkedBlobs(); 078 079 @Override 080 public void mark(String digest) { 081 marked.add(digest); 082 } 083 084 @Override 085 public BinaryManagerStatus getStatus() { 086 return status; 087 } 088 089 @Override 090 public boolean isInProgress() { 091 // volatile as this is designed to be called from another thread 092 return startTime != 0; 093 } 094}