mobile/android/base/favicons/cache/FaviconCacheElement.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/favicons/cache/FaviconCacheElement.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,115 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +package org.mozilla.gecko.favicons.cache;
     1.9 +
    1.10 +import android.graphics.Bitmap;
    1.11 +
    1.12 +/**
    1.13 + * Objects stored in the Favicon cache - allow for the bitmap to be tagged to indicate if it has
    1.14 + * been scaled. Unscaled bitmaps are not included in the scaled-bitmap cache's size calculation.
    1.15 + */
    1.16 +public class FaviconCacheElement implements Comparable<FaviconCacheElement> {
    1.17 +    // Was this Favicon computed via scaling another primary Favicon, or is this a primary Favicon?
    1.18 +    final boolean isPrimary;
    1.19 +
    1.20 +    // The Favicon bitmap.
    1.21 +    Bitmap faviconPayload;
    1.22 +
    1.23 +    // If set, faviconPayload is absent. Since the underlying ICO may contain multiple primary
    1.24 +    // payloads, primary payloads are never truly deleted from the cache, but instead have their
    1.25 +    // payload deleted and this flag set on their FaviconCacheElement. That way, the cache always
    1.26 +    // has a record of the existence of a primary payload, even if it is no longer in the cache.
    1.27 +    // This means that when a request comes in that will be best served using a primary that is in
    1.28 +    // the database but no longer cached, we know that it exists and can go get it (Useful when ICO
    1.29 +    // support is added).
    1.30 +    volatile boolean invalidated;
    1.31 +
    1.32 +    final int imageSize;
    1.33 +
    1.34 +    // Used for LRU pruning.
    1.35 +    final FaviconsForURL backpointer;
    1.36 +
    1.37 +    public FaviconCacheElement(Bitmap payload, boolean primary, int size, FaviconsForURL backpointer) {
    1.38 +        this.faviconPayload = payload;
    1.39 +        this.isPrimary = primary;
    1.40 +        this.imageSize = size;
    1.41 +        this.backpointer = backpointer;
    1.42 +    }
    1.43 +
    1.44 +    public FaviconCacheElement(Bitmap faviconPayload, boolean isPrimary, FaviconsForURL backpointer) {
    1.45 +        this.faviconPayload = faviconPayload;
    1.46 +        this.isPrimary = isPrimary;
    1.47 +        this.backpointer = backpointer;
    1.48 +
    1.49 +        if (faviconPayload != null) {
    1.50 +            imageSize = faviconPayload.getWidth();
    1.51 +        } else {
    1.52 +            imageSize = 0;
    1.53 +        }
    1.54 +    }
    1.55 +
    1.56 +    public int sizeOf() {
    1.57 +        if (invalidated) {
    1.58 +            return 0;
    1.59 +        }
    1.60 +        return faviconPayload.getRowBytes() * faviconPayload.getHeight();
    1.61 +    }
    1.62 +
    1.63 +    /**
    1.64 +     * Establish an ordering on FaviconCacheElements based on size and validity. An element is
    1.65 +     * considered "greater than" another if it is valid and the other is not, or if it contains a
    1.66 +     * larger payload.
    1.67 +     *
    1.68 +     * @param another The FaviconCacheElement to compare to this one.
    1.69 +     * @return -1 if this element is less than the given one, 1 if the other one is larger than this
    1.70 +     *         and 0 if both are of equal value.
    1.71 +     */
    1.72 +    @Override
    1.73 +    public int compareTo(FaviconCacheElement another) {
    1.74 +        if (invalidated && !another.invalidated) {
    1.75 +            return -1;
    1.76 +        }
    1.77 +
    1.78 +        if (!invalidated && another.invalidated) {
    1.79 +            return 1;
    1.80 +        }
    1.81 +
    1.82 +        if (invalidated) {
    1.83 +            return 0;
    1.84 +        }
    1.85 +
    1.86 +        final int w1 = imageSize;
    1.87 +        final int w2 = another.imageSize;
    1.88 +        if (w1 > w2) {
    1.89 +            return 1;
    1.90 +        } else if (w2 > w1) {
    1.91 +            return -1;
    1.92 +        }
    1.93 +        return 0;
    1.94 +    }
    1.95 +
    1.96 +    /**
    1.97 +     * Called when this element is evicted from the cache.
    1.98 +     *
    1.99 +     * If primary, drop the payload and set invalid. If secondary, just unlink from parent node.
   1.100 +     */
   1.101 +    public void onEvictedFromCache() {
   1.102 +        if (isPrimary) {
   1.103 +            // So we keep a record of which primaries exist in the database for this URL, we
   1.104 +            // don't actually delete the entry for primaries. Instead, we delete their payload
   1.105 +            // and flag them as invalid. This way, we can later figure out that what a request
   1.106 +            // really want is one of the primaries that have been dropped from the cache, and we
   1.107 +            // can go get it.
   1.108 +            invalidated = true;
   1.109 +            faviconPayload = null;
   1.110 +        } else {
   1.111 +            // Secondaries don't matter - just delete them.
   1.112 +            if (backpointer == null) {
   1.113 +                return;
   1.114 +            }
   1.115 +            backpointer.favicons.remove(this);
   1.116 +        }
   1.117 +    }
   1.118 +}

mercurial