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