SerialBitmapReferenceCounter.java revision 9b2c9802d9eb0fb9aaa25388ad064a41b95186af
1cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Juddpackage com.bumptech.photos.resize;
2cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
3cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Juddimport android.graphics.Bitmap;
49b2c9802d9eb0fb9aaa25388ad064a41b95186afSam Juddimport com.bumptech.photos.resize.bitmap_recycle.BitmapPool;
5cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
6cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Juddimport java.util.Map;
72a2882e26b572d6d69939ac553cd840059caee3aSam Juddimport java.util.concurrent.ConcurrentHashMap;
82a2882e26b572d6d69939ac553cd840059caee3aSam Juddimport java.util.concurrent.ConcurrentLinkedQueue;
9cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
10cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd/**
11cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd * Created with IntelliJ IDEA.
12cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd * User: sam
13cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd * Date: 6/4/13
14cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd * Time: 9:54 AM
15cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd * To change this template use File | Settings | File Templates.
16cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd */
17cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Juddpublic class BitmapTracker {
18cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
192a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private static class InnerTrackerPool {
202a2882e26b572d6d69939ac553cd840059caee3aSam Judd        private ConcurrentLinkedQueue<InnerTracker> pool = new ConcurrentLinkedQueue<InnerTracker>();
21cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
222a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public InnerTracker get() {
232a2882e26b572d6d69939ac553cd840059caee3aSam Judd            InnerTracker result = pool.poll();
242a2882e26b572d6d69939ac553cd840059caee3aSam Judd            if (result == null) {
252a2882e26b572d6d69939ac553cd840059caee3aSam Judd                result = new InnerTracker();
262a2882e26b572d6d69939ac553cd840059caee3aSam Judd            }
27cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
282a2882e26b572d6d69939ac553cd840059caee3aSam Judd            return result;
29cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
30cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
312a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public void release(InnerTracker innerTracker) {
322a2882e26b572d6d69939ac553cd840059caee3aSam Judd            pool.offer(innerTracker);
33cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
34cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd    }
35cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
362a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private static class InnerTracker {
372a2882e26b572d6d69939ac553cd840059caee3aSam Judd        private volatile int refs = 0;
382a2882e26b572d6d69939ac553cd840059caee3aSam Judd        private volatile boolean pending = false;
39cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
402a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public void acquire() {
412a2882e26b572d6d69939ac553cd840059caee3aSam Judd            pending = false;
422a2882e26b572d6d69939ac553cd840059caee3aSam Judd            synchronized (this) {
432a2882e26b572d6d69939ac553cd840059caee3aSam Judd                refs++;
44cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd            }
45cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
46cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
472a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public boolean release() {
482a2882e26b572d6d69939ac553cd840059caee3aSam Judd            synchronized (this) {
492a2882e26b572d6d69939ac553cd840059caee3aSam Judd                refs--;
50cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd            }
51cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
522a2882e26b572d6d69939ac553cd840059caee3aSam Judd            return refs == 0 && !pending;
532a2882e26b572d6d69939ac553cd840059caee3aSam Judd        }
54cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
552a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public boolean reject() {
562a2882e26b572d6d69939ac553cd840059caee3aSam Judd            pending = false;
572a2882e26b572d6d69939ac553cd840059caee3aSam Judd            return refs == 0;
582a2882e26b572d6d69939ac553cd840059caee3aSam Judd        }
59cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
602a2882e26b572d6d69939ac553cd840059caee3aSam Judd        public void markPending() {
612a2882e26b572d6d69939ac553cd840059caee3aSam Judd            pending = true;
62cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
632a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
64cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
652a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private final Map<Integer, InnerTracker> counter;
669b2c9802d9eb0fb9aaa25388ad064a41b95186afSam Judd    private final BitmapPool target;
672a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private final InnerTrackerPool pool = new InnerTrackerPool();
68cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
699b2c9802d9eb0fb9aaa25388ad064a41b95186afSam Judd    public BitmapTracker(BitmapPool target, int bitmapsPerSize) {
702a2882e26b572d6d69939ac553cd840059caee3aSam Judd        this.target = target;
712a2882e26b572d6d69939ac553cd840059caee3aSam Judd        counter = new ConcurrentHashMap<Integer, InnerTracker>(bitmapsPerSize * 6, 0.75f, 4);
722a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
732a2882e26b572d6d69939ac553cd840059caee3aSam Judd
742a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void initBitmap(Bitmap toInit) {
752a2882e26b572d6d69939ac553cd840059caee3aSam Judd        counter.put(toInit.hashCode(), pool.get());
762a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
772a2882e26b572d6d69939ac553cd840059caee3aSam Judd
782a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void acquireBitmap(Bitmap bitmap) {
792a2882e26b572d6d69939ac553cd840059caee3aSam Judd        get(bitmap).acquire();
802a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
81cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
822a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void releaseBitmap(Bitmap bitmap) {
832a2882e26b572d6d69939ac553cd840059caee3aSam Judd        final InnerTracker tracker = get(bitmap);
842a2882e26b572d6d69939ac553cd840059caee3aSam Judd        if (tracker.release()) {
852a2882e26b572d6d69939ac553cd840059caee3aSam Judd            recycle(tracker, bitmap);
86cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
872a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
88cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
892a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void rejectBitmap(Bitmap bitmap) {
902a2882e26b572d6d69939ac553cd840059caee3aSam Judd        final InnerTracker tracker = get(bitmap);
912a2882e26b572d6d69939ac553cd840059caee3aSam Judd        if (tracker.reject()) {
922a2882e26b572d6d69939ac553cd840059caee3aSam Judd            recycle(tracker, bitmap);
93cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd        }
942a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
952a2882e26b572d6d69939ac553cd840059caee3aSam Judd
962a2882e26b572d6d69939ac553cd840059caee3aSam Judd    public void markPending(Bitmap bitmap) {
972a2882e26b572d6d69939ac553cd840059caee3aSam Judd        get(bitmap).markPending();
982a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
992a2882e26b572d6d69939ac553cd840059caee3aSam Judd
1002a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private InnerTracker get(Bitmap bitmap) {
1012a2882e26b572d6d69939ac553cd840059caee3aSam Judd        return counter.get(bitmap.hashCode());
1022a2882e26b572d6d69939ac553cd840059caee3aSam Judd    }
103cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd
1042a2882e26b572d6d69939ac553cd840059caee3aSam Judd    private void recycle(InnerTracker tracker, Bitmap bitmap) {
1052a2882e26b572d6d69939ac553cd840059caee3aSam Judd        counter.remove(bitmap.hashCode());
1062a2882e26b572d6d69939ac553cd840059caee3aSam Judd        pool.release(tracker);
1072a2882e26b572d6d69939ac553cd840059caee3aSam Judd        target.put(bitmap);
108cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd    }
109cdd5d2d1ccd23f74c8a42887d409ddfe150c2201Sam Judd}
110