SharedObject.java revision 836e6b40a94ec3fb7545a76cb072960442b7eee9
12ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/* GENERATED SOURCE. DO NOT MODIFY. */
22ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/*
32ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*******************************************************************************
42ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Copyright (C) 2013-2014, International Business Machines
52ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* Corporation and others.  All Rights Reserved.
62ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*******************************************************************************
72ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* SharedObject.java, ported from sharedobject.h/.cpp
82ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*
92ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* C++ version created on: 2013dec19
102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller* created by: Markus W. Scherer
112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller*/
122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpackage android.icu.impl.coll;
142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport java.util.concurrent.atomic.AtomicInteger;
162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerimport android.icu.util.ICUCloneNotSupportedException;
182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller/**
202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Base class for shared, reference-counted, auto-deleted objects.
212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Java subclasses are mutable and must implement clone().
222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>In C++, the SharedObject base class is used for both memory and ownership management.
242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * In Java, memory management (deletion after last reference is gone)
252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * is up to the garbage collector,
262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * but the reference counter is still used to see whether the referent is the sole owner.
272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <p>Usage:
292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * <pre>
302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * class S extends SharedObject {
312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     public clone() { ... }
322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * }
332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // Either use the nest class Reference (which costs an extra allocation),
352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // or duplicate its code in the class that uses S
362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * // (which duplicates code and is more error-prone).
372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * class U {
382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // For read-only access, use s.readOnly().
392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // For writable access, use S ownedS = s.copyOnWrite();
402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     private SharedObject.Reference&lt;S&gt; s;
412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // Returns a writable version of s.
422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // If there is exactly one owner, then s itself is returned.
432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // If there are multiple owners, then s is replaced with a clone,
442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // and that is returned.
452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     private S getOwnedS() {
462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         return s.copyOnWrite();
472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     }
482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     public U clone() {
492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         ...
502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         c.s = s.clone();
512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         ...
522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     }
532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * }
542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * class V {
562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // For read-only access, use s directly.
572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // For writable access, use S ownedS = getOwnedS();
582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     private S s;
592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // Returns a writable version of s.
602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // If there is exactly one owner, then s itself is returned.
612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // If there are multiple owners, then s is replaced with a clone,
622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     // and that is returned.
632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     private S getOwnedS() {
642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         if(s.getRefCount() > 1) {
652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             S ownedS = s.clone();
662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             s.removeRef();
672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             s = ownedS;
682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             ownedS.addRef();
692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         }
702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         return s;
712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     }
722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     public U clone() {
732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         ...
742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         s.addRef();
752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         ...
762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     }
772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     protected void finalize() {
782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         ...
792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         if(s != null) {
802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             s.removeRef();
812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *             s = null;
822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         }
832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *         ...
842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *     }
852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * }
862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * </pre>
872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Either use only Java memory management, or use addRef()/removeRef().
892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * Sharing requires reference-counting.
902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller *
912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * TODO: Consider making this more widely available inside ICU,
922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller * or else adopting a different model.
93836e6b40a94ec3fb7545a76cb072960442b7eee9Neil Fuller * @hide Only a subset of ICU is exposed in Android
94704056c96cc5de08c2425fa1679a5c0a92c5a88eNeil Fuller * @hide All android.icu classes are currently hidden
952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller */
962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fullerpublic class SharedObject implements Cloneable {
972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Similar to a smart pointer, basically a port of the static methods of C++ SharedObject.
992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1002ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public static final class Reference<T extends SharedObject> implements Cloneable {
1012ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        private T ref;
1022ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1032ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Reference(T r) {
1042ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ref = r;
1052ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if(r != null) {
1062ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                r.addRef();
1072ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
1082ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1092ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1102ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @SuppressWarnings("unchecked")
1112ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
1122ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public Reference<T> clone() {
1132ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            Reference<T> c;
1142ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            try {
1152ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                c = (Reference<T>)super.clone();
1162ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            } catch (CloneNotSupportedException e) {
1172ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                // Should never happen.
1182ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                throw new ICUCloneNotSupportedException(e);
1192ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
1202ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if(ref != null) {
1212ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ref.addRef();
1222ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
1232ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return c;
1242ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1252ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1262ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public T readOnly() { return ref; }
1272ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1282ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        /**
1292ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * Returns a writable version of the reference.
1302ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * If there is exactly one owner, then the reference itself is returned.
1312ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * If there are multiple owners, then the reference is replaced with a clone,
1322ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         * and that is returned.
1332ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller         */
1342ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public T copyOnWrite() {
1352ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            T r = ref;
1362ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if(r.getRefCount() <= 1) { return r; }
1372ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            @SuppressWarnings("unchecked")
1382ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            T r2 = (T)r.clone();
1392ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            r.removeRef();
1402ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            ref = r2;
1412ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            r2.addRef();
1422ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            return r2;
1432ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1442ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1452ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        public void clear() {
1462ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            if(ref != null) {
1472ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ref.removeRef();
1482ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller                ref = null;
1492ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            }
1502ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1512ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1522ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        @Override
1532ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        protected void finalize() throws Throwable {
1542ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            super.finalize();
1552ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            clear();
1562ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1572ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1582ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1592ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /** Initializes refCount to 0. */
1602ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public SharedObject() {}
1612ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1622ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /** Initializes refCount to 0. */
1632ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    @Override
1642ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public SharedObject clone() {
1652ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        SharedObject c;
1662ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        try {
1672ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            c = (SharedObject)super.clone();
1682ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        } catch (CloneNotSupportedException e) {
1692ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            // Should never happen.
1702ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller            throw new ICUCloneNotSupportedException(e);
1712ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        }
1722ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        c.refCount = new AtomicInteger();
1732ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        return c;
1742ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1752ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1762ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1772ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Increments the number of references to this object. Thread-safe.
1782ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1792ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final void addRef() { refCount.incrementAndGet(); }
1802ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1812ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Decrements the number of references to this object,
1822ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * and auto-deletes "this" if the number becomes 0. Thread-safe.
1832ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1842ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final void removeRef() {
1852ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Deletion in Java is up to the garbage collector.
1862ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        refCount.decrementAndGet();
1872ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1882ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1892ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    /**
1902ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     * Returns the reference counter. Uses a memory barrier.
1912ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller     */
1922ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final int getRefCount() { return refCount.get(); }
1932ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1942ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    public final void deleteIfZeroRefCount() {
1952ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller        // Deletion in Java is up to the garbage collector.
1962ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    }
1972ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller
1982ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller    private AtomicInteger refCount = new AtomicInteger();
1992ae130017183d2f66d55bf0ca51f8da3294644fdNeil Fuller}
200