pax_global_header00006660000000000000000000000064130036411640014510gustar00rootroot0000000000000052 comment=3fe81c7fb09d9118a04920642405fd052792b246 hppc-0.7.2/000077500000000000000000000000001300364116400124505ustar00rootroot00000000000000hppc-0.7.2/.gitignore000066400000000000000000000003441300364116400144410ustar00rootroot00000000000000# Mac specific .DS_Store # Maven target *.versionsBackup # Eclipse .classpath .project .settings .externalToolBuilders # External tools. .clover # Locally generated .builder.classpath .benchmark.*.db # IntelliJ .idea/ *.imlhppc-0.7.2/ALTERNATIVES.txt000066400000000000000000000021471300364116400151160ustar00rootroot00000000000000 ALTERNATIVES ------------ HPPC was written for selfish needs and because (at the time it was conceived) no other library offered a commercially permissive license. Nowadays there are a number of options to choose from (alphabetically). * fastutil (by Sebastiano Vigna), http://fastutil.di.unimi.it/ A very flexible, Apache licensed set of collections and algorithms. Compatible with Java Collections. * HPPC-RT (by Vincent Sonnier), https://github.com/vsonnier/hppc A fork of HPPC for real-time computing, minimizes allocations, introduces overhead-less iterators and other miscellaneous goodies. * Koloboke (by Roman Leventov), https://github.com/OpenHFT/Koloboke A very impressive library that offers unprecedented speed and features. Includes support for Java8 (including Collections compatibility). * PCJ (by Søren Bak), http://pcj.sourceforge.net/ The grand-daddy of them all. :) DO NOT use it, it contains bugs. But it deserves to be mentioned nonetheless. * Trove, https://bitbucket.org/robeden/trove/ If you're a GNU fan, this may be just the sweet spot for you. hppc-0.7.2/CHANGES.txt000066400000000000000000000442531300364116400142710ustar00rootroot00000000000000 [0.7.2] Released on October 25th, 2016 http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=12632 ** Other changes PR #5: OSGi descriptors in JAR manifests, bundle packaging. (Guillaume Delafosse) [0.7.1] Released on May 7th, 2015 http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=12628 ** New features HPPC-159: Add .visualizeKeyDistribution(int characters) to maps and sets ** Bug fixes HPPC-156: forEach iterators spin loop endlessly on *HashSet and *ScatterSet. HPPC-158: *ScatterMap.from should shadow *HashMap.from with proper covariant. HPPC-155: *ScatterSet.from should shadow *HashSet.from with proper covariant. [0.7.0] Released on May 5th, 2015 http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=12421 ** API-breaking changes HPPC-117: A summary of API changes resulting from other issues. * (HPPC-118) Direct generic buffers are declared Object[]. Should not affect runtime code (Object[] casts were required anyway). * (HPPC-106) Guava adapters dropped. Copy to your own code from previous HPPC release if required. * 1.7 compatibility only. static factories removed, use diamonds. T.newInstanceWithCapacity(*) -> removed, use new T<>(*) T.newInstanceWithExpectedSize(*) -> removed, use new T<>(*) T.newInstance(*) -> removed, use new T<>(*) T.from(container) -> removed, use new T<>(container) * EmptyArrays has been removed. Empty arrays are now a static constant in each *ArrayList. * (HPPC-97) Removed allocated[] fields from hash containers. If you used explicit loops utilizing allocated[] you should rewrite them to use cursors or other form of iteration instead (it will be simpler than taking care of the empty slot marker). * (HPPC-146) Removed DoubleLinkedIntSet. * (HPPC-115) Hash containers now, by default, use a random internal mixing seed to reorder entries (so the order of keys is not constant from execution to execution). See detailed HPPC-115 entry below. * (HPPC-121) Renamed methods: T.removeFirstOccurrences -> T.removeFirst T.removeLastOccurrences -> T.removeLast T.removeAllOccurrences -> T.removeAll(type) * (HPPC-123) Dropped MurmurHash3 class entirely. * (HPPC-125) The semantics of how equals works has changed (a container can be equal only if the comparison's target is of the same class and contains the same entries. * (HPPC-129) ArraySizingStrategy#round() method has been removed completely. * (HPPC-130) removeAll(KTypeLookupContainer) had an incorrect generic signature of: public int removeAll(final KTypeLookupContainer c) now corrected to: public int removeAll(final KTypeLookupContainer c) (for primitive types this does not apply). * (HPPC-131) retainAll(KTypeLookupContainer) had an incorrect generic signature of: public int retainAll(final KTypeLookupContainer c) now corrected to: public int retainAll(final KTypeLookupContainer c) (for primitive types this does not apply). * (HPPC-133) KTypeContainer.toArray(Class) now accepts any array component type; runtime checks will throw ArrayStoreException if not compatible. * (HPPC-135) KTypeVTypeAssociativeContainer#removeAll had an incorrect generic signature of: public int removeAll(KTypeContainer container) now corrected to: public int removeAll(KTypeContainer container) * (HPPC-116): Dropped methods that required a memory write (lset, lget, lkey) and replaced them with methods that take a logical "index" of a key: int indexOf(KType); boolean indexExists(int index); VType indexGet(int index); VType indexReplace(int index, VType newValue); void indexInsert(int index, KType key, VType value); So, for example: int index; if ((index = map.indexOf(key)) >= 0) { // key exists, do something with the value. doSomething(map.indexGet(index)); } else { // Insert the new key-value pair. map.indexInsert(index, key, newValue); } * (HPPC-141): Dropped mutable type wrappers. * (HPPC-144): Several less-frequently used classes have been moved to a separate JAR file. See full description of HPPC-144 below. * (HPPC-145): Removed any "Open" infix from all classes: KTypeOpenHashSet -> KTypeHashSet KTypeVTypeOpenHashMap -> KTypeVTypeHashMap * (HPPC-152) XorShiftRandom has been removed and replaced with a simpler, int-only PRNG XorShift128+ (XorShift128P). ** New features HPPC-150: Make the default key mixing strategy globally configurable (via "hppc.bitmixer" sysprop). This property allows switching from random bit mixer strategy to any of the following: - random the default strategy. Varies bit mixer per instance. - deterministic the default strategy in HPPC up to v. 0.6.x. Varies bit mixer depending on hash container size. - none No bit mixing is used (hash sets/maps become scatter sets/ maps). This is a last-resort, discouraged, property. Your code should not rely on hash map/set ordering. Your code should use scatter maps when speed is of absolute importance and there are guarantees that keys won't be copied around to other associative containers. HPPC-145: Removed any "Open" infix from all classes. HPPC-144: Moved certain esoteric key/value containers to a separate JAR. This JAR has an identical dependency as main HPPC jar, but is declared with an "esoteric" classifier. The following containers are included in the set of "esoteric" ones: * all associative containers with Byte* keys * all associative containers with Float* keys * all associative containers with Double* keys Byte-keyed containers are very infrequent (just create a plain array for values). Hash containers keyed by a floating-point type are odd and may lead to confusion. The problem is how the "key" should be normalized from fixed-bit representation and then internally compared. If fp normalization is applied (like Double.doubleToLongBits) then the value one puts in a set or a map may be different from the value later retrieved while iterating over the set of keys. On the other hand, if one takes raw floating point values (for example Double.doubleToRawLongBits) then there are awkward side-effects (like various types of NaNs can be stored as separate keys, for example). All floating-point "esoterics" use proper normalization, but it is strongly advised to manually apply the floating point-fixed-point conversion (normalization) in the target code and just use a corresponding fixed-point associative container for storing normalized values. HPPC-143: Added KTypeScatterSet and KTypeVTypeScatterMap. These classes are specializations of KTypeHashSet and KTypeVTypeHashMap with a simpler bit distribution function and no bit mixers. They are useful for key existence checks or counting but should not be propagated across containers. HPPC-134: Set and Map's removeAll() should pick the best removal strategy. HPPC-139: Added release() to the API (clears and releases internal buffers). HPPC-116: Drop methods that require memory write (lset, lget, lkey) and replace them with methods that take a logical "index" of a key. HPPC-115: Provide better guard against key clustering leading to exponential times. HPPC-97: Use unallocated slot marker key instead of an explicit allocation table for hash containers. This should result in memory savings and even speedups resulting from fewer memory accesses. HPPC-112: ensureCapacity(elements) added to all containers. HPPC-113: Clean up the definition of "capacity" vs. buffer size. Initial capacity is now the number of elements that can be stored without hash container rehash. A few methods have been removed or renamed because the meaning of "capacity" and presizing for the given number of expected elements is now equivalent. See API changes. HPPC-114: Buffer resizing and allocation should be throwing non-assertion mode exceptions. This is an unchecked exception. It will also leave the data structure in a consistent state. ** Bug fixes HPPC-135: KTypeVTypeAssociativeContainer#removeAll had an incorrect generic signature. HPPC-133: KTypeContainer.toArray(Class) can return incorrect array type. HPPC-131: retainAll(KTypeLookupContainer) had an incorrect generic signature. HPPC-130: removeAll(KTypeLookupContainer) had an incorrect generic signature. HPPC-115: Hash containers now, by default, use a random internal mixing seed to reorder entries. This is done to prevent a potential (but likely!) case of exponential costs of merging keys from two or more containers. If you desperately need non-permuted order, use an explicit constructor and pass HashOrderMixing.none() as the mixing strategy. Carefully weigh the risk of stalling your program with data-related deadlocks; this is only useful if you're using hash container as a scatter table (without merging it with anything else). You can also provide your own strategy to get predictable hash key ordering. Just make sure the mix seed is different from container to container (for example by using a thread local increment counter or something like that). ** Other changes HPPC-152: Remove XorShiftRandom (add a simpler RPRG: XorShift128+). HPPC-149: Recognize tests.seed as the initialization seed for randomized key mix strategies. HPPC-102: Use Arrays.copyOf instead of new[]+System.arraycopy() for resizing arrays. HPPC-141: Dropped mutable type wrappers (*Holder). HPPC-128: The preprocessor (intrinsics, preprocessor) is now deployed as part of the official release. HPPC-138: Move Intrinsics class to the generator project. Add forbidden-API checks to ensure intrinsics are replaced. HPPC-137: An overhaul of intrinsics (equality comparisons, no vtype/ ktype distinction, etc.) HPPC-129: ArraySizingStrategy#round() method has been removed completely. HPPC-125: The equals method should not return true when comparing against subclasses of the current object. This can be very misleading, especially when the subclass has a different implementation of key comparisons, etc. HPPC-123: Dropped MurmurHash3 class entirely. HPPC-121: Rename remove{All|First|Last}Occurrence(s) to remove{All|First|Last}(key). HPPC-146: Removed IntDoubleLinkedSet. HPPC-120: Rework entry shifting routine to be less hairy. HPPC-106: Drop Guava adapter (and dependency). HPPC-118: Buffers for generic classes are now declared as Object[] and not as generic type array. This prevents problems with compiler-injected casts (it does not matter for the erased type but matters in user code). HPPC-105: Cleanup project structure and IDE integration. HPPC-109: Moved @author tags to NOTICE.txt. [0.6.1] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=12420 ** New features HPPC-96: Identity hash maps with primitive backing storage arrays for values. [0.6.0] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=11820 ** API-breaking changes HPPC-82: Expose resizeAt and lastSlot to subclasses (sets, maps). HPPC-94: Drop support for Java 1.5 (backcompat build). ** Bug fixes HPPC-93: NaN keys are not treated correctly in hash sets/ maps. HPPC-80: Practical deadlock on populating a set/ map with an iterator over another map (storage-size dependent rehash). HPPC-81: Improvements to near-the-limit collection sizes and resize strategies. ** New features HPPC-85: addTo and putOrAdd pulled up to ObjectIntMap interface. HPPC-91: Added newInstanceWithExpectedSize methods to KTypeOpenHashSet and KTypeVTypeOpenHashMap (no buffer resizing for a given number of elements). [shaunkalley] HPPC-88: added get(key,defaultValue) to somehow support custom default values and potential read-only concurrent containsKey/get conditionals. ** Changes in functionality ** Other changes HPPC-79: javadocs generated with 1.7 (and 1.8) look crappy. [0.5.5] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=12120 ** New features ** Other changes ** API-breaking changes ** Bug fixes [0.5.4] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=11927 ** New features HPPC-91: Added newInstanceWithExpectedSize methods to KTypeOpenHashSet and KTypeVTypeOpenHashMap (no buffer resizing for a given number of elements). [shaunkalley] [0.5.3] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=11833 ** New features HPPC-88: added get(key,defaultValue) to somehow support custom default values and potential read-only concurrent containsKey/get conditionals. [0.5.2] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=11832 ** Bug fixes HPPC-84: hashCode calculated incorrectly for sets/ maps [0.5.1] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=11828 ** API-breaking changes HPPC-82: Expose resizeAt and lastSlot to subclasses (sets, maps). ** Bug fixes HPPC-80: Practical deadlock on populating a set/ map with an iterator over another map (storage-size dependent rehash). HPPC-81: Improvements to near-the-limit collection sizes and resize strategies. ** New features ** Changes in functionality ** Other changes HPPC-79: javadocs generated with 1.7 (and 1.8) look crappy. [0.5.0] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=10321 ** API-breaking changes: HPPC-66: allow retrieving key instances by key-equality from Object*Map versions of hash maps. Renamed lget in KTypeOpenHashSet to lkey for consistency. So, the methods accessing last found key in sets and maps are: lget (maps, accesses last value), lset (maps, accesses last value), lkey (maps, sets, accesses last key), lslot (both, slot index). HPPC-68: Lifted final markers on public methods ** New features HPPC-63: a jdk15-compatible artifact is being published to Maven Central now. HPPC-66: allow retrieving key instances by key-equality from Object*Map versions of hash maps and hash sets. HPPC-69: added toString to cursors. HPPC-77: BitSet should use hotspot intrinsics (popcnt mostly) ** Bug fixes HPPC-65: putOrAdd uses == for comparing object keys instead of equality HPPC-72: XorShiftRandom always returns a zero. [Sergey Peretyatko] This class was used only in benchmarks and tests so unless you're using it directly you're not affected. HPPC-73: get, contains and any other method may block indefinitely with high load factors and full storage array capacity HPPC-74: Load factor is not used in KTypeOpenHashSet HPPC-75: put or add may leave the internal state of the hash containers inconsistent on OOM conditions ** Other Added newInstance() to BitSet and IntDoubleLinkedSet for consistency. [0.4.1] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=10322 ** New features HPPC-63: a jdk15-compatible artifact is being published to Maven Central now. ** Bug fixes HPPC-65: putOrAdd uses == for comparing object keys instead of equality [0.4.0] http://issues.carrot2.org/secure/ReleaseNote.jspa?projectId=10070&version=10210 ** API-breaking changes: HPPC-60: Cleaned up the code of all iterators (including some name/scope changes of iterator classes, so if you relied on these, things may break). HPPC-59: keySet() renamed to keys() on associative containers. HPPC-46: toArray() on object types must return actual T[], not Object[] HPPC-52: Dropped custom hash functions and comparators from associative containers for speed reasons. ** New features HPPC-61: Cleaned up Maven structure: parent aggregator and submodules. HPPC-57: Added a view of values to associative containers (values() method). HPPC-49: Added support for XorShift random. HPPC-34: Added support for Cloneable. HPPC-51: Replace double hashing in open hash map/set to linear probing and a good hashing function to ensure random distribution of elements HPPC-47: Changed the implementation of MurmurHash to MurmurHash3, impl. borrowed from Sebastiano Vigna's fastutil library. [ASL] ** Bug fixes HPPC-46: toArray() on object types must return actual T[], not Object[] ** Other HPPC-58: Better integration with Eclipse, new template->code generation. hppc-0.7.2/INSTALL.txt000066400000000000000000000011161300364116400143160ustar00rootroot00000000000000Maven shortcuts --------------- # All unit tests mvn clean verify # Package JAR files, no tests. mvn clean package -Pquick Eclipse workflow/ import ------------------------ # Install template processor and copy over initial IDE .settings mvn -Peclipse # Ready to use m2e: "File->Import->Existing Maven Projects". Benchmarking ------------ There are some sanity tests and isolated benchmarks of common operations in hppc-benchmarks. # Create benchmark JAR mvn package -Pquick -am -pl :hppc-benchmarks # List available benchmarks java -jar hppc-benchmarks/target/benchmarks.jar -l hppc-0.7.2/LICENSE.txt000066400000000000000000000261741300364116400143050ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2010-2013, Carrot Search s.c., Boznicza 11/56, Poznan, Poland Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. hppc-0.7.2/NOTICE.txt000066400000000000000000000004151300364116400141720ustar00rootroot00000000000000ACKNOWLEDGEMENT =============== HPPC borrowed code, ideas or both from: * Apache Lucene, http://lucene.apache.org/ (Apache license) * Fastutil, http://fastutil.di.unimi.it/ (Apache license) * Koloboke, https://github.com/OpenHFT/Koloboke (Apache license) hppc-0.7.2/README.txt000066400000000000000000000011001300364116400141360ustar00rootroot00000000000000 HPPC: High Performance Primitive Collections -------------------------------------------- Collections of primitive types (maps, sets, stacks, lists) with open internals and an API twist (no java.util.collections.* compatibility). See the following for more information: Wiki: https://github.com/carrotsearch/hppc/wiki Bugs: http://issues.carrot2.org/browse/HPPC/ See ALTERNATIVES.txt if you're just shopping around. See LICENSE.txt to make your company's lawyer happy. See CHANGES.txt for API changes and updates. (c) Carrot Search s.c., http://carrotsearch.com/ hppc-0.7.2/etc/000077500000000000000000000000001300364116400132235ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/000077500000000000000000000000001300364116400146475ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/configs/000077500000000000000000000000001300364116400162775ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/configs/hppc-benchmarks/000077500000000000000000000000001300364116400213445ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/configs/hppc-benchmarks/_externalToolBuilders/000077500000000000000000000000001300364116400256555ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/configs/hppc-benchmarks/_externalToolBuilders/hppc.benchmarks-jmh.launch000066400000000000000000000026171300364116400327010ustar00rootroot00000000000000 hppc-0.7.2/etc/eclipse/configs/hppc-benchmarks/_project000066400000000000000000000015751300364116400231040ustar00rootroot00000000000000 hppc-benchmarks org.eclipse.ui.externaltools.ExternalToolBuilder auto, LaunchConfigHandle <project>/.externalToolBuilders/hppc.benchmarks-jmh.launch org.eclipse.jdt.core.javabuilder org.eclipse.m2e.core.maven2Builder org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature hppc-0.7.2/etc/eclipse/configs/hppc/000077500000000000000000000000001300364116400172315ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/configs/hppc/_externalToolBuilders/000077500000000000000000000000001300364116400235425ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/configs/hppc/_externalToolBuilders/hppc.templates-generate.launch000066400000000000000000000031701300364116400314560ustar00rootroot00000000000000 hppc-0.7.2/etc/eclipse/configs/hppc/_project000066400000000000000000000015661300364116400207710ustar00rootroot00000000000000 hppc org.eclipse.ui.externaltools.ExternalToolBuilder auto, LaunchConfigHandle <project>/.externalToolBuilders/hppc.templates-generate.launch org.eclipse.jdt.core.javabuilder org.eclipse.m2e.core.maven2Builder org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature hppc-0.7.2/etc/eclipse/hppc.process-templates.launch000066400000000000000000000034211300364116400224460ustar00rootroot00000000000000 hppc-0.7.2/etc/eclipse/hppc.test-all.launch000066400000000000000000000022441300364116400205230ustar00rootroot00000000000000 hppc-0.7.2/etc/eclipse/hppc.test-templates.launch000066400000000000000000000023141300364116400217470ustar00rootroot00000000000000 hppc-0.7.2/etc/eclipse/settings/000077500000000000000000000000001300364116400165075ustar00rootroot00000000000000hppc-0.7.2/etc/eclipse/settings/org.eclipse.jdt.core.prefs000066400000000000000000000767041300364116400235070ustar00rootroot00000000000000eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve org.eclipse.jdt.core.compiler.compliance=1.7 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.doc.comment.support=enabled org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.autoboxing=ignore org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning org.eclipse.jdt.core.compiler.problem.deadCode=warning org.eclipse.jdt.core.compiler.problem.deprecation=warning org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled org.eclipse.jdt.core.compiler.problem.discouragedReference=warning org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=protected org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=public org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error org.eclipse.jdt.core.compiler.problem.nullReference=warning org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled org.eclipse.jdt.core.compiler.problem.unusedImport=warning org.eclipse.jdt.core.compiler.problem.unusedLabel=warning org.eclipse.jdt.core.compiler.problem.unusedLocal=warning org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning org.eclipse.jdt.core.compiler.source=1.7 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false org.eclipse.jdt.core.formatter.comment.format_block_comments=false org.eclipse.jdt.core.formatter.comment.format_header=false org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true org.eclipse.jdt.core.formatter.comment.format_line_comments=false org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true org.eclipse.jdt.core.formatter.comment.indent_root_tags=true org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert org.eclipse.jdt.core.formatter.comment.line_length=80 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true org.eclipse.jdt.core.formatter.indentation.size=2 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=true org.eclipse.jdt.core.formatter.join_wrapped_lines=true org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.lineSplit=120 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true org.eclipse.jdt.core.formatter.tabulation.char=space org.eclipse.jdt.core.formatter.tabulation.size=2 org.eclipse.jdt.core.formatter.use_on_off_tags=true org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true hppc-0.7.2/etc/eclipse/settings/org.eclipse.m2e.core.prefs000066400000000000000000000001411300364116400233670ustar00rootroot00000000000000activeProfiles=eclipse eclipse.preferences.version=1 resolveWorkspaceProjects=true version=1 hppc-0.7.2/etc/forbidden-apis/000077500000000000000000000000001300364116400161115ustar00rootroot00000000000000hppc-0.7.2/etc/forbidden-apis/intrinsics.txt000066400000000000000000000001771300364116400210440ustar00rootroot00000000000000@defaultMessage Left-over intrinsics that should have been replaced by the template processor? com.carrotsearch.hppc.Intrinsicshppc-0.7.2/etc/forbidden-apis/time-relative.txt000066400000000000000000000002121300364116400214140ustar00rootroot00000000000000@defaultMessage Time-derived randomness shouldn't be present in the code. java.lang.System#currentTimeMillis() java.lang.System#nanoTime()hppc-0.7.2/hppc-benchmarks/000077500000000000000000000000001300364116400155155ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/pom.xml000066400000000000000000000070661300364116400170430ustar00rootroot00000000000000 4.0.0 com.carrotsearch hppc-parent 0.7.2 ../pom.xml hppc-benchmarks jar HPPC Benchmarks com.carrotsearch hppc ${project.version} com.carrotsearch hppc ${project.version} esoteric it.unimi.dsi fastutil ${version.fastutil} net.openhft koloboke-impl-jdk6-7 ${version.koloboke} org.openjdk.jmh jmh-core ${version.jmh} org.openjdk.jmh jmh-generator-annprocess ${version.jmh} provided true true verify org.apache.maven.plugins maven-shade-plugin ${version.maven-shade-plugin} shade-jmh package shade benchmarks org.openjdk.jmh.Main *:* META-INF/*.SF META-INF/*.DSA META-INF/*.RSA eclipse m2e.version org.apache.maven.plugins maven-shade-plugin ${version.maven-shade-plugin} shade-jmh none hppc-0.7.2/hppc-benchmarks/src/000077500000000000000000000000001300364116400163045ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/000077500000000000000000000000001300364116400172305ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/000077500000000000000000000000001300364116400201515ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/000077500000000000000000000000001300364116400207275ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/000077500000000000000000000000001300364116400234075ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/000077500000000000000000000000001300364116400243415ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/000077500000000000000000000000001300364116400264565ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/B001_ModXor.java000066400000000000000000000020301300364116400312060ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; @Fork(1) @Warmup(iterations = 5) @Measurement(iterations = 5) @State(Scope.Thread) public class B001_ModXor { private int v; private int mask = 0x238751; @Benchmark public int modOp() { v = v % mask++; return v; } @Benchmark public int xorOp() { v = v ^ mask++; return v; } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .include(B001_ModXor.class.getSimpleName()) .build(); new Runner(opt).run(); } } hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/B002_HashSet_Add.java000066400000000000000000000036301300364116400321150ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import com.carrotsearch.hppc.XorShift128P; @Fork(1) @Warmup(iterations = 5) @Measurement(iterations = 5) @State(Scope.Benchmark) public class B002_HashSet_Add { public static interface Ops { Object addAll(int [] keys); } @Param("0.75") public double loadFactor; @Param public Library library; @Param({"200"}) public int mbOfKeys; public int [] keys; public IntSetOps ops; @Setup(Level.Iteration) public void prepareDelegate() { ops = library.newIntSet(keys.length, loadFactor); } @Setup(Level.Trial) public void prepare() { int keyCount = mbOfKeys * (1024 * 1024) / 4; keys = new int [keyCount]; XorShift128P rnd = new XorShift128P(0xdeadbeefL); for (int i = 0; i < keys.length; i++) { keys[i] = rnd.nextInt(); } } @Benchmark() @BenchmarkMode(Mode.SingleShotTime) public Object bulk() { ops.bulkAdd(keys); return ops; } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder() .param("library", "HPPC_SCATTER") .include(B002_HashSet_Add.class.getSimpleName()) .build(); new Runner(opt).run(); } } hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/B003_HashSet_Contains.java000066400000000000000000000036261300364116400332110ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; import com.carrotsearch.hppc.XorShift128P; @Fork(1) @Warmup(iterations = 5) @Measurement(iterations = 5) @State(Scope.Benchmark) public class B003_HashSet_Contains { @Param("0.75") public double loadFactor; @Param public Library library; @Param({"200"}) public int mbOfKeys; public int [] keys; public IntSetOps ops; @Setup(Level.Trial) public void prepare() { int keyCount = mbOfKeys * (1024 * 1024) / 4; keys = new int [keyCount]; XorShift128P rnd = new XorShift128P(0xdeadbeefL); for (int i = 0; i < keys.length; i++) { keys[i] = rnd.nextInt(2 * keys.length); } ops = library.newIntSet(keys.length, loadFactor); int[] existing = new int [keyCount]; for (int i = 0; i < keys.length; i++) { existing[i] = rnd.nextInt(2 * keys.length); } ops.bulkAdd(existing); } @Benchmark() @BenchmarkMode(Mode.SingleShotTime) public Object bulk() { return ops.bulkContains(keys); } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder().include(B003_HashSet_Contains.class.getSimpleName()).build(); new Runner(opt).run(); } } B004_HashSet_CollisionAvalanche.java000066400000000000000000000036001300364116400351030ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarkspackage com.carrotsearch.hppc.benchmarks; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Measurement; import org.openjdk.jmh.annotations.Mode; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; import org.openjdk.jmh.annotations.Warmup; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder; @Fork(1) @Warmup(iterations = 5) @Measurement(iterations = 5) @State(Scope.Benchmark) public class B004_HashSet_CollisionAvalanche { @Param("0.75") public double loadFactor; @Param public Library library; private IntSetOps source; private IntSetOps target; private int[] keys; @Setup(Level.Trial) public void prepare() { // make sure we have nearly full load (dense source) int keyCount = (int) Math.ceil((1 << 19) / loadFactor) - 5000; int [] keys = new int [keyCount]; for (int i = keyCount; i-- != 0;) { keys[i] = i; } source = library.newIntSet(0, loadFactor); source.bulkAdd(keys); this.keys = source.iterationOrderArray(); } @Setup(Level.Iteration) public void prepareDelegate() { target = library.newIntSet(0, loadFactor); } @Benchmark() @BenchmarkMode(Mode.SingleShotTime) public Object run() { target.bulkAdd(keys); return target; } public static void main(String[] args) throws RunnerException { Options opt = new OptionsBuilder().include(B004_HashSet_CollisionAvalanche.class.getSimpleName()).build(); new Runner(opt).run(); } } hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/BenchmarkDelegate.java000066400000000000000000000001541300364116400326460ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; public interface BenchmarkDelegate{ T newInstance(); } hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/HppcBenchmarkDelegate.java000066400000000000000000000003621300364116400334620ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; public class HppcBenchmarkDelegate implements B002_HashSet_Add.Ops { public HppcBenchmarkDelegate() { } @Override public Object addAll(int[] keys) { return null; } } hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/IntSetOps.java000066400000000000000000000003111300364116400312040ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; public interface IntSetOps { void add(int key); void bulkAdd(int [] keys); int bulkContains(int [] keys); int[] iterationOrderArray(); } hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/Library.java000066400000000000000000000023311300364116400307240ustar00rootroot00000000000000package com.carrotsearch.hppc.benchmarks; import com.carrotsearch.hppc.benchmarks.implementations.FastutilIntSetOps; import com.carrotsearch.hppc.benchmarks.implementations.HppcIntSetOps; import com.carrotsearch.hppc.benchmarks.implementations.HppcIntScatterSetOps; import com.carrotsearch.hppc.benchmarks.implementations.KolobokeIntSetOps; /** * Benchmarked libraries. */ public enum Library { HPPC { @Override public IntSetOps newIntSet(int expectedElements, double loadFactor) { return new HppcIntSetOps(expectedElements, loadFactor); } }, HPPC_SCATTER { @Override public IntSetOps newIntSet(int expectedElements, double loadFactor) { return new HppcIntScatterSetOps(expectedElements, loadFactor); } }, FASTUTIL { @Override public IntSetOps newIntSet(int expectedElements, double loadFactor) { return new FastutilIntSetOps(expectedElements, loadFactor); } }, KOLOBOKE { @Override public IntSetOps newIntSet(int expectedElements, double loadFactor) { return new KolobokeIntSetOps(expectedElements, loadFactor); } }; public abstract IntSetOps newIntSet(int expectedElements, double loadFactor); }hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/implementations/000077500000000000000000000000001300364116400316665ustar00rootroot00000000000000FastutilIntSetOps.java000066400000000000000000000016071300364116400360620ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/implementationspackage com.carrotsearch.hppc.benchmarks.implementations; import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import com.carrotsearch.hppc.benchmarks.IntSetOps; public class FastutilIntSetOps implements IntSetOps { private final IntOpenHashSet delegate; public FastutilIntSetOps(int expectedElements, double loadFactor) { this.delegate = new IntOpenHashSet(expectedElements, (float) loadFactor); } @Override public void add(int key) { delegate.add(key); } @Override public void bulkAdd(int[] keys) { for (int key : keys) { delegate.add(key); } } @Override public int bulkContains(int[] keys) { int v = 0; for (int key : keys) { if (delegate.contains(key)) { v++; } } return v; } @Override public int[] iterationOrderArray() { return delegate.toIntArray(); } } HppcIntScatterSetOps.java000066400000000000000000000015611300364116400365060ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/implementationspackage com.carrotsearch.hppc.benchmarks.implementations; import com.carrotsearch.hppc.IntScatterSet; import com.carrotsearch.hppc.benchmarks.*; public class HppcIntScatterSetOps implements IntSetOps { private final IntScatterSet delegate; public HppcIntScatterSetOps(int expectedElements, double loadFactor) { this.delegate = new IntScatterSet(expectedElements, loadFactor); } @Override public void add(int key) { delegate.add(key); } @Override public void bulkAdd(int[] keys) { for (int key : keys) { delegate.add(key); } } @Override public int bulkContains(int[] keys) { int v = 0; for (int key : keys) { if (delegate.contains(key)) { v++; } } return v; } @Override public int[] iterationOrderArray() { return delegate.toArray(); } } HppcIntSetOps.java000066400000000000000000000015411300364116400351560ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/implementationspackage com.carrotsearch.hppc.benchmarks.implementations; import com.carrotsearch.hppc.IntHashSet; import com.carrotsearch.hppc.benchmarks.IntSetOps; public class HppcIntSetOps implements IntSetOps { private final IntHashSet delegate; public HppcIntSetOps(int expectedElements, double loadFactor) { this.delegate = new IntHashSet(expectedElements, loadFactor); } @Override public void add(int key) { delegate.add(key); } @Override public void bulkAdd(int[] keys) { for (int key : keys) { delegate.add(key); } } @Override public int bulkContains(int[] keys) { int v = 0; for (int key : keys) { if (delegate.contains(key)) { v++; } } return v; } @Override public int[] iterationOrderArray() { return delegate.toArray(); } } KolobokeIntSetOps.java000066400000000000000000000021721300364116400360320ustar00rootroot00000000000000hppc-0.7.2/hppc-benchmarks/src/main/java/com/carrotsearch/hppc/benchmarks/implementationspackage com.carrotsearch.hppc.benchmarks.implementations; import net.openhft.koloboke.collect.hash.HashConfig; import net.openhft.koloboke.collect.set.hash.HashIntSet; import net.openhft.koloboke.collect.set.hash.HashIntSets; import com.carrotsearch.hppc.benchmarks.IntSetOps; public class KolobokeIntSetOps implements IntSetOps { private final HashIntSet delegate; public KolobokeIntSetOps(int expectedElements, double loadFactor) { this.delegate = HashIntSets.getDefaultFactory() .withHashConfig(HashConfig.fromLoads(loadFactor / 2, loadFactor, loadFactor)).newMutableSet(); this.delegate.ensureCapacity(expectedElements); } @Override public void add(int key) { delegate.add(key); } @Override public void bulkAdd(int[] keys) { for (int key : keys) { delegate.add(key); } } @Override public int bulkContains(int[] keys) { int v = 0; for (int key : keys) { if (delegate.contains(key)) { v++; } } return v; } @Override public int[] iterationOrderArray() { return delegate.toIntArray(); } } hppc-0.7.2/hppc-examples/000077500000000000000000000000001300364116400152165ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/pom.xml000066400000000000000000000036141300364116400165370ustar00rootroot00000000000000 4.0.0 com.carrotsearch hppc-parent 0.7.2 ../pom.xml hppc-examples jar HPPC Examples true true com.carrotsearch hppc ${project.version} junit junit test com.carrotsearch.randomizedtesting randomizedtesting-runner test org.assertj assertj-core jar test com.carrotsearch.randomizedtesting junit4-maven-plugin junit4-tests junit4 **/*HppcExample_* hppc-0.7.2/hppc-examples/src/000077500000000000000000000000001300364116400160055ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/000077500000000000000000000000001300364116400167645ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/000077500000000000000000000000001300364116400177055ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/000077500000000000000000000000001300364116400204635ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/000077500000000000000000000000001300364116400231435ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/000077500000000000000000000000001300364116400240755ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examples/000077500000000000000000000000001300364116400257135ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examples/Helpers.java000066400000000000000000000006711300364116400301640ustar00rootroot00000000000000package com.carrotsearch.hppc.examples; import java.util.Locale; import com.carrotsearch.hppc.SuppressForbidden; class Helpers { @SuppressForbidden public static void printf(String msg, Object... args) { System.out.printf(Locale.ROOT, msg, args); } @SuppressForbidden public static void printfln(String msg, Object... args) { System.out.printf(Locale.ROOT, msg, args); System.out.println(); } } HppcExample_001_IteratingOverLists.java000066400000000000000000000033761300364116400351570ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import static com.carrotsearch.hppc.examples.Helpers.*; import org.junit.Test; import com.carrotsearch.hppc.IntArrayList; import com.carrotsearch.hppc.cursors.IntCursor; import com.carrotsearch.hppc.procedures.IntProcedure; /** * Examples of how to iterate over HPPC lists. */ public class HppcExample_001_IteratingOverLists { public final IntArrayList list = IntArrayList.from(1, 1, 2, 3, 5); /** * All lists implement {@link Iterable} interface that returns a "cursor" * object that moves over the container's elements. The cursor object remains * identical for the entire iteration (very little memory overhead). */ @Test public void cursor() { for (IntCursor c : list) { printfln("list[%d] = %d", c.index, c.value); } } /** * A simple loop over indices of a list. */ @Test public void simpleLoop() throws Exception { for (int i = 0, max = list.size(); i < max; i++) { printfln("list[%d] = %d", i, list.get(i)); } } /** * A for-each type loop with an anonymous class. Note the index * of the current element is not passed to the procedure. */ @Test public void forEachLoop() throws Exception { list.forEach(new IntProcedure() { int index; public void apply(int value) { printfln("list[%d] = %d", index++, value); } }); } /** * A direct buffer access. * * Also see {@link HppcExample_005_IteratingOverObjectBuffers} * for caveats concerning iterating over object buffers. */ @Test public void directBufferLoop() throws Exception { final int[] buffer = list.buffer; final int size = list.size(); for (int i = 0; i < size; i++) { printfln("list[%d] = %d", i, buffer[i]); } } } HppcExample_002_IteratingOverDeques.java000066400000000000000000000034671300364116400353110ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import static com.carrotsearch.hppc.examples.Helpers.*; import java.util.Iterator; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.IntArrayDeque; import com.carrotsearch.hppc.cursors.IntCursor; import com.carrotsearch.hppc.procedures.IntProcedure; /** * Examples of how to iterate over HPPC deques. */ public class HppcExample_002_IteratingOverDeques { public IntArrayDeque deque; @Before public void setup() { deque = new IntArrayDeque(); deque.addLast(1, 1, 2, 3, 5); } /** * All deques implement {@link Iterable} interface that returns a "cursor" * object that moves over the container's elements. The cursor object remains * identical for the entire iteration (very little memory overhead). * * The cursor's index points at the underlying buffer's position of a * given element. */ @Test public void cursorFirstToLast() { for (IntCursor c : deque) { printfln("deque[%d] = %d", c.index, c.value); } } /** * Reverse order iterator (cursor). */ @Test public void cursorLastToFirst() { for (Iterator i = deque.descendingIterator(); i.hasNext();) { IntCursor c = i.next(); printfln("deque[%d] = %d", c.index, c.value); } } /** * A for-each type loop with an anonymous class. */ @Test public void forEachLoop() throws Exception { deque.forEach(new IntProcedure() { public void apply(int value) { printfln("deque[?] = %d", value); } }); } /** * A for-each type loop with an anonymous class. */ @Test public void forEachLoopReversed() throws Exception { deque.descendingForEach(new IntProcedure() { public void apply(int value) { printfln("deque[?] = %d", value); } }); } } HppcExample_003_IteratingOverSets.java000066400000000000000000000040711300364116400347720ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import static com.carrotsearch.hppc.examples.Helpers.*; import static org.assertj.core.api.Assertions.*; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.IntHashSet; import com.carrotsearch.hppc.IntScatterSet; import com.carrotsearch.hppc.cursors.IntCursor; import com.carrotsearch.hppc.procedures.IntProcedure; /** * Examples of how to iterate over HPPC sets. */ public class HppcExample_003_IteratingOverSets { public IntHashSet hashSet; public IntScatterSet scatterSet; @Before public void setup() { // Note that copying the other way around wouldn't be safe (and is thus impossible // because there is no IntScatterSet constructor that can copy keys from another // container). scatterSet = IntScatterSet.from(1, 1, 2, 3, 5, 0); hashSet = new IntHashSet(scatterSet); } /** * All sets implement the {@link Iterable} interface that returns a "cursor" * object that moves over the container's elements. The cursor object remains * identical for the entire iteration (very little memory overhead). * * The cursor's index points at the underlying buffer's position of a * given element, the cursor's value is the element itself. */ @Test public void cursor() { for (IntCursor c : scatterSet) { printfln("scatterSet contains %d (at buffer index %d)", c.value, c.index); assertThat(c.value).isEqualTo(scatterSet.keys[c.index]); } for (IntCursor c : hashSet) { printfln("hashSet contains %d (at buffer index %d)", c.value, c.index); assertThat(c.value).isEqualTo(hashSet.keys[c.index]); } } /** * A for-each type loop with an anonymous class. */ @Test public void forEachLoop() { scatterSet.forEach(new IntProcedure() { @Override public void apply(int value) { printfln("scatterSet contains %d", value); } }); hashSet.forEach(new IntProcedure() { @Override public void apply(int value) { printfln("hashSet contains %d", value); } }); } } HppcExample_004_IteratingOverMaps.java000066400000000000000000000045741300364116400347650ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import static com.carrotsearch.hppc.examples.Helpers.*; import static org.assertj.core.api.Assertions.*; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.IntLongHashMap; import com.carrotsearch.hppc.IntLongScatterMap; import com.carrotsearch.hppc.cursors.IntLongCursor; import com.carrotsearch.hppc.procedures.IntLongProcedure; /** * Examples of how to iterate over HPPC maps. */ public class HppcExample_004_IteratingOverMaps { public IntLongHashMap hashMap; public IntLongScatterMap scatterMap; @Before public void setup() { // Note that copying the other way around wouldn't be safe (and is thus impossible // because there is no IntLongHashMap constructor that can copy keys from another // container). scatterMap = IntLongScatterMap.from( new int [] {1, 1, 2, 3, 5, 0}, new long [] {1, 2, 3, 4, 5, 6}); hashMap = new IntLongHashMap(scatterMap); } /** * All maps implement the {@link Iterable} interface that returns a "cursor" * object that moves over the container's elements. The cursor object remains * identical for the entire iteration (very little memory overhead). * * The cursor's index points at the underlying buffer's position of a * given element, the cursor's key is the key itself and cursor's value is the * value associated with the key. */ @Test public void cursor() { for (IntLongCursor c : scatterMap) { printfln("scatterMap %d => %d (at buffer index %d)", c.key, c.value, c.index); assertThat(c.value).isEqualTo(scatterMap.values[c.index]); assertThat(c.key).isEqualTo(scatterMap.keys[c.index]); } for (IntLongCursor c : hashMap) { printfln("hashMap %d => %d (at buffer index %d)", c.key, c.value, c.index); assertThat(c.value).isEqualTo(hashMap.values[c.index]); assertThat(c.key).isEqualTo(hashMap.keys[c.index]); } } /** * A for-each type loop with an anonymous class. */ @Test public void forEachLoop() { scatterMap.forEach(new IntLongProcedure() { @Override public void apply(int key, long value) { printfln("scatterMap %d => %d", key, value); } }); hashMap.forEach(new IntLongProcedure() { @Override public void apply(int key, long value) { printfln("hashMap %d => %d", key, value); } }); } } HppcExample_005_ForEachValues.java000066400000000000000000000020141300364116400340350ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import org.junit.Test; import com.carrotsearch.hppc.IntIntHashMap; import com.carrotsearch.hppc.procedures.IntIntProcedure; /** * An example of plucking a value from an anonymous inner class. */ public class HppcExample_005_ForEachValues { @Test public void forEach_FilteredCounting() { // Create a map of key-value pairs. final IntIntHashMap map = new IntIntHashMap(); map.put(1, 2); map.put(2, -5); map.put(3, 10); map.put(4, -1); // And count only non-negative values. Note the "counter" // is physically part of the anonymous inner class but we can // access it because of how forEach is declared (it returns the exact // subclass type of the argument). int count = map.forEach(new IntIntProcedure() { int counter; public void apply(int key, int value) { if (value >= 0) { counter++; } } }).counter; System.out.println("There are " + count + " values that are non-negative."); } } HppcExample_005_IteratingOverObjectBuffers.java000066400000000000000000000016671300364116400366110ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import static com.carrotsearch.hppc.examples.Helpers.*; import org.junit.Test; import com.carrotsearch.hppc.ObjectArrayList; /** * Examples of how to iterate over HPPC lists with object (generic) buffers. */ public class HppcExample_005_IteratingOverObjectBuffers { public final ObjectArrayList list = ObjectArrayList.from(1, 1, 2, 3, 5); /** * Compared to {@link HppcExample_001_IteratingOverLists#directBufferLoop()}, * a direct buffer access for Object types is a bit trickier because the * buffer is actually Object[], not an array of the declared generic type. * * A manual cast to the generic type (for every element) is required. */ @Test public void directBufferLoop() throws Exception { final Object[] buffer = list.buffer; final int size = list.size(); for (int i = 0; i < size; i++) { printfln("list[%d] = %d", i, buffer[i]); } } } HppcExample_006_HashAndScatterMaps.java000066400000000000000000000343531300364116400350370ustar00rootroot00000000000000hppc-0.7.2/hppc-examples/src/test/java/com/carrotsearch/hppc/examplespackage com.carrotsearch.hppc.examples; import java.util.Locale; import java.util.concurrent.TimeUnit; import org.junit.Test; import com.carrotsearch.hppc.HashOrderMixing; import com.carrotsearch.hppc.IntHashSet; import com.carrotsearch.hppc.cursors.IntCursor; /** * Explains the difference between scatter and hash containers. */ @SuppressWarnings("deprecation") public class HppcExample_006_HashAndScatterMaps { @Test public void scatterVsHashDifference() throws Exception { int key; /* * To understand the difference between scatter and hash containers one must first * understand how open addressing with linear conflict resolution works. * * Any associative container has a "key buffer" which is a linear array. When a new * (or existing) key arrives, its "slot" is computed in this linear array (the slot * is an index to the key buffer). The calculation of the slot for a key * can be done in a number of ways, typically it is the hash code of the key modulo * the buffer length. * * In HPPC we can even retrieve the actual "slot" of an existing key. Here is a snippet * that forces the slot (hash) value of a key to become itself, just for demonstration. */ IntHashSet set = new IntHashSet() { @Override protected int hashKey(int key) { return key; } }; key = 0x0002; set.add(key); println("Key 0x%04x is at slot: %d", key, set.indexOf(key)); /* * Prints: * * Key 0x0002 is at slot: 2 * * The problem arises when two keys have the same slot value, the we have to resolve * a conflict; this is typically done by looking for the next available slot (to the right), * again modulo key buffer size. For example this key will conflict with the previous one * because they have the same hash value (modulo buffer size), so it'll be placed at slot * '3', even though it should have been at '2'. */ key = 0x1002; set.add(key); println("Key 0x%04x is at slot: %d", key, set.indexOf(key)); /* * Prints: * * Key 0x1002 is at slot: 3 * * This is called open addressing with linear conflict resolution: * * http://en.wikipedia.org/wiki/Open_addressing * http://en.wikipedia.org/wiki/Linear_probing * * This method of building associative containers has some very nice properties: we can * use CPU caches very effectively (since conflicts scan neighboring elements), we can implement * element removals efficiently (it's basically a shift of other conflicting elements). * * But there is also a problem. What happens if we keep adding conflicting elements over * and over? They will create a long chain of "occuppied" slots and every new insertion * (or lookup) will have an increasingly prohibitive cost until a rehash occurs. * * With our toy example this is quite easy to demonstrate. */ for (int i = 2; i < 10; i++) { key = (i << 12) + 2; set.add(key); println("Key 0x%04x is at slot: %d", key, set.indexOf(key)); } /* * Prints: * * Key 0x2002 is at slot: 4 * Key 0x3002 is at slot: 5 * Key 0x4002 is at slot: 6 * Key 0x5002 is at slot: 7 * Key 0x6002 is at slot: 8 * Key 0x7002 is at slot: 9 * Key 0x8002 is at slot: 10 * Key 0x9002 is at slot: 11 * * We now have a hash map that isn't like a hash map at all -- all keys, instead of being * distributed across the buffer space, are adjacent and grouped. Here is the visualization * of the buffer (a dot is an empty buffer region, numbers indicate progressively * more occupied regions). Let's also expand the buffer a bit to make the point clearer. */ set.ensureCapacity(1000); println("Keys buffer: %s", set.visualizeKeyDistribution(30)); /* * Prints: * * Keys buffer: 1............................. * * which is clearly a nonsensical hash set distribution. A typically deployed trick is to make * some hash function redistribute keys all over the buffer space. Then it's more difficult (but * not impossible) to encounter such bad collision chains. Note how the (linear) keys are * distributed over the buffer space and how the occupancy of the buffer drops upon buffer * expansions. We use a constant hash order mixing strategy here, ignore it for the moment. */ println("Adding keys..."); set = new IntHashSet(0, 0.75d, HashOrderMixing.constant(0xdeadbeef)); key = 0; for (int i = 0; i < 50; i++) { for (int j = 0; j < 1000; j++) { set.add(key++); } println("%5d keys, buffer size: %6d, occupancy: %s", set.size(), set.keys.length, set.visualizeKeyDistribution(30)); } /* * You should see that, with increasing buffer size and the number of keys, they are nearly * uniformly distributed over the buffer space: * * 1000 keys, buffer size: 2049, occupancy: 544355644445654565654666556565 * 2000 keys, buffer size: 4097, occupancy: 545564435485554555744555454565 * 3000 keys, buffer size: 4097, occupancy: 879887778698777787987788687888 * 4000 keys, buffer size: 8193, occupancy: 555555655554565455555554555445 * 5000 keys, buffer size: 8193, occupancy: 667766866675676566666666666666 * 6000 keys, buffer size: 8193, occupancy: 888887987786898677888787787777 * 7000 keys, buffer size: 16385, occupancy: 445454445444444454545444444444 * 8000 keys, buffer size: 16385, occupancy: 555555545554455555655555555455 * ... * 49000 keys, buffer size: 65537, occupancy: 888888878888888888887878888888 * 50000 keys, buffer size: 131073, occupancy: 444444444444444444444444444444 * * The final step causes a rehash so occupancy drops by 50% * (the buffer is doubled). Makes sense. * * There is still a very subtle problem that remains. Consider the following * snippet of code that copies the first 10000 keys from the above container * to another hash container (with the same hashing function). We make the * capacity of "other" identical to the origin set. */ println("Copying to 'other'..."); IntHashSet other = new IntHashSet(set.size(), 0.75d, HashOrderMixing.constant(0xdeadbeef)); int keysToCopy = 10000; for (IntCursor c : set) { if (--keysToCopy < 0) { break; } else { other.add(c.value); } } /* * Now lets check out the distribution of keys in "other". */ println("%5d keys, buffer size: %6d, occupancy: %s", other.size(), other.keys.length, other.visualizeKeyDistribution(30)); /* * The above should print: * * 10000 keys, buffer size: 131073, occupancy: 444443........................ * * Clearly something went terribly wrong -- our keys are grouped again * (although a bit more sparsely). * * The reason for this behavior is pretty obvious: the keys are assigned to slots that are * distributed according to the result of the hash function. But when one iterates over * the elements of a hash set, the keys are traversed in the nearly-sorted order of * these hash values! * * Let it sink in a bit. If we iterate over a hash set, the keys we retrieve are in the * *worst* possible hash-order. * * This can lead to some very dangerous data-related pathologies, like any lookup operation * requiring a long time to find a free or matching slot. * * This is very easy to demonstrate (in a number of ways). The example below * simply recreates a hash container with a high load factor that is on * the verge of expansion. */ // 5000 keys from expanding the buffer... (nearly full capacity). double lf = 0.9; int keys = (int) Math.ceil((1 << 19) / lf) - 5000; set = new IntHashSet(0, lf, HashOrderMixing.none()); for (int i = keys; i-- != 0;) { set.add(i); } other = new IntHashSet(0, lf, HashOrderMixing.none()); int added = 0; long start = System.currentTimeMillis(); long deadline = start + TimeUnit.SECONDS.toMillis(5); for (int v : set.toArray()) { other.add(v); // Print some diagnostics every 10k elements. if ((++added % 10000) == 0) { long round = -(start - (start = System.currentTimeMillis())); println("%6d keys, round: %5d ms, buffer: %s", added, round, other.visualizeKeyDistribution(40)); if (start > deadline) { println("Breaking out forcibly, it'll take forever."); break; // Don't run for too long. } } } /* * Note how add(), that should be a very simple and cheap operation, becomes an * expensive, nearly blocking call. The reason is of course the fully-occupied * front of the hash table; every slot lookup become more and more expensive. * * ... * 340000 keys, round: 1 ms, buffer: 7777777777777777777777777777777777777771 * 345000 keys, round: 1 ms, buffer: 7777777777777777777777777777777777777775 * 350000 keys, round: 4 ms, buffer: 9777777777777777777777777777777777777777 * 355000 keys, round: 29 ms, buffer: X977777777777777777777777777777777777777 * 360000 keys, round: 57 ms, buffer: XXX7777777777777777777777777777777777777 * 365000 keys, round: 85 ms, buffer: XXXX777777777777777777777777777777777777 * 370000 keys, round: 112 ms, buffer: XXXXX77777777777777777777777777777777777 * 375000 keys, round: 141 ms, buffer: XXXXXX8777777777777777777777777777777777 * 380000 keys, round: 169 ms, buffer: XXXXXXX877777777777777777777777777777777 * 385000 keys, round: 196 ms, buffer: XXXXXXXX97777777777777777777777777777777 * 390000 keys, round: 223 ms, buffer: XXXXXXXXX9777777777777777777777777777777 * 395000 keys, round: 250 ms, buffer: XXXXXXXXXXX77777777777777777777777777777 * 400000 keys, round: 278 ms, buffer: XXXXXXXXXXXX7777777777777777777777777777 * 405000 keys, round: 306 ms, buffer: XXXXXXXXXXXXX777777777777777777777777777 * 410000 keys, round: 333 ms, buffer: XXXXXXXXXXXXXX77777777777777777777777777 * 415000 keys, round: 362 ms, buffer: XXXXXXXXXXXXXXX8777777777777777777777777 * 420000 keys, round: 390 ms, buffer: XXXXXXXXXXXXXXXX877777777777777777777777 * 425000 keys, round: 418 ms, buffer: XXXXXXXXXXXXXXXXX97777777777777777777777 * 430000 keys, round: 447 ms, buffer: XXXXXXXXXXXXXXXXXX9777777777777777777777 * 435000 keys, round: 473 ms, buffer: XXXXXXXXXXXXXXXXXXXX77777777777777777777 * 440000 keys, round: 502 ms, buffer: XXXXXXXXXXXXXXXXXXXXX7777777777777777777 * ... * * The examples leading to the above scenario can be multiplied and are not always * easy to predict. There is no perfect way to solve it either, it's an inherent * feature of linear conflict resolution. There are some workarounds that could * be applied to putAll and similar operations (Koloboke and Fastutil implement * them), but there is no way to solve the issue systematically... unless each and * every hash container has a different key distribution. * * Which is exactly what HPPC implements. The two different "flavors" of associative * containers are meant to distinguish between "safe" and "fast" ones. * * Any hash container will, by default, use a fairly unique internal * mixing seed that ensures no two objects have the same distribution of keys. * * Compare the running time (and distributions) from the code below with the one * executed before. */ other = new IntHashSet(0, 0.9d); added = 0; start = System.currentTimeMillis(); for (int v : set.toArray()) { if ((++added % 50000) == 0) { long round = -(start - (start = System.currentTimeMillis())); println("%6d keys, round: %5d ms, buffer: %s", added, round, other.visualizeKeyDistribution(40)); } other.add(v); } /* * Prints: * * 50000 keys, round: 7 ms, buffer: 8888888888888878888888888888888888888888 * 100000 keys, round: 3 ms, buffer: 8888888888888888888888888888888888888888 * 150000 keys, round: 3 ms, buffer: 6666666666666666666666666666666666666666 * 200000 keys, round: 2 ms, buffer: 8888888888888888888888888888888888888888 * 250000 keys, round: 5 ms, buffer: 5555555555555555555555555555555555555555 * 300000 keys, round: 1 ms, buffer: 6666666666666666666666666666666666666666 * 350000 keys, round: 2 ms, buffer: 7777777777777777777777777777777777777777 * 400000 keys, round: 2 ms, buffer: 8888888888888888888888888888888888888888 * 450000 keys, round: 2 ms, buffer: 9999999999999999999999999999999999999999 * 500000 keys, round: 9 ms, buffer: 5555555555555555555555555555555555555555 * 550000 keys, round: 2 ms, buffer: 5555555555555555555555555555555555555555 * 600000 keys, round: 2 ms, buffer: 6666666666666666666666666666666666666666 * 650000 keys, round: 2 ms, buffer: 6666666666666666666666666666666666666666 * * Nothing is free though. There is a small performance penalty (and it * really is very small unless you're dealing with huge collections) associated with * an additional memory read (the mixing seed) and a XOR with the key hash. * * To conclude this example: contrary to hash containers, the "scatter" * variants of maps and sets do *not* implement key remixing; they also implement * a simpler hashing heuristic to speed up slot lookups. * * Scatter containers are still useful (they're faster!) and can be used to implement lookup tables * or counting tables. It is important to remember though to *never* copy the keys of a hash map * or a hash set to a scatter map or set. You can do it the other way around though: * copy keys from a scatter set to a hash set, for instance, because the hash set's mixing * function will make sure they are uniquely redistributed across the buffer space. * * That's it, simple. */ } private void println(String msg, Object... args) { System.out.println(String.format(Locale.ROOT, msg, args)); } } hppc-0.7.2/hppc-template-processor/000077500000000000000000000000001300364116400172305ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/pom.xml000066400000000000000000000070121300364116400205450ustar00rootroot00000000000000 4.0.0 com.carrotsearch hppc-parent 0.7.2 ../pom.xml hppc-template-processor maven-plugin HPPC Template Processor Template Processor and Code Generation for HPPC. com.google.guava guava org.apache.velocity velocity ${version.velocity} org.antlr antlr4 ${version.antlr} org.apache.maven maven-plugin-api ${version.maven.api} org.apache.maven maven-core ${version.maven.api} org.apache.maven.plugin-tools maven-plugin-annotations 3.4 provided com.carrotsearch.randomizedtesting randomizedtesting-runner test junit junit org.assertj assertj-core test org.antlr antlr4-maven-plugin antlr4 antlr4 true org.apache.maven.plugins maven-plugin-plugin 3.4 java-annotations mojo-descriptor process-classes descriptor generated-helpmojo helpmojo eclipse m2e.version false false hppc-0.7.2/hppc-template-processor/src/000077500000000000000000000000001300364116400200175ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/000077500000000000000000000000001300364116400207435ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/000077500000000000000000000000001300364116400221475ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/000077500000000000000000000000001300364116400227255ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/carrotsearch/000077500000000000000000000000001300364116400254055ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/carrotsearch/hppc/000077500000000000000000000000001300364116400263375ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/carrotsearch/hppc/generator/000077500000000000000000000000001300364116400303255ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/carrotsearch/hppc/generator/parser/000077500000000000000000000000001300364116400316215ustar00rootroot00000000000000Java7Lexer.g4000066400000000000000000000213241300364116400337500ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/carrotsearch/hppc/generator/parser/* [The "BSD licence"] Copyright (c) 2013 Terence Parr, Sam Harwell All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ lexer grammar Java7Lexer; channels { CHANNEL_COMMENT } // §3.9 Keywords ABSTRACT : 'abstract'; ASSERT : 'assert'; BOOLEAN : 'boolean'; BREAK : 'break'; BYTE : 'byte'; CASE : 'case'; CATCH : 'catch'; CHAR : 'char'; CLASS : 'class'; CONST : 'const'; CONTINUE : 'continue'; DEFAULT : 'default'; DO : 'do'; DOUBLE : 'double'; ELSE : 'else'; ENUM : 'enum'; EXTENDS : 'extends'; FINAL : 'final'; FINALLY : 'finally'; FLOAT : 'float'; FOR : 'for'; IF : 'if'; GOTO : 'goto'; IMPLEMENTS : 'implements'; IMPORT : 'import'; INSTANCEOF : 'instanceof'; INT : 'int'; INTERFACE : 'interface'; LONG : 'long'; NATIVE : 'native'; NEW : 'new'; PACKAGE : 'package'; PRIVATE : 'private'; PROTECTED : 'protected'; PUBLIC : 'public'; RETURN : 'return'; SHORT : 'short'; STATIC : 'static'; STRICTFP : 'strictfp'; SUPER : 'super'; SWITCH : 'switch'; SYNCHRONIZED : 'synchronized'; THIS : 'this'; THROW : 'throw'; THROWS : 'throws'; TRANSIENT : 'transient'; TRY : 'try'; VOID : 'void'; VOLATILE : 'volatile'; WHILE : 'while'; // §3.10.1 Integer Literals IntegerLiteral : DecimalIntegerLiteral | HexIntegerLiteral | OctalIntegerLiteral | BinaryIntegerLiteral ; fragment DecimalIntegerLiteral : DecimalNumeral IntegerTypeSuffix? ; fragment HexIntegerLiteral : HexNumeral IntegerTypeSuffix? ; fragment OctalIntegerLiteral : OctalNumeral IntegerTypeSuffix? ; fragment BinaryIntegerLiteral : BinaryNumeral IntegerTypeSuffix? ; fragment IntegerTypeSuffix : [lL] ; fragment DecimalNumeral : '0' | NonZeroDigit (Digits? | Underscores Digits) ; fragment Digits : Digit (DigitOrUnderscore* Digit)? ; fragment Digit : '0' | NonZeroDigit ; fragment NonZeroDigit : [1-9] ; fragment DigitOrUnderscore : Digit | '_' ; fragment Underscores : '_'+ ; fragment HexNumeral : '0' [xX] HexDigits ; fragment HexDigits : HexDigit (HexDigitOrUnderscore* HexDigit)? ; fragment HexDigit : [0-9a-fA-F] ; fragment HexDigitOrUnderscore : HexDigit | '_' ; fragment OctalNumeral : '0' Underscores? OctalDigits ; fragment OctalDigits : OctalDigit (OctalDigitOrUnderscore* OctalDigit)? ; fragment OctalDigit : [0-7] ; fragment OctalDigitOrUnderscore : OctalDigit | '_' ; fragment BinaryNumeral : '0' [bB] BinaryDigits ; fragment BinaryDigits : BinaryDigit (BinaryDigitOrUnderscore* BinaryDigit)? ; fragment BinaryDigit : [01] ; fragment BinaryDigitOrUnderscore : BinaryDigit | '_' ; // §3.10.2 Floating-Point Literals FloatingPointLiteral : DecimalFloatingPointLiteral | HexadecimalFloatingPointLiteral ; fragment DecimalFloatingPointLiteral : Digits '.' Digits? ExponentPart? FloatTypeSuffix? | '.' Digits ExponentPart? FloatTypeSuffix? | Digits ExponentPart FloatTypeSuffix? | Digits FloatTypeSuffix ; fragment ExponentPart : ExponentIndicator SignedInteger ; fragment ExponentIndicator : [eE] ; fragment SignedInteger : Sign? Digits ; fragment Sign : [+-] ; fragment FloatTypeSuffix : [fFdD] ; fragment HexadecimalFloatingPointLiteral : HexSignificand BinaryExponent FloatTypeSuffix? ; fragment HexSignificand : HexNumeral '.'? | '0' [xX] HexDigits? '.' HexDigits ; fragment BinaryExponent : BinaryExponentIndicator SignedInteger ; fragment BinaryExponentIndicator : [pP] ; // §3.10.3 Boolean Literals BooleanLiteral : 'true' | 'false' ; // §3.10.4 Character Literals CharacterLiteral : '\'' SingleCharacter '\'' | '\'' EscapeSequence '\'' ; fragment SingleCharacter : ~['\\] ; // §3.10.5 String Literals StringLiteral : '"' StringCharacters? '"' ; fragment StringCharacters : StringCharacter+ ; fragment StringCharacter : ~["\\] | EscapeSequence ; // §3.10.6 Escape Sequences for Character and String Literals fragment EscapeSequence : '\\' [btnfr"'\\] | OctalEscape | UnicodeEscape ; fragment OctalEscape : '\\' OctalDigit | '\\' OctalDigit OctalDigit | '\\' ZeroToThree OctalDigit OctalDigit ; fragment UnicodeEscape : '\\' 'u' HexDigit HexDigit HexDigit HexDigit ; fragment ZeroToThree : [0-3] ; // §3.10.7 The Null Literal NullLiteral : 'null' ; // §3.11 Separators LPAREN : '('; RPAREN : ')'; LBRACE : '{'; RBRACE : '}'; LBRACK : '['; RBRACK : ']'; SEMI : ';'; COMMA : ','; DOT : '.'; // §3.12 Operators ASSIGN : '='; GT : '>'; LT : '<'; BANG : '!'; TILDE : '~'; QUESTION : '?'; COLON : ':'; EQUAL : '=='; LE : '<='; GE : '>='; NOTEQUAL : '!='; AND : '&&'; OR : '||'; INC : '++'; DEC : '--'; ADD : '+'; SUB : '-'; MUL : '*'; DIV : '/'; BITAND : '&'; BITOR : '|'; CARET : '^'; MOD : '%'; ADD_ASSIGN : '+='; SUB_ASSIGN : '-='; MUL_ASSIGN : '*='; DIV_ASSIGN : '/='; AND_ASSIGN : '&='; OR_ASSIGN : '|='; XOR_ASSIGN : '^='; MOD_ASSIGN : '%='; LSHIFT_ASSIGN : '<<='; RSHIFT_ASSIGN : '>>='; URSHIFT_ASSIGN : '>>>='; // §3.8 Identifiers (must appear after all keywords in the grammar) Identifier : JavaLetter JavaLetterOrDigit* ; fragment JavaLetter : [a-zA-Z$_] // these are the "java letters" below 0xFF | // covers all characters above 0xFF which are not a surrogate ~[\u0000-\u00FF\uD800-\uDBFF] {Character.isJavaIdentifierStart(_input.LA(-1))}? | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF [\uD800-\uDBFF] [\uDC00-\uDFFF] {Character.isJavaIdentifierStart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? ; fragment JavaLetterOrDigit : [a-zA-Z0-9$_] // these are the "java letters or digits" below 0xFF | // covers all characters above 0xFF which are not a surrogate ~[\u0000-\u00FF\uD800-\uDBFF] {Character.isJavaIdentifierPart(_input.LA(-1))}? | // covers UTF-16 surrogate pairs encodings for U+10000 to U+10FFFF [\uD800-\uDBFF] [\uDC00-\uDFFF] {Character.isJavaIdentifierPart(Character.toCodePoint((char)_input.LA(-2), (char)_input.LA(-1)))}? ; // // Additional symbols not defined in the lexical specification // AT : '@'; ELLIPSIS : '...'; // // Whitespace and comments // WHITESPACE : [ \t\r\n\u000C]+ -> channel(HIDDEN) ; JAVADOC : '/**' .*? '**/' -> channel(CHANNEL_COMMENT) ; COMMENT : '/*' .*? '*/' -> channel(CHANNEL_COMMENT) ; LINE_COMMENT : '//' ~[\r\n]* -> channel(CHANNEL_COMMENT) ; Java7Parser.g4000066400000000000000000000323241300364116400341270ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/antlr4/com/carrotsearch/hppc/generator/parser/* [The "BSD licence"] Copyright (c) 2013 Terence Parr, Sam Harwell All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ parser grammar Java7Parser; options { tokenVocab=Java7Lexer; } // starting point for parsing a java file compilationUnit : packageDeclaration? importDeclaration* typeDeclaration* EOF ; packageDeclaration : annotation* 'package' qualifiedName ';' ; importDeclaration : 'import' 'static'? qualifiedName ('.' '*')? ';' ; typeDeclaration : classOrInterfaceModifier* classDeclaration | classOrInterfaceModifier* enumDeclaration | classOrInterfaceModifier* interfaceDeclaration | classOrInterfaceModifier* annotationTypeDeclaration | ';' ; modifier : classOrInterfaceModifier | ( 'native' | 'synchronized' | 'transient' | 'volatile' ) ; classOrInterfaceModifier : annotation // class or interface | ( 'public' // class or interface | 'protected' // class or interface | 'private' // class or interface | 'static' // class or interface | 'abstract' // class or interface | 'final' // class only -- does not apply to interfaces | 'strictfp' // class or interface ) ; variableModifier : 'final' | annotation ; classDeclaration : 'class' Identifier typeParameters? ('extends' type)? ('implements' typeList)? classBody ; typeParameters : '<' typeParameter (',' typeParameter)* '>' ; typeParameter : Identifier ('extends' typeBound)? ; typeBound : type ('&' type)* ; enumDeclaration : ENUM Identifier ('implements' typeList)? '{' enumConstants? ','? enumBodyDeclarations? '}' ; enumConstants : enumConstant (',' enumConstant)* ; enumConstant : annotation* Identifier arguments? classBody? ; enumBodyDeclarations : ';' classBodyDeclaration* ; interfaceDeclaration : 'interface' Identifier typeParameters? ('extends' typeList)? interfaceBody ; typeList : type (',' type)* ; classBody : '{' classBodyDeclaration* '}' ; interfaceBody : '{' interfaceBodyDeclaration* '}' ; classBodyDeclaration : ';' | 'static'? block | modifier* memberDeclaration ; memberDeclaration : methodDeclaration | genericMethodDeclaration | fieldDeclaration | constructorDeclaration | genericConstructorDeclaration | interfaceDeclaration | annotationTypeDeclaration | classDeclaration | enumDeclaration ; /* We use rule this even for void methods which cannot have [] after parameters. This simplifies grammar and we can consider void to be a type, which renders the [] matching as a context-sensitive issue or a semantic check for invalid return type after parsing. */ methodDeclaration : (type|'void') Identifier formalParameters ('[' ']')* ('throws' qualifiedNameList)? ( methodBody | ';' ) ; genericMethodDeclaration : typeParameters methodDeclaration ; constructorDeclaration : Identifier formalParameters ('throws' qualifiedNameList)? constructorBody ; genericConstructorDeclaration : typeParameters constructorDeclaration ; fieldDeclaration : type variableDeclarators ';' ; interfaceBodyDeclaration : modifier* interfaceMemberDeclaration | ';' ; interfaceMemberDeclaration : constDeclaration | interfaceMethodDeclaration | genericInterfaceMethodDeclaration | interfaceDeclaration | annotationTypeDeclaration | classDeclaration | enumDeclaration ; constDeclaration : type constantDeclarator (',' constantDeclarator)* ';' ; constantDeclarator : Identifier ('[' ']')* '=' variableInitializer ; // see matching of [] comment in methodDeclaratorRest interfaceMethodDeclaration : (type|'void') Identifier formalParameters ('[' ']')* ('throws' qualifiedNameList)? ';' ; genericInterfaceMethodDeclaration : typeParameters interfaceMethodDeclaration ; variableDeclarators : variableDeclarator (',' variableDeclarator)* ; variableDeclarator : variableDeclaratorId ('=' variableInitializer)? ; variableDeclaratorId : Identifier ('[' ']')* ; variableInitializer : arrayInitializer | expression ; arrayInitializer : '{' (variableInitializer (',' variableInitializer)* (',')? )? '}' ; enumConstantName : Identifier ; type : classOrInterfaceType ('[' ']')* | primitiveType ('[' ']')* ; classOrInterfaceType : identifierTypePair ('.' identifierTypePair )* ; identifierTypePair : Identifier typeArguments? ; primitiveType : 'boolean' | 'char' | 'byte' | 'short' | 'int' | 'long' | 'float' | 'double' ; typeArguments : '<' typeArgument (',' typeArgument)* '>' ; typeArgument : type | '?' (('extends' | 'super') type)? ; qualifiedNameList : qualifiedName (',' qualifiedName)* ; formalParameters : '(' formalParameterList? ')' ; formalParameterList : formalParameter (',' formalParameter)* (',' lastFormalParameter)? | lastFormalParameter ; formalParameter : variableModifier* type variableDeclaratorId ; lastFormalParameter : variableModifier* type '...' variableDeclaratorId ; methodBody : block ; constructorBody : block ; qualifiedName : Identifier ('.' Identifier)* ; literal : IntegerLiteral | FloatingPointLiteral | CharacterLiteral | StringLiteral | BooleanLiteral | 'null' ; // ANNOTATIONS annotation : '@' annotationName ( '(' ( elementValuePairs | elementValue )? ')' )? ; annotationName : qualifiedName ; elementValuePairs : elementValuePair (',' elementValuePair)* ; elementValuePair : Identifier '=' elementValue ; elementValue : expression | annotation | elementValueArrayInitializer ; elementValueArrayInitializer : '{' (elementValue (',' elementValue)*)? (',')? '}' ; annotationTypeDeclaration : '@' 'interface' Identifier annotationTypeBody ; annotationTypeBody : '{' (annotationTypeElementDeclaration)* '}' ; annotationTypeElementDeclaration : modifier* annotationTypeElementRest | ';' // this is not allowed by the grammar, but apparently allowed by the actual compiler ; annotationTypeElementRest : type annotationMethodOrConstantRest ';' | classDeclaration ';'? | interfaceDeclaration ';'? | enumDeclaration ';'? | annotationTypeDeclaration ';'? ; annotationMethodOrConstantRest : annotationMethodRest | annotationConstantRest ; annotationMethodRest : Identifier '(' ')' defaultValue? ; annotationConstantRest : variableDeclarators ; defaultValue : 'default' elementValue ; // STATEMENTS / BLOCKS block : '{' blockStatement* '}' ; blockStatement : localVariableDeclarationStatement | statement | typeDeclaration ; localVariableDeclarationStatement : localVariableDeclaration ';' ; localVariableDeclaration : variableModifier* type variableDeclarators ; statement : block | ASSERT expression (':' expression)? ';' | 'if' parExpression statement ('else' statement)? | 'for' '(' forControl ')' statement | 'while' parExpression statement | 'do' statement 'while' parExpression ';' | 'try' block (catchClause+ finallyBlock? | finallyBlock) | 'try' resourceSpecification block catchClause* finallyBlock? | 'switch' parExpression '{' switchBlockStatementGroup* switchLabel* '}' | 'synchronized' parExpression block | 'return' expression? ';' | 'throw' expression ';' | 'break' Identifier? ';' | 'continue' Identifier? ';' | ';' | statementExpression ';' | Identifier ':' statement ; catchClause : 'catch' '(' variableModifier* catchType Identifier ')' block ; catchType : qualifiedName ('|' qualifiedName)* ; finallyBlock : 'finally' block ; resourceSpecification : '(' resources ';'? ')' ; resources : resource (';' resource)* ; resource : variableModifier* classOrInterfaceType variableDeclaratorId '=' expression ; /** Matches cases then statements, both of which are mandatory. * To handle empty cases at the end, we add switchLabel* to statement. */ switchBlockStatementGroup : switchLabel+ blockStatement+ ; switchLabel : 'case' constantExpression ':' | 'case' enumConstantName ':' | 'default' ':' ; forControl : enhancedForControl | forInit? ';' expression? ';' forUpdate? ; forInit : localVariableDeclaration | expressionList ; enhancedForControl : variableModifier* type variableDeclaratorId ':' expression ; forUpdate : expressionList ; // EXPRESSIONS parExpression : '(' expression ')' ; expressionList : expression (',' expression)* ; statementExpression : expression ; constantExpression : expression ; expression : primary | expression '.' Identifier | expression '.' 'this' | expression '.' 'new' nonWildcardTypeArguments? innerCreator | expression '.' 'super' superSuffix | expression '.' explicitGenericInvocation | expression '[' expression ']' | expression '(' expressionList? ')' | 'new' creator | '(' type ')' expression | expression ('++' | '--') | ('+'|'-'|'++'|'--') expression | ('~'|'!') expression | expression ('*'|'/'|'%') expression | expression ('+'|'-') expression | expression ('<' '<' | '>' '>' '>' | '>' '>') expression | expression ('<=' | '>=' | '>' | '<') expression | expression 'instanceof' type | expression ('==' | '!=') expression | expression '&' expression | expression '^' expression | expression '|' expression | expression '&&' expression | expression '||' expression | expression '?' expression ':' expression | expression ( '=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' | '>>=' | '>>>=' | '<<=' | '%=' ) expression ; primary : '(' expression ')' | 'this' | 'super' | literal | Identifier | type '.' 'class' | 'void' '.' 'class' | nonWildcardTypeArguments (explicitGenericInvocationSuffix | 'this' arguments) ; creator : nonWildcardTypeArguments createdName classCreatorRest | createdName (arrayCreatorRest | classCreatorRest) ; createdName : identifierTypeOrDiamondPair ('.' identifierTypeOrDiamondPair)* | primitiveType ; identifierTypeOrDiamondPair : Identifier typeArgumentsOrDiamond? ; innerCreator : Identifier nonWildcardTypeArgumentsOrDiamond? classCreatorRest ; arrayCreatorRest : '[' ( ']' ('[' ']')* arrayInitializer | expression ']' ('[' expression ']')* ('[' ']')* ) ; classCreatorRest : arguments classBody? ; explicitGenericInvocation : nonWildcardTypeArguments explicitGenericInvocationSuffix ; nonWildcardTypeArguments : '<' typeList '>' ; typeArgumentsOrDiamond : '<' '>' | typeArguments ; nonWildcardTypeArgumentsOrDiamond : '<' '>' | nonWildcardTypeArguments ; superSuffix : arguments | '.' Identifier arguments? ; explicitGenericInvocationSuffix : 'super' superSuffix | Identifier arguments ; arguments : '(' expressionList? ')' ; hppc-0.7.2/hppc-template-processor/src/main/java/000077500000000000000000000000001300364116400216645ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/000077500000000000000000000000001300364116400224425ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/000077500000000000000000000000001300364116400251225ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/000077500000000000000000000000001300364116400260545ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/Intrinsics.java000066400000000000000000000115111300364116400310430ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Objects; /** * Intrinsic methods that are fully functional for the source templates * (generic) and are replaced with low-level corresponding equivalents for the * generated primitive types. * * Whenever there is a generic type on a static method it can be used to parameterize * the given method based on the actual template type. Most intrinsics can guess their * generic template parameter (for example if the template has only one replaceable * type), but sometimes it may be necessary to provide the template type directly. * * This class should not appear in the final distribution (all methods are * replaced in templates. Use forbidden-apis checker to make sure this is the * case. */ public final class Intrinsics { /** * Anything that implements value-equality function as replaced by the * {@link #equals} intrinsic. * * Not a public interface because we want the implementing methods to be * effectively protected, but used for API consistency in templates. */ public interface EqualityFunction { boolean equals(Object v1, Object v2); } /** * Anything that distributes keys by their hash value. * * Not a public interface because we want the implementing methods to be * effectively protected, but used for API consistency in templates. * */ public interface KeyHasher { int hashKey(T key); } /** * Everything static. */ private Intrinsics() {} /** * Returns true if the provided value is an "empty key" marker. * For generic types the empty key is null, for any other type * it is an equivalent of zero. * * Testing for zeros should be compiled into fast machine code. */ public static boolean isEmpty(Object value) { return value == null; } /** * Returns the default "empty key" (null or 0 for * primitive types). */ public static T empty() { return (T) null; } /** * A template cast to the given type T. With type erasure it should work * internally just fine and it simplifies code. The cast will be erased for * primitive types. */ @SuppressWarnings("unchecked") public static T cast(Object value) { return (T) value; } /** * Creates an array for the given template type. */ @SuppressWarnings("unchecked") public static T[] newArray(int arraySize) { return (T[]) new Object[arraySize]; } /** * Compare two keys for equivalence. * * Generic types are compared using the delegate function. * * Primitive types are compared using ==, except for * floating-point types where they're compared by their actual representation * bits as returned from {@link Double#doubleToLongBits(double)} and * {@link Float#floatToIntBits(float)}. */ public static boolean equals(EqualityFunction delegate, Object e1, Object e2) { return delegate.equals(e1, e2); } /** * Compare two keys for equivalence. * * Generic types are compared for null-equivalence or using * {@link Object#equals(Object)}. * * Primitive types are compared using ==, except for * floating-point types where they're compared by their actual representation * bits as returned from {@link Double#doubleToLongBits(double)} and * {@link Float#floatToIntBits(float)}. */ public static boolean equals(Object e1, Object e2) { return Objects.equals(e1, e2); } /** * An intrinsic that is replaced with plain addition of arguments for * primitive template types. Invalid for non-number generic types. */ @SuppressWarnings("unchecked") public static T add(T op1, T op2) { if (op1.getClass() != op2.getClass()) { throw new RuntimeException("Arguments of different classes: " + op1 + " " + op2); } if (Byte.class.isInstance(op1)) { return (T)(Byte)(byte)(((Byte) op1).byteValue() + ((Byte) op2).byteValue()); } if (Short.class.isInstance(op1)) { return (T)(Short)(short)(((Short) op1).shortValue() + ((Short) op2).shortValue()); } if (Character.class.isInstance(op1)) { return (T)(Character)(char)(((Character) op1).charValue() + ((Character) op2).charValue()); } if (Integer.class.isInstance(op1)) { return (T)(Integer)(((Integer) op1).intValue() + ((Integer) op2).intValue()); } if (Float.class.isInstance(op1)) { return (T)(Float)(((Float) op1).floatValue() + ((Float) op2).floatValue()); } if (Long.class.isInstance(op1)) { return (T)(Long)(((Long) op1).longValue() + ((Long) op2).longValue()); } if (Double.class.isInstance(op1)) { return (T)(Double)(((Double) op1).doubleValue() + ((Double) op2).doubleValue()); } throw new UnsupportedOperationException("Invalid for arbitrary types: " + op1 + " " + op2); } } hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/000077500000000000000000000000001300364116400300425ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/AddSourceMojo.java000066400000000000000000000016301300364116400334030ustar00rootroot00000000000000package com.carrotsearch.hppc.generator; import java.io.File; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; /** * Adds additional source directories to test or main sources. */ @Mojo(name = "add-source", defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true, requiresProject = true) public class AddSourceMojo extends AbstractMojo { @Parameter( required = true ) public File[] sources; @Parameter(property = "project", readonly = true, required = true) private MavenProject project; public void execute() { for (File source : sources) { this.project.addCompileSourceRoot(source.getAbsolutePath()); } } }AddTestSourceMojo.java000066400000000000000000000016521300364116400341700ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generatorpackage com.carrotsearch.hppc.generator; import java.io.File; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; /** * Adds additional source directories to test or main sources. */ @Mojo(name = "add-test-source", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES, threadSafe = true, requiresProject = true) public class AddTestSourceMojo extends AbstractMojo { @Parameter( required = true ) public File[] sources; @Parameter(property = "project", readonly = true, required = true) private MavenProject project; public void execute() { for (File source : sources) { this.project.addTestCompileSourceRoot(source.getAbsolutePath()); } } }IntrinsicMethod.java000066400000000000000000000004721300364116400337340ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generatorpackage com.carrotsearch.hppc.generator; import java.util.ArrayList; import java.util.regex.Matcher; /** * Intrinsic method invocation. */ public interface IntrinsicMethod { void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList params); } hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/OutputFile.java000066400000000000000000000003541300364116400330070ustar00rootroot00000000000000package com.carrotsearch.hppc.generator; import java.nio.file.Path; class OutputFile { public final Path path; public boolean upToDate; public OutputFile(Path target) { this.path = target.toAbsolutePath().normalize(); } }hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/TemplateFile.java000066400000000000000000000004031300364116400332550ustar00rootroot00000000000000package com.carrotsearch.hppc.generator; import java.nio.file.Path; class TemplateFile { public final Path path; public TemplateFile(Path path) { this.path = path; } public String getFileName() { return path.getFileName().toString(); } }TemplateOptions.java000066400000000000000000000044001300364116400337530ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generatorpackage com.carrotsearch.hppc.generator; import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import com.google.common.base.Preconditions; /** * Template options for velocity directives in templates. */ public class TemplateOptions { public static final String TEMPLATE_FILE_TOKEN = "__TEMPLATE_SOURCE__"; private boolean ignore; public Type ktype; public Type vtype; public Path templateFile; public TemplateOptions(Type ktype) { this(ktype, null); } public TemplateOptions(Type ktype, Type vtype) { this.ktype = ktype; this.vtype = vtype; } public void setIgnored(boolean ignore) { this.ignore = ignore; } public boolean isIgnored() { return ignore; } public boolean isKTypePrimitive() { return ktype != Type.GENERIC; } public boolean isVTypePrimitive() { return getVType() != Type.GENERIC; } public boolean isKTypeGeneric() { return ktype == Type.GENERIC; } public boolean isVTypeGeneric() { return getVType() == Type.GENERIC; } public boolean isAllGeneric() { return isKTypeGeneric() && isVTypeGeneric(); } public boolean isAnyPrimitive() { return isKTypePrimitive() || isVTypePrimitive(); } public boolean isAnyGeneric() { return isKTypeGeneric() || (hasVType() && isVTypeGeneric()); } public boolean hasVType() { return vtype != null; } public boolean hasKType() { return true; } public Type getKType() { Preconditions.checkArgument(hasKType(), "Template does not specify KType."); return ktype; } public Type getVType() { Preconditions.checkArgument(hasVType(), "Template does not specify VType."); return vtype; } /* * Returns the current time in ISO format. */ public String getTimeNow() { SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.ROOT); return format.format(new Date()); } public String getTemplateFile() { return templateFile.getFileName().toString(); } public String getGeneratedAnnotation() { return String.format(Locale.ROOT, "@javax.annotation.Generated(\n" + " date = \"%s\",\n" + " value = \"%s\")", getTimeNow(), TEMPLATE_FILE_TOKEN); } }TemplateProcessorMojo.java000066400000000000000000000342151300364116400351330ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generatorpackage com.carrotsearch.hppc.generator; import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.nio.charset.StandardCharsets; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.collections.ExtendedProperties; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.velocity.VelocityContext; import org.apache.velocity.runtime.RuntimeConstants; import org.apache.velocity.runtime.RuntimeInstance; import org.apache.velocity.runtime.log.NullLogChute; import com.carrotsearch.hppc.generator.intrinsics.Add; import com.carrotsearch.hppc.generator.intrinsics.Cast; import com.carrotsearch.hppc.generator.intrinsics.Empty; import com.carrotsearch.hppc.generator.intrinsics.Equals; import com.carrotsearch.hppc.generator.intrinsics.IsEmpty; import com.carrotsearch.hppc.generator.intrinsics.NewArray; import com.carrotsearch.hppc.generator.parser.SignatureProcessor; import com.google.common.base.Stopwatch; /** * Maven mojo applying preprocessor templates. */ @Mojo(name = "template-processor", defaultPhase = LifecyclePhase.GENERATE_SOURCES, threadSafe = true, requiresProject = true) public class TemplateProcessorMojo extends AbstractMojo { private final HashMap intrinsics; { intrinsics = new HashMap<>(); intrinsics.put("empty", new Empty()); intrinsics.put("isEmpty", new IsEmpty()); intrinsics.put("newArray", new NewArray()); intrinsics.put("cast", new Cast()); intrinsics.put("add", new Add()); intrinsics.put("equals", new Equals()); } @Parameter(property = "project", readonly = true, required = true) private MavenProject project; @Parameter(defaultValue = "false") public boolean verbose; @Parameter(property = "template.processor.incremental", defaultValue = "true") public boolean incremental; @Parameter(required = true) public String attachSources; @Parameter(required = true) public File templatesDir; @Parameter(required = true) public File outputDir; private RuntimeInstance velocity; private Path templatesPath; private Path outputPath; @Override public void execute() throws MojoExecutionException { try { execute0(); } catch (IOException e) { throw new MojoExecutionException("Couldn't process templates.", e); } } private void execute0() throws IOException, MojoExecutionException { velocity = new RuntimeInstance(); final ExtendedProperties p = new ExtendedProperties(); p.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, NullLogChute.class.getName()); p.setProperty(RuntimeConstants.SET_NULL_ALLOWED, "false"); velocity.setConfiguration(p); // Cater for Eclipse's insanity -- we can't just specify a separate launch config that'd run // after a manual 'clean'. String eclipseLauncherBuildType = System.getenv("ECLIPSE_BUILD_TYPE"); if ("full".equals(eclipseLauncherBuildType)) { if (incremental) { getLog().info("Disabling incremental processing (Eclipse built type: " + eclipseLauncherBuildType + ")"); incremental = false; } } this.templatesPath = templatesDir.toPath().toAbsolutePath().normalize(); this.outputPath = outputDir.toPath().toAbsolutePath().normalize(); Path basedir = project.getBasedir().toPath().toAbsolutePath().normalize(); getLog().info(String.format(Locale.ROOT, "Processing templates from %s => %s", basedir.relativize(templatesPath), basedir.relativize(outputPath))); final Stopwatch sw = Stopwatch.createStarted(); final List templates = collectTemplateFiles(templatesPath); final List generated = processTemplates(templates); final List removed = removeOtherFiles(outputPath, generated); int updated = generated.size(); for (OutputFile o : generated) { if (o.upToDate) updated--; } getLog().info(String.format(Locale.ROOT, "Processed %d templates in %.2f sec. (%d output files: %d updated, %d deleted).", templates.size(), sw.elapsed(TimeUnit.MILLISECONDS) / 1000.0f, generated.size(), updated, removed.size())); switch (attachSources.toLowerCase(Locale.ROOT)) { case "main": project.addCompileSourceRoot(outputPath.toString()); break; case "test": project.addTestCompileSourceRoot(outputPath.toString()); break; default: throw new MojoExecutionException("Invalid source attachment option ('source' or 'test' allowed): " + attachSources); } } private List removeOtherFiles(Path outputPath, List keep) throws IOException { final Set keepPaths = new HashSet<>(); for (OutputFile o : keep) { keepPaths.add(o.path.toRealPath().toString()); } final List toRemove = new ArrayList<>(); Files.walkFileTree(outputPath, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { path = path.toRealPath(); if (!keepPaths.contains(path.toString())) { toRemove.add(path); } return FileVisitResult.CONTINUE; } }); for (Path p : toRemove) { verboseLog("Deleting: " + p.toString()); Files.delete(p); } return toRemove; } private void verboseLog(String message) { if (verbose) { getLog().info(message); } else { getLog().debug(message); } } /** * Apply templates to .ktype files (single-argument). */ private List processTemplates(List inputs) throws IOException { List outputs = new ArrayList<>(); for (TemplateFile f : inputs) { String fileName = f.getFileName(); if (!fileName.contains("VType") && fileName.contains("KType")) { for (Type ktype : Type.values()) { TemplateOptions options = new TemplateOptions(ktype); options.templateFile = f.path; generate(f, outputs, options); } } if (fileName.contains("KTypeVType")) { for (Type ktype : Type.values()) { for (Type vtype : Type.values()) { TemplateOptions options = new TemplateOptions(ktype, vtype); options.templateFile = f.path; generate(f, outputs, options); } } } } return outputs; } private Stopwatch timeVelocity = Stopwatch.createUnstarted(); private Stopwatch timeIntrinsics = Stopwatch.createUnstarted(); private Stopwatch timeTypeClassRefs = Stopwatch.createUnstarted(); private Stopwatch timeComments = Stopwatch.createUnstarted(); /** * Apply templates. */ private void generate(TemplateFile input, List outputs, TemplateOptions templateOptions) throws IOException { final String targetFileName = targetFileName(templatesPath.relativize(input.path).toString(), templateOptions); final OutputFile output = new OutputFile(outputPath.resolve(targetFileName).toAbsolutePath().normalize()); if (incremental && Files.exists(output.path) && Files.getLastModifiedTime(output.path).toMillis() >= Files.getLastModifiedTime(input.path).toMillis()) { // No need to re-render but mark as generated. output.upToDate = true; outputs.add(output); return; } String template = new String(Files.readAllBytes(input.path), StandardCharsets.UTF_8); timeVelocity.start(); template = filterVelocity(input, template, templateOptions); timeVelocity.stop(); // Check if template requested ignoring a given type combination. if (templateOptions.isIgnored()) { return; } getLog().debug("Processing: " + input.getFileName() + " => " + output.path); try { timeIntrinsics.start(); template = filterIntrinsics(template, templateOptions); timeIntrinsics.stop(); timeComments.start(); template = filterComments(template); timeComments.stop(); timeTypeClassRefs.start(); template = filterTypeClassRefs(template, templateOptions); template = filterStaticTokens(template, templateOptions); timeTypeClassRefs.stop(); } catch (RuntimeException e) { getLog().error("Error processing: " + input.getFileName() + " => " + output.path + ":\n\t" + e.getMessage()); throw e; } Files.createDirectories(output.path.getParent()); Files.write(output.path, template.getBytes(StandardCharsets.UTF_8)); outputs.add(output); } private String filterStaticTokens(String template, TemplateOptions templateOptions) { return template.replace(TemplateOptions.TEMPLATE_FILE_TOKEN, templateOptions.getTemplateFile()); } private String filterIntrinsics(String input, TemplateOptions templateOptions) { // TODO: this should be eventually moved to AST processor. Pattern p = Pattern.compile( "(Intrinsics.\\s*)" + "(<(?[^>]+)>\\s*)?" + "(?[a-zA-Z0-9]+)", Pattern.MULTILINE | Pattern.DOTALL); StringBuilder sb = new StringBuilder(); while (true) { Matcher m = p.matcher(input); if (m.find()) { sb.append(input.substring(0, m.start())); String method = m.group("method"); int bracketCount = 0; int last = m.end() + 1; ArrayList params = new ArrayList<>(); outer: for (int i = m.end(); i < input.length(); i++) { switch (input.charAt(i)) { case '(': bracketCount++; break; case ')': bracketCount--; if (bracketCount == 0) { if (last != i) { params.add(input.substring(last, i).trim()); } input = input.substring(i + 1); break outer; } break; case ',': if (bracketCount == 1) { params.add(input.substring(last, i)); last = i + 1; } break; } } getLog().debug("Intrinsic call: " + m.group() + "; method: " + method + ", generic: " + m.group("generic") + ", args: " + params); // Allow recursion of intrinsics into arguments. for (int i = 0; i < params.size(); i++) { params.set(i, filterIntrinsics(params.get(i), templateOptions)); } IntrinsicMethod im = intrinsics.get(method); if (im == null) { throw new RuntimeException(String.format(Locale.ROOT, "Unknown intrinsic method '%s' in call: %s", method, m.group())); } else { im.invoke(m, sb, templateOptions, m.group("generic"), params); } } else { sb.append(input); break; } } return sb.toString(); } private String filterComments(String input) { Pattern p = Pattern.compile("(/\\*!)|(!\\*/)", Pattern.MULTILINE | Pattern.DOTALL); return p.matcher(input).replaceAll(""); } private String filterTypeClassRefs(String input, TemplateOptions options) { try { SignatureProcessor signatureProcessor = new SignatureProcessor(input); return signatureProcessor.process(options); } catch (Exception e) { getLog().error("Signature processor failure: " + options.getTemplateFile(), e); throw new RuntimeException(e); } } /** * Apply velocity to the input. */ private String filterVelocity(TemplateFile f, String template, TemplateOptions options) { final VelocityContext ctx = new VelocityContext(); ctx.put("TemplateOptions", options); ctx.put("true", true); ctx.put("templateOnly", false); ctx.put("false", false); StringWriter sw = new StringWriter(); velocity.evaluate(ctx, sw, f.getFileName(), template); return sw.toString(); } private String targetFileName(String relativePath, TemplateOptions templateOptions) { if (templateOptions.hasVType()) { relativePath = relativePath.replace("KTypeVType", templateOptions.getKType().getBoxedType() + templateOptions.getVType().getBoxedType()); } return relativePath.replace("KType", templateOptions.getKType().getBoxedType()); } private List scanFilesMatching(Path dir, String matchPattern) throws IOException { final List paths = new ArrayList<>(); if (Files.isDirectory(dir)) { final PathMatcher matcher = dir.getFileSystem().getPathMatcher(matchPattern); Files.walkFileTree(dir, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException { if (matcher.matches(path)) { paths.add(path); } return FileVisitResult.CONTINUE; } }); } return paths; } /** * Collect all template files from this and subdirectories. */ private List collectTemplateFiles(Path dir) throws IOException { final List paths = new ArrayList<>(); for (Path path : scanFilesMatching(dir, "glob:**.java")) { paths.add(new TemplateFile(path)); } return paths; } } hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/Type.java000066400000000000000000000011221300364116400316220ustar00rootroot00000000000000package com.carrotsearch.hppc.generator; import java.util.Locale; public enum Type { GENERIC, BYTE, CHAR, SHORT, INT, FLOAT, LONG, DOUBLE; public String getBoxedType() { if (this == GENERIC) { return "Object"; } else { String boxed = name().toLowerCase(); return Character.toUpperCase(boxed.charAt(0)) + boxed.substring(1); } } public String getType() { if (this == GENERIC) { return "Object"; } else { return name().toLowerCase(Locale.ROOT); } } public boolean isGeneric() { return this == GENERIC; } }hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsics/000077500000000000000000000000001300364116400322275ustar00rootroot00000000000000AbstractIntrinsicMethod.java000066400000000000000000000052011300364116400376000ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsicspackage com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.Locale; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.IntrinsicMethod; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.Type; abstract class AbstractIntrinsicMethod implements IntrinsicMethod { protected static Type inferTemplateType(Matcher m, TemplateOptions templateOptions, String templateCast) { templateCast = inferTemplateCastName(m, templateOptions, templateCast); Type type; switch (templateCast) { case "KType": if (!templateOptions.hasKType()) { throw new RuntimeException(format( "Template cast requires %s but the template does not have it: %s", templateCast, m.group())); } type = templateOptions.getKType(); break; case "VType": if (!templateOptions.hasVType()) { throw new RuntimeException(format( "Template cast requires %s but the template does not have it: %s", templateCast, m.group())); } type = templateOptions.getVType(); break; default: throw new RuntimeException(format( "Ukrecognized template cast to %s in: %s", templateCast, m.group())); } return type; } protected static String inferTemplateCastName(Matcher m, TemplateOptions templateOptions, String templateCast) { if (templateCast == null || templateCast.isEmpty()) { if (templateOptions.hasKType() && !templateOptions.hasVType()) { templateCast = "KType"; } else if (templateOptions.hasVType() && !templateOptions.hasKType()) { templateCast = "VType"; } } if (templateCast == null) { throw new RuntimeException(format( "Couldn't infer template type of: %s", m.group())); } return templateCast; } protected static void expectArgumentCount(Matcher m, ArrayList arguments, int expectedCount) { if (arguments.size() != expectedCount) { throw new RuntimeException(format("Expected exactly %d arguments but was %d: %s(%s)", expectedCount, arguments.size(), m.group(), arguments)); } } protected static String format(String format, Object... args) { return String.format(Locale.ROOT, format, args); } protected RuntimeException unreachable() { throw new RuntimeException("Unreachable block reached."); } } hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsics/Add.java000066400000000000000000000013241300364116400335620ustar00rootroot00000000000000package com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.Type; public class Add extends AbstractIntrinsicMethod { @Override public void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList params) { expectArgumentCount(m, params, 2); Type type = inferTemplateType(m, templateOptions, genericCast); if (type.isGeneric()) { throw new RuntimeException("Can't add generic types: " + m.group()); } sb.append(String.format("((%1$s) + (%2$s))", params.toArray())); } } Cast.java000066400000000000000000000025541300364116400337130ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsicspackage com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.TemplateOptions; public class Cast extends AbstractIntrinsicMethod { @Override public void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList params) { expectArgumentCount(m, params, 1); String cast = inferTemplateCastName(m, templateOptions, genericCast); switch (genericCast) { case "KType[]": case "KType": if (!templateOptions.hasKType()) { throw new RuntimeException("KType is not available for casting in this template?: " + m.group()); } if (templateOptions.isKTypeGeneric()) { cast = "(" + genericCast + ")"; } else { cast = ""; // dropped } break; case "VType[]": case "VType": if (!templateOptions.hasVType()) { throw new RuntimeException("VType is not available for casting in this template?: " + m.group()); } if (templateOptions.isVTypeGeneric()) { cast = "(" + genericCast + ")"; } else { cast = ""; // dropped } break; default: throw unreachable(); } sb.append(cast + " " + params.get(0)); } } Empty.java000066400000000000000000000020631300364116400341120ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsicspackage com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.TemplateOptions; public class Empty extends AbstractIntrinsicMethod { @Override public void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList params) { expectArgumentCount(m, params, 0); switch (inferTemplateType(m, templateOptions, genericCast)) { case GENERIC: sb.append("null"); break; case FLOAT: sb.append("0f"); break; case DOUBLE: sb.append("0d"); break; case BYTE: sb.append("((byte) 0)"); break; case CHAR: sb.append("((char) 0)"); break; case SHORT: sb.append("((short) 0)"); break; case INT: sb.append("0"); break; case LONG: sb.append("0L"); break; default: throw unreachable(); } } } Equals.java000066400000000000000000000030711300364116400342460ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsicspackage com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.Type; public class Equals extends AbstractIntrinsicMethod { @Override public void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList arguments) { if (arguments.size() != 2 && arguments.size() != 3) { throw new RuntimeException(format("Expected exactly 2 or 3 arguments but was %d: %s(%s)", arguments.size(), m.group(), arguments)); } String v1 = arguments.remove(arguments.size() - 1); String v2 = arguments.remove(arguments.size() - 1); Type type = super.inferTemplateType(m, templateOptions, genericCast); switch (type) { case GENERIC: String comparer = arguments.isEmpty() ? "java.util.Objects" : arguments.get(0); sb.append(format("%s.equals(%s, %s)", comparer, v1, v2)); break; case FLOAT: sb.append(format("(Float.floatToIntBits(%s) == Float.floatToIntBits(%s))", v1, v2)); break; case DOUBLE: sb.append(format("(Double.doubleToLongBits(%s) == Double.doubleToLongBits(%s))", v1, v2)); break; case BYTE: case SHORT: case CHAR: case INT: case LONG: sb.append(format("((%s) == (%s))", v1, v2)); break; default: throw unreachable(); } } } IsEmpty.java000066400000000000000000000020311300364116400344010ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsicspackage com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.TemplateOptions; public class IsEmpty extends AbstractIntrinsicMethod { @Override public void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList params) { expectArgumentCount(m, params, 1); switch (inferTemplateType(m, templateOptions, genericCast)) { case GENERIC: sb.append(format("((%s) == null)", params.get(0))); break; case FLOAT: sb.append(format("(Float.floatToIntBits(%s) == 0)", params.get(0))); break; case DOUBLE: sb.append(format("(Double.doubleToLongBits(%s) == 0)", params.get(0))); break; case BYTE: case CHAR: case INT: case LONG: case SHORT: sb.append(format("((%s) == 0)", params.get(0))); break; default: throw unreachable(); } } } NewArray.java000066400000000000000000000020321300364116400345400ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/intrinsicspackage com.carrotsearch.hppc.generator.intrinsics; import java.util.ArrayList; import java.util.regex.Matcher; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.Type; public class NewArray extends AbstractIntrinsicMethod { @Override public void invoke(Matcher m, StringBuilder sb, TemplateOptions templateOptions, String genericCast, ArrayList params) { expectArgumentCount(m, params, 1); genericCast = inferTemplateCastName(m, templateOptions, genericCast); Type type = inferTemplateType(m, templateOptions, genericCast); switch (type) { case GENERIC: sb.append(format("((%s[]) new Object [%s])", genericCast, params.get(0))); break; case BYTE: case CHAR: case DOUBLE: case FLOAT: case INT: case LONG: case SHORT: sb.append(format("(new %s [%s])", type.getType(), params.get(0))); break; default: throw unreachable(); } } } hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/parser/000077500000000000000000000000001300364116400313365ustar00rootroot00000000000000Channels.java000066400000000000000000000003711300364116400336560ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/parserpackage com.carrotsearch.hppc.generator.parser; class Channels { private Channels() {} public final static int LINE_COMMENT = 1000; public final static int BLOCK_COMMENT = 1001; public final static int JAVADOC_COMMENT = 1002; } Replacement.java000066400000000000000000000011331300364116400343570ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/parserpackage com.carrotsearch.hppc.generator.parser; import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.tree.SyntaxTree; /** */ final class Replacement { public final Interval interval; public final String replacement; public Replacement(Interval interval, String replacement) { this.interval = interval; this.replacement = replacement; } public Replacement(SyntaxTree ctx, String replacement) { this(ctx.getSourceInterval(), replacement); } @Override public String toString() { return interval + " => " + replacement; } } SignatureProcessor.java000066400000000000000000000076251300364116400357750ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/parserpackage com.carrotsearch.hppc.generator.parser; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.BailErrorStrategy; import org.antlr.v4.runtime.BufferedTokenStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.Lexer; import org.antlr.v4.runtime.Token; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.parser.Java7Parser.CompilationUnitContext; /** */ public class SignatureProcessor { final Java7Parser parser; final CommonTokenStream tokenStream; final CompilationUnitContext unitContext; public SignatureProcessor(String input) { Lexer lexer = new Java7Lexer(new ANTLRInputStream(input)); tokenStream = new CommonTokenStream(lexer); parser = new Java7Parser(tokenStream); parser.setErrorHandler(new BailErrorStrategy()); unitContext = parser.compilationUnit(); } /* * */ public String process(TemplateOptions templateOptions) throws IOException { return applyReplacements(findReplacements(templateOptions), templateOptions); } /* * */ private List findReplacements(TemplateOptions templateOptions) { List replacements = unitContext.accept(new SignatureReplacementVisitor(templateOptions, this)); return replacements; } /* * */ private String applyReplacements(List replacements, TemplateOptions options) throws IOException { StringWriter sw = new StringWriter(); reconstruct(sw, tokenStream, 0, tokenStream.size() - 1, replacements, options); return sw.toString(); } /** * Process references inside comment blocks, javadocs, etc. */ private String processComment(String text, TemplateOptions options) { if (options.hasKType()) { text = text.replaceAll("(KType)(?=\\p{Lu})", options.getKType().getBoxedType()); text = text.replace("KType", options.getKType().getType()); } if (options.hasVType()) { text = text.replaceAll("(VType)(?=\\p{Lu})", options.getVType().getBoxedType()); text = text.replace("VType", options.getVType().getType()); } return text; } /* * */ T reconstruct( T sw, BufferedTokenStream tokenStream, int from, int to, Collection replacements, TemplateOptions templateOptions) throws IOException { ArrayList sorted = new ArrayList<>(replacements); Collections.sort(sorted, new Comparator() { @Override public int compare(Replacement a, Replacement b) { return Integer.compare(a.interval.a, b.interval.b); } }); for (int i = 1; i < sorted.size(); i++) { Replacement previous = sorted.get(i - 1); Replacement current = sorted.get(i); if (!previous.interval.startsBeforeDisjoint(current.interval)) { throw new RuntimeException("Overlapping intervals: " + previous + " " + current); } } int left = from; for (Replacement r : sorted) { int right = r.interval.a; for (int i = left; i < right; i++) { sw.append(tokenText(templateOptions, tokenStream.get(i))); } sw.append(r.replacement); left = r.interval.b + 1; } for (int i = left; i < to; i++) { sw.append(tokenText(templateOptions, tokenStream.get(i))); } return sw; } protected String tokenText(TemplateOptions templateOptions, Token token) { String text = token.getText(); if (token.getChannel() == Java7Lexer.CHANNEL_COMMENT) { text = processComment(text, templateOptions); } return text; } } SignatureReplacementVisitor.java000066400000000000000000000425201300364116400376260ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/main/java/com/carrotsearch/hppc/generator/parserpackage com.carrotsearch.hppc.generator.parser; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Deque; import java.util.List; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.misc.Interval; import org.antlr.v4.runtime.tree.TerminalNode; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.Type; import com.carrotsearch.hppc.generator.parser.Java7Parser.ClassDeclarationContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.ClassOrInterfaceTypeContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.ConstructorDeclarationContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.CreatedNameContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.GenericMethodDeclarationContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.IdentifierTypeOrDiamondPairContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.IdentifierTypePairContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.InterfaceDeclarationContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.MethodDeclarationContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.PrimaryContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.QualifiedNameContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.TypeArgumentContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.TypeArgumentsContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.TypeBoundContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.TypeContext; import com.carrotsearch.hppc.generator.parser.Java7Parser.TypeParameterContext; class SignatureReplacementVisitor extends Java7ParserBaseVisitor> { private final static List NONE = Collections.emptyList(); private final TemplateOptions templateOptions; private final SignatureProcessor processor; public SignatureReplacementVisitor(TemplateOptions templateOptions, SignatureProcessor processor) { this.templateOptions = templateOptions; this.processor = processor; } private static class TypeBound { private final String originalBound; private final Type targetType; public TypeBound(Type targetType, String originalBound) { this.targetType = targetType; this.originalBound = originalBound; } public Type templateBound() { checkNotNull(targetType, "Target not a template bound: " + originalBound); return targetType; } public boolean isTemplateType() { return targetType != null; } public String originalBound() { return originalBound; } public String getBoxedType() { return templateBound().getBoxedType(); } } private TypeBound typeBoundOf(TypeParameterContext c) { String symbol = c.Identifier().toString(); switch (symbol) { case "KType": return new TypeBound(templateOptions.getKType(), c.getText()); case "VType": return new TypeBound(templateOptions.getVType(), c.getText()); default: return new TypeBound(null, c.getText()); } } private TypeBound typeBoundOf(TypeArgumentContext c, Deque wildcards) { if (c.getText().equals("?")) { return new TypeBound(wildcards.removeFirst(), c.getText()); } TypeBound t = typeBoundOf(c.type()); if (t.isTemplateType()) { return new TypeBound(t.templateBound(), getSourceText(c)); } else { return new TypeBound(null, getSourceText(c)); } } private String getSourceText(ParserRuleContext c) { return this.processor.tokenStream.getText(c.getSourceInterval()); } private TypeBound typeBoundOf(TypeContext c) { if (c.primitiveType() != null) { return new TypeBound(null, c.getText()); } else { TypeBound t = typeBoundOf(c.classOrInterfaceType()); if (t.isTemplateType()) { return new TypeBound(t.templateBound(), c.getText()); } else { return new TypeBound(null, c.getText()); } } } private TypeBound typeBoundOf(ClassOrInterfaceTypeContext c) { checkArgument(c.identifierTypePair().size() == 1, "Unexpected typeBoundOf context: " + c.getText()); for (IdentifierTypePairContext p : c.identifierTypePair()) { switch (p.Identifier().getText()) { case "KType": return new TypeBound(templateOptions.getKType(), p.getText()); case "VType": return new TypeBound(templateOptions.getVType(), p.getText()); } } return new TypeBound(null, c.getText()); } public List visitClassDeclaration(ClassDeclarationContext ctx) { List result = new ArrayList<>(super.visitClassDeclaration(ctx)); String className = ctx.Identifier().getText(); if (isTemplateIdentifier(className) || true) { List typeBounds = new ArrayList<>(); if (ctx.typeParameters() != null) { for (TypeParameterContext c : ctx.typeParameters().typeParameter()) { typeBounds.add(typeBoundOf(c)); } result.add(new Replacement(ctx.typeParameters(), toString(typeBounds))); } int typeBoundIndex = 0; if (className.contains("KType")) { className = className.replace("KType", typeBounds.get(typeBoundIndex++).templateBound().getBoxedType()); } if (className.contains("VType")) { className = className.replace("VType", typeBounds.get(typeBoundIndex++).templateBound().getBoxedType()); } result.add(new Replacement(ctx.Identifier(), className)); } return result; } @Override public List visitInterfaceDeclaration(InterfaceDeclarationContext ctx) { List result = super.visitInterfaceDeclaration(ctx); String className = ctx.Identifier().getText(); if (isTemplateIdentifier(className)) { List typeBounds = new ArrayList<>(); for (TypeParameterContext c : ctx.typeParameters().typeParameter()) { typeBounds.add(typeBoundOf(c)); } Replacement replaceGenericTypes = new Replacement(ctx.typeParameters(), toString(typeBounds)); int typeBoundIndex = 0; if (className.contains("KType")) { className = className.replace("KType", typeBounds.get(typeBoundIndex++).templateBound().getBoxedType()); } if (className.contains("VType")) { className = className.replace("VType", typeBounds.get(typeBoundIndex++).templateBound().getBoxedType()); } Replacement replaceIdentifier = new Replacement(ctx.Identifier(), className); result = new ArrayList<>(result); result.addAll(Arrays.asList( replaceIdentifier, replaceGenericTypes)); } return result; } @Override public List visitConstructorDeclaration(ConstructorDeclarationContext ctx) { return processIdentifier(ctx.Identifier(), super.visitConstructorDeclaration(ctx)); } @Override public List visitPrimary(PrimaryContext ctx) { TerminalNode identifier = ctx.Identifier(); if (identifier != null && isTemplateIdentifier(identifier.getText())) { return processIdentifier(identifier, NONE); } else { return super.visitPrimary(ctx); } } @Override public List visitGenericMethodDeclaration(GenericMethodDeclarationContext ctx) { ArrayList bounds = new ArrayList<>(); for (TypeParameterContext c : ctx.typeParameters().typeParameter()) { switch (c.Identifier().getText()) { case "KType": checkArgument(c.typeBound() == null, "Unexpected type bound on template type: " + c.getText()); if (templateOptions.isKTypeGeneric()) { bounds.add(c.getText()); } break; case "VType": checkArgument(c.typeBound() == null, "Unexpected type bound on template type: " + c.getText()); if (templateOptions.isVTypeGeneric()) { bounds.add(c.getText()); } break; default: TypeBoundContext tbc = c.typeBound(); if (tbc != null) { checkArgument(tbc.type().size() == 1, "Expected exactly one type bound: " + c.getText()); TypeContext tctx = tbc.type().get(0); Interval sourceInterval = tbc.getSourceInterval(); try { StringWriter sw = processor.reconstruct( new StringWriter(), processor.tokenStream, sourceInterval.a, sourceInterval.b, visitType(tctx), templateOptions); bounds.add(c.Identifier() + " extends " + sw.toString()); } catch (IOException e) { throw new RuntimeException(e); } } else { bounds.add(c.getText()); } break; } } List replacements = new ArrayList<>(); if (bounds.isEmpty()) { replacements.add(new Replacement(ctx.typeParameters(), "")); } else { replacements.add(new Replacement(ctx.typeParameters(), "<" + join(", ", bounds) + ">")); } replacements.addAll(super.visitMethodDeclaration(ctx.methodDeclaration())); return replacements; } @Override public List visitMethodDeclaration(MethodDeclarationContext ctx) { List replacements = new ArrayList<>(); if (ctx.type() != null) { replacements.addAll(visitType(ctx.type())); } replacements.addAll(processIdentifier(ctx.Identifier(), NONE)); replacements.addAll(visitFormalParameters(ctx.formalParameters())); if (ctx.qualifiedNameList() != null) { replacements.addAll(visitQualifiedNameList(ctx.qualifiedNameList())); } replacements.addAll(visitMethodBody(ctx.methodBody())); return replacements; } @Override public List visitIdentifierTypeOrDiamondPair(IdentifierTypeOrDiamondPairContext ctx) { if (ctx.typeArgumentsOrDiamond() == null) { return processIdentifier(ctx.Identifier(), NONE); } else { List replacements = new ArrayList<>(); String identifier = ctx.Identifier().getText(); if (ctx.typeArgumentsOrDiamond().getText().equals("<>")) { if (identifier.contains("KType") && templateOptions.isKTypePrimitive() && (!identifier.contains("VType") || templateOptions.isVTypePrimitive())) { replacements.add(new Replacement(ctx.typeArgumentsOrDiamond(), "")); } return processIdentifier(ctx.Identifier(), replacements); } else { List typeBounds = new ArrayList<>(); TypeArgumentsContext typeArguments = ctx.typeArgumentsOrDiamond().typeArguments(); Deque wildcards = getWildcards(); for (TypeArgumentContext c : typeArguments.typeArgument()) { typeBounds.add(typeBoundOf(c, wildcards)); } replacements.add(new Replacement(typeArguments, toString(typeBounds))); int typeBoundIndex = 0; if (identifier.contains("KType")) { TypeBound bb = typeBounds.get(typeBoundIndex++); if (bb.isTemplateType()) { identifier = identifier.replace("KType", bb.getBoxedType()); } else { identifier = identifier.replace("KType", "Object"); } } if (identifier.contains("VType")) { TypeBound bb = typeBounds.get(typeBoundIndex++); if (bb.isTemplateType()) { identifier = identifier.replace("VType", bb.getBoxedType()); } else { identifier = identifier.replace("VType", "Object"); } } replacements.add(new Replacement(ctx.Identifier(), identifier)); } return replacements; } } @Override public List visitCreatedName(CreatedNameContext ctx) { return super.visitCreatedName(ctx); } @Override public List visitIdentifierTypePair(IdentifierTypePairContext ctx) { String identifier = ctx.Identifier().getText(); if (isTemplateIdentifier(identifier)) { if (ctx.typeArguments() != null) { List replacements = new ArrayList<>(); List typeBounds = new ArrayList<>(); Deque wildcards = getWildcards(); for (TypeArgumentContext c : ctx.typeArguments().typeArgument()) { typeBounds.add(typeBoundOf(c, wildcards)); } replacements.add(new Replacement(ctx.typeArguments(), toString(typeBounds))); int typeBoundIndex = 0; if (identifier.contains("KType")) { TypeBound bb = typeBounds.get(typeBoundIndex++); if (bb.isTemplateType()) { identifier = identifier.replace("KType", bb.getBoxedType()); } else { identifier = identifier.replace("KType", "Object"); } } if (identifier.contains("VType")) { TypeBound bb = typeBounds.get(typeBoundIndex++); if (bb.isTemplateType()) { identifier = identifier.replace("VType", bb.getBoxedType()); } else { identifier = identifier.replace("VType", "Object"); } } replacements.add(new Replacement(ctx.Identifier(), identifier)); return replacements; } else { return processIdentifier(ctx.Identifier(), NONE); } } return super.visitIdentifierTypePair(ctx); } @Override public List visitQualifiedName(QualifiedNameContext ctx) { List replacements = NONE; for (TerminalNode identifier : ctx.Identifier()) { String symbol = identifier.getText(); if (isTemplateIdentifier(symbol)) { if (symbol.contains("KType")) { symbol = symbol.replace("KType", templateOptions.getKType().getBoxedType()); } if (symbol.contains("VType")) { symbol = symbol.replace("VType", templateOptions.getVType().getBoxedType()); } if (replacements == NONE) { replacements = new ArrayList<>(); } replacements.add(new Replacement(identifier, symbol)); } } return replacements; } @Override protected List defaultResult() { return NONE; } @Override protected List aggregateResult(List first, List second) { if (second.size() == 0) return first; if (first.size() == 0) return second; // Treat partial results as immutable. List result = new ArrayList(); result.addAll(first); result.addAll(second); return result; } private ArrayDeque getWildcards() { ArrayDeque deque = new ArrayDeque<>(); if (templateOptions.hasKType()) { deque.addLast(templateOptions.getKType()); } if (templateOptions.hasVType()) { deque.addLast(templateOptions.getVType()); } return deque; } private List processIdentifier(TerminalNode ctx, List replacements) { String identifier = ctx.getText(); if (isTemplateIdentifier(identifier)) { replacements = new ArrayList<>(replacements); switch (identifier) { case "KType": identifier = templateOptions.isKTypePrimitive() ? templateOptions.getKType().getType() : "KType"; break; case "VType": identifier = templateOptions.isVTypePrimitive() ? templateOptions.getVType().getType() : "VType"; break; default: if (identifier.contains("KType")) { identifier = identifier.replace("KType", templateOptions.getKType().getBoxedType()); } if (identifier.contains("VType")) { identifier = identifier.replace("VType", templateOptions.getVType().getBoxedType()); } break; } replacements.add(new Replacement(ctx, identifier)); } return replacements; } private String toString(List typeBounds) { List parts = new ArrayList<>(); for (TypeBound tb : typeBounds) { if (tb.isTemplateType()) { if (!tb.templateBound().isGeneric()) { continue; } } parts.add(tb.originalBound()); } return parts.isEmpty() ? "" : "<" + join(", ", parts) + ">"; } private String join(String on, Iterable parts) { StringBuilder out = new StringBuilder(); boolean prependOn = false; for (String part : parts) { if (prependOn) { out.append(on); } else { prependOn = true; } out.append(part); } return out.toString(); } private boolean isTemplateIdentifier(String symbol) { return symbol.contains("KType") || symbol.contains("VType"); } } hppc-0.7.2/hppc-template-processor/src/test/000077500000000000000000000000001300364116400207765ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/000077500000000000000000000000001300364116400217175ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/000077500000000000000000000000001300364116400224755ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/000077500000000000000000000000001300364116400251555ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/000077500000000000000000000000001300364116400261075ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/generator/000077500000000000000000000000001300364116400300755ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/generator/parser/000077500000000000000000000000001300364116400313715ustar00rootroot00000000000000KTypeVTypeClass.java000066400000000000000000000015031300364116400351660ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/generator/parserpackage com.carrotsearch.hppc.generator.parser; import com.carrotsearch.hppc.generator.parser.subpackage.KTypeVTypeInterfaceImported; /** * A list of KTypes. */ public class KTypeVTypeClass extends KTypeVTypeSuper implements KTypeVTypeInterface, KTypeVTypeInterfaceImported, Cloneable { KType [] keys; public KTypeVTypeClass() {} public KTypeVTypeClass(KType[] foo, VType boo) {} public KTypeVTypeClass(KTypeVTypeSuper foo) {} public VType foo(KType key, VType value) { throw new RuntimeException(); } public void foo(KTypeVTypeSuper foo) {} } class KTypeVTypeSuper {} interface KTypeVTypeInterface {}TestSignatureProcessor.java000066400000000000000000000310541300364116400366610ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/generator/parserpackage com.carrotsearch.hppc.generator.parser; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Locale; import org.assertj.core.api.Assertions; import org.junit.Assume; import org.junit.Test; import org.junit.runner.RunWith; import com.carrotsearch.hppc.generator.TemplateOptions; import com.carrotsearch.hppc.generator.Type; import com.carrotsearch.hppc.generator.parser.SignatureProcessor; import com.carrotsearch.randomizedtesting.RandomizedRunner; @RunWith(RandomizedRunner.class) public class TestSignatureProcessor { @Test public void testClassKV() throws IOException { SignatureProcessor sp = new SignatureProcessor("public class KTypeVTypeClass {}"); check(Type.INT, Type.LONG, sp, "public class IntLongClass {}"); check(Type.INT, Type.GENERIC, sp, "public class IntObjectClass {}"); check(Type.GENERIC, Type.LONG, sp, "public class ObjectLongClass {}"); check(Type.GENERIC, Type.GENERIC, sp, "public class ObjectObjectClass {}"); } @Test public void testClassVK_SignatureReversed() throws IOException { SignatureProcessor sp = new SignatureProcessor("public class KTypeVTypeClass {}"); check(Type.INT, Type.LONG, sp, "public class LongIntClass {}"); check(Type.INT, Type.GENERIC, sp, "public class ObjectIntClass {}"); check(Type.GENERIC, Type.LONG, sp, "public class LongObjectClass {}"); check(Type.GENERIC, Type.GENERIC, sp, "public class ObjectObjectClass {}"); } @Test public void testClassK() throws IOException { SignatureProcessor sp = new SignatureProcessor("public class KTypeClass {}"); check(Type.INT, sp, "public class IntClass {}"); check(Type.GENERIC, sp, "public class ObjectClass {}"); } @Test public void testClassExtendsNonTemplate() throws IOException { SignatureProcessor sp = new SignatureProcessor("public class KTypeVTypeClass extends SuperClass {}"); check(Type.INT, Type.LONG, sp, "public class IntLongClass extends SuperClass {}"); check(Type.INT, Type.GENERIC, sp, "public class IntObjectClass extends SuperClass {}"); check(Type.GENERIC, Type.LONG, sp, "public class ObjectLongClass extends SuperClass {}"); check(Type.GENERIC, Type.GENERIC, sp, "public class ObjectObjectClass extends SuperClass {}"); } @Test public void testClassExtendsTemplate() throws IOException { SignatureProcessor sp = new SignatureProcessor( "public class KTypeVTypeClass extends KTypeVTypeSuperClass {}"); check(Type.INT, Type.LONG, sp, "public class IntLongClass extends IntLongSuperClass {}"); check(Type.INT, Type.GENERIC, sp, "public class IntObjectClass extends IntObjectSuperClass {}"); check(Type.GENERIC, Type.LONG, sp, "public class ObjectLongClass extends ObjectLongSuperClass {}"); check(Type.GENERIC, Type.GENERIC, sp, "public class ObjectObjectClass extends ObjectObjectSuperClass {}"); } @Test public void testClassImplementsTemplate() throws IOException { SignatureProcessor sp = new SignatureProcessor( "public class KTypeVTypeClass " + " extends KTypeVTypeSuperClass" + " implements KTypeVTypeInterface {}"); check(Type.INT, Type.LONG, sp, "public class IntLongClass extends IntLongSuperClass implements IntLongInterface {}"); check(Type.INT, Type.GENERIC, sp, "public class IntObjectClass extends IntObjectSuperClass implements IntObjectInterface {}"); check(Type.GENERIC, Type.LONG, sp, "public class ObjectLongClass extends ObjectLongSuperClass implements ObjectLongInterface {}"); check(Type.GENERIC, Type.GENERIC, sp, "public class ObjectObjectClass extends ObjectObjectSuperClass implements ObjectObjectInterface {}"); } @Test public void testInterfaceKV() throws IOException { SignatureProcessor sp = new SignatureProcessor( "public interface KTypeVTypeInterface " + " extends KTypeVTypeSuper {}"); check(Type.INT, Type.LONG, sp, "public interface IntLongInterface extends IntLongSuper {}"); check(Type.INT, Type.GENERIC, sp, "public interface IntObjectInterface extends IntObjectSuper {}"); check(Type.GENERIC, Type.LONG, sp, "public interface ObjectLongInterface extends ObjectLongSuper {}"); check(Type.GENERIC, Type.GENERIC, sp, "public interface ObjectObjectInterface extends ObjectObjectSuper {}"); } @Test public void testImportDeclarations() throws IOException { SignatureProcessor sp = new SignatureProcessor( "import foo.KTypeVTypeClass; class Foo {}"); check(Type.INT, Type.LONG, sp, "import foo.IntLongClass; class Foo {}"); check(Type.INT, Type.GENERIC, sp, "import foo.IntObjectClass; class Foo {}"); check(Type.GENERIC, Type.LONG, sp, "import foo.ObjectLongClass; class Foo {}"); check(Type.GENERIC, Type.GENERIC, sp, "import foo.ObjectObjectClass; class Foo {}"); } @Test public void testFieldDeclaration() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeFoo { KType foo; KType [] foo2; }"); check(Type.FLOAT, sp, "class FloatFoo { float foo; float [] foo2; }"); check(Type.GENERIC, sp, "class ObjectFoo { KType foo; KType [] foo2; }"); } @Test public void testClassConstructor() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeVTypeFoo { public KTypeVTypeFoo(KType k, VType v) {} }"); check(Type.FLOAT, Type.DOUBLE, sp, "class FloatDoubleFoo { public FloatDoubleFoo(float k, double v) {} }"); check(Type.FLOAT, Type.GENERIC, sp, "class FloatObjectFoo { public FloatObjectFoo(float k, VType v) {} }"); check(Type.GENERIC, Type.FLOAT, sp, "class ObjectFloatFoo { public ObjectFloatFoo(KType k, float v) {} }"); check(Type.GENERIC, Type.GENERIC, sp, "class ObjectObjectFoo { public ObjectObjectFoo(KType k, VType v) {} }"); } @Test public void testThisReference() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeVTypeFoo { public void foo() { KTypeVTypeFoo.this.foo(); } }"); check(Type.FLOAT, Type.DOUBLE, sp, "class FloatDoubleFoo { public void foo() { FloatDoubleFoo.this.foo(); } }"); } @Test public void testNewClassDiamond() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeVTypeFoo { public void foo() { new KTypeVTypeFoo<>(); } }"); check(Type.FLOAT, Type.DOUBLE, sp, "class FloatDoubleFoo { public void foo() { new FloatDoubleFoo(); } }"); check(Type.GENERIC, Type.DOUBLE, sp, "class ObjectDoubleFoo { public void foo() { new ObjectDoubleFoo<>(); } }"); } @Test public void testNewClass() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeVTypeFoo { public void foo() { new KTypeVTypeFoo(); } }"); check(Type.FLOAT, Type.DOUBLE, sp, "class FloatDoubleFoo { public void foo() { new FloatDoubleFoo(); } }"); check(Type.GENERIC, Type.DOUBLE, sp, "class ObjectDoubleFoo { public void foo() { new ObjectDoubleFoo(); } }"); } @Test public void testStaticGenericMethod() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeVTypeFoo { static KTypeVTypeFoo foo(KType[] k, VType[] v) {} }"); check(Type.FLOAT, Type.DOUBLE, sp, "class FloatDoubleFoo { static FloatDoubleFoo foo(float[] k, double[] v) {} }"); check(Type.GENERIC, Type.DOUBLE, sp, "class ObjectDoubleFoo { static ObjectDoubleFoo foo(KType[] k, double[] v) {} }"); } @Test public void testWildcardBound() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeFoo { void bar(KTypeFoo other) {} }"); check(Type.FLOAT, sp, "class FloatFoo { void bar(FloatFoo other) {} }"); check(Type.GENERIC, sp, "class ObjectFoo { void bar(ObjectFoo other) {} }"); } @Test public void testGenericNamedTypeBound() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeFoo { public > T forEach(T v) { throw new R(); } }"); check(Type.FLOAT, sp, "class FloatFoo { public T forEach(T v) { throw new R(); } }"); check(Type.GENERIC, sp, "class ObjectFoo { public > T forEach(T v) { throw new R(); } }"); } @Test public void testBug_ErasesObjectConstructor() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeVTypeFoo { static { HashSet values = new HashSet(); }}"); check(Type.FLOAT, Type.INT, sp, "class FloatIntFoo { static { HashSet values = new HashSet(); }}"); check(Type.GENERIC, Type.GENERIC, sp, "class ObjectObjectFoo { static { HashSet values = new HashSet(); }}"); } @Test public void testBug_ErasesUntemplated() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeFoo { void foo() { KTypeBar x = new KTypeBar(); } }"); check(Type.FLOAT, sp, "class FloatFoo { void foo() { ObjectBar x = new ObjectBar(); } }"); check(Type.GENERIC, sp, "class ObjectFoo { void foo() { ObjectBar x = new ObjectBar(); } }"); } @Test public void testBug_EraseNestedPrimitive() throws IOException { SignatureProcessor sp = new SignatureProcessor( "class KTypeFoo { static class Nested extends KTypeBar {} }"); check(Type.FLOAT, sp, "class FloatFoo { static class Nested extends FloatBar {} }"); check(Type.GENERIC, sp, "class ObjectFoo { static class Nested extends ObjectBar {} }"); } @Test public void testJavaDoc_k() throws IOException { SignatureProcessor sp = new SignatureProcessor( "/** KTypeFoo KTypes */"); check(Type.FLOAT, sp, "/** FloatFoo floats */"); check(Type.GENERIC, sp, "/** ObjectFoo Objects */"); } @Test public void testJavaDoc_kv() throws IOException { SignatureProcessor sp = new SignatureProcessor( "/** KTypeFoo KTypes KTypeVTypeFoo VTypes */"); check(Type.FLOAT, Type.DOUBLE, sp, "/** FloatFoo floats FloatDoubleFoo doubles */"); check(Type.GENERIC, Type.GENERIC, sp, "/** ObjectFoo Objects ObjectObjectFoo Objects */"); } @Test public void testFullClass() throws IOException { Path path = Paths.get("src/test/java/com/carrotsearch/hppc/generator/parser/KTypeVTypeClass.java"); // Path path = Paths.get("c:\\carrot2\\gh.carrotsearch\\hppc\\hppc\\src\\main\\templates\\com\\carrotsearch\\hppc\\KTypeArrayDeque.java"); Assume.assumeTrue(Files.isRegularFile(path)); SignatureProcessor sp = new SignatureProcessor(new String(Files.readAllBytes(path), StandardCharsets.UTF_8)); System.out.println(sp.process(new TemplateOptions(Type.LONG, Type.GENERIC))); } private void check(Type ktype, SignatureProcessor processor, String expected) throws IOException { check(new TemplateOptions(ktype), processor, expected); } private void check(Type ktype, Type vtype, SignatureProcessor processor, String expected) throws IOException { check(new TemplateOptions(ktype, vtype), processor, expected); } private void check(TemplateOptions templateOptions, SignatureProcessor processor, String expected) throws IOException { String output = processor.process(templateOptions); expected = expected.replaceAll("\\s+", " "); output = output.replaceAll("\\s+", " "); if (!output.equals(expected)) { System.out.println(String.format(Locale.ROOT, "Output : %s\n" + "Expected: %s\n", output, expected)); } Assertions.assertThat(output).isEqualTo(expected); } } hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/generator/parser/subpackage/000077500000000000000000000000001300364116400334765ustar00rootroot00000000000000KTypeVTypeInterfaceImported.java000066400000000000000000000001771300364116400416400ustar00rootroot00000000000000hppc-0.7.2/hppc-template-processor/src/test/java/com/carrotsearch/hppc/generator/parser/subpackagepackage com.carrotsearch.hppc.generator.parser.subpackage; public interface KTypeVTypeInterfaceImported { } hppc-0.7.2/hppc/000077500000000000000000000000001300364116400134025ustar00rootroot00000000000000hppc-0.7.2/hppc/pom.xml000066400000000000000000000420701300364116400147220ustar00rootroot00000000000000 4.0.0 com.carrotsearch hppc-parent 0.7.2 ../pom.xml hppc bundle HPPC Collections High Performance Primitive Collections. Fundamental data structures (maps, sets, lists, stacks, queues) generated for combinations of object and primitive types to conserve JVM memory and speed up execution. com.carrotsearch hppc-template-processor ${project.version} provided true junit junit test com.carrotsearch.randomizedtesting randomizedtesting-runner test org.assertj assertj-core jar test true install org.apache.maven.plugins maven-source-plugin 2.4 attach-sources verify jar-no-fork **/ByteByte* **/ByteChar* **/ByteShort* **/ByteInt* **/ByteFloat* **/ByteLong* **/ByteDouble* **/ByteObject* **/ByteHashSet* **/ByteScatterSet* **/ByteSet* **/FloatByte* **/FloatChar* **/FloatShort* **/FloatInt* **/FloatFloat* **/FloatLong* **/FloatDouble* **/FloatObject* **/FloatHashSet* **/FloatScatterSet* **/FloatSet* **/DoubleByte* **/DoubleChar* **/DoubleShort* **/DoubleInt* **/DoubleFloat* **/DoubleLong* **/DoubleDouble* **/DoubleObject* **/DoubleHashSet* **/DoubleScatterSet* **/DoubleSet* attach-sources-esoteric verify jar-no-fork esoteric-sources **/ByteByte* **/ByteChar* **/ByteShort* **/ByteInt* **/ByteFloat* **/ByteLong* **/ByteDouble* **/ByteObject* **/ByteHashSet* **/ByteScatterSet* **/ByteSet* **/FloatByte* **/FloatChar* **/FloatShort* **/FloatInt* **/FloatFloat* **/FloatLong* **/FloatDouble* **/FloatObject* **/FloatHashSet* **/FloatScatterSet* **/FloatSet* **/DoubleByte* **/DoubleChar* **/DoubleShort* **/DoubleInt* **/DoubleFloat* **/DoubleLong* **/DoubleDouble* **/DoubleObject* **/DoubleHashSet* **/DoubleScatterSet* **/DoubleSet* org.apache.maven.plugins maven-jar-plugin default-jar package **/ByteByte* **/ByteChar* **/ByteShort* **/ByteInt* **/ByteFloat* **/ByteLong* **/ByteDouble* **/ByteObject* **/ByteHashSet* **/ByteScatterSet* **/ByteSet* **/FloatByte* **/FloatChar* **/FloatShort* **/FloatInt* **/FloatFloat* **/FloatLong* **/FloatDouble* **/FloatObject* **/FloatHashSet* **/FloatScatterSet* **/FloatSet* **/DoubleByte* **/DoubleChar* **/DoubleShort* **/DoubleInt* **/DoubleFloat* **/DoubleLong* **/DoubleDouble* **/DoubleObject* **/DoubleHashSet* **/DoubleScatterSet* **/DoubleSet* esoteric-jar package jar esoteric **/ByteByte* **/ByteChar* **/ByteShort* **/ByteInt* **/ByteFloat* **/ByteLong* **/ByteDouble* **/ByteObject* **/ByteHashSet* **/ByteScatterSet* **/ByteSet* **/FloatByte* **/FloatChar* **/FloatShort* **/FloatInt* **/FloatFloat* **/FloatLong* **/FloatDouble* **/FloatObject* **/FloatHashSet* **/FloatScatterSet* **/FloatSet* **/DoubleByte* **/DoubleChar* **/DoubleShort* **/DoubleInt* **/DoubleFloat* **/DoubleLong* **/DoubleDouble* **/DoubleObject* **/DoubleHashSet* **/DoubleScatterSet* **/DoubleSet* org.apache.felix maven-bundle-plugin esoteric-bundle package bundle esoteric com.carrotsearch hppc-template-processor ${project.version} generate-sources generate-sources template-processor ${template.processor.incremental} main ${project.basedir}/src/main/templates ${project.build.directory}/generated-sources/main/java generate-test-sources generate-test-sources template-processor ${template.processor.incremental} test ${project.basedir}/src/test/templates ${project.build.directory}/generated-sources/test/java com.carrotsearch.randomizedtesting junit4-maven-plugin org.apache.maven.plugins maven-assembly-plugin make-release-assembly package single src/main/assembly/bin.xml gnu false false de.thetaphi forbiddenapis check-forbidden-apis ${project.parent.basedir}/etc/forbidden-apis/intrinsics.txt ${project.parent.basedir}/etc/forbidden-apis/time-relative.txt com.carrotsearch.hppc.SuppressForbidden eclipse m2e.version true true true true com.carrotsearch hppc-template-processor ${project.version} add-templates generate-sources add-source src/main/templates add-templates-tests generate-test-sources add-test-source src/test/templates sonatype-oss-release org.apache.maven.plugins maven-javadoc-plugin attach-javadocs ${project.build.sourceEncoding} HPPC v${project.version} API Documentation HPPC v${project.version} API Documentation
High Performance Primitive Collections (HPPC) v${project.version}
API Documentation]]>
true true false true true HPPC com.carrotsearch.hppc* css/1.7/stylesheet.css
jar
jdk18 [1.8,) org.apache.maven.plugins maven-javadoc-plugin attach-javadocs -Xdoclint:-missing css/1.8/stylesheet.css
hppc-0.7.2/hppc/src/000077500000000000000000000000001300364116400141715ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/000077500000000000000000000000001300364116400151155ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/assembly/000077500000000000000000000000001300364116400167345ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/assembly/bin.xml000066400000000000000000000020371300364116400202300ustar00rootroot00000000000000 distribution zip ../ ALTERNATIVES.txt CHANGES.txt LICENSE.txt NOTICE.txt README.txt ${project.build.directory} *.jar apidocs/** *-javadoc.jar *-sources.jar hppc-0.7.2/hppc/src/main/java/000077500000000000000000000000001300364116400160365ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/java/com/000077500000000000000000000000001300364116400166145ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/java/com/carrotsearch/000077500000000000000000000000001300364116400212745ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/000077500000000000000000000000001300364116400222265ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/AbstractIterator.java000066400000000000000000000030341300364116400263460ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Iterator; import java.util.NoSuchElementException; /** * Simplifies the implementation of iterators a bit. Modeled loosely after * Google Guava's API. */ public abstract class AbstractIterator implements Iterator { private final static int NOT_CACHED = 0; private final static int CACHED = 1; private final static int AT_END = 2; /** Current iterator state. */ private int state = NOT_CACHED; /** * The next element to be returned from {@link #next()} if fetched. */ private E nextElement; /** * {@inheritDoc} */ @Override public boolean hasNext() { if (state == NOT_CACHED) { state = CACHED; nextElement = fetch(); } return state == CACHED; } /** * {@inheritDoc} */ @Override public E next() { if (!hasNext()) { throw new NoSuchElementException(); } state = NOT_CACHED; return nextElement; } /** * Default implementation throws {@link UnsupportedOperationException}. */ @Override public void remove() { throw new UnsupportedOperationException(); } /** * Fetch next element. The implementation must return {@link #done()} when all * elements have been fetched. * * @return Returns the next value for the iterator or chain-calls {@link #done()}. */ protected abstract E fetch(); /** * Call when done. * * @return Returns a unique sentinel value to indicate end-of-iteration. */ protected final E done() { state = AT_END; return null; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/ArraySizingStrategy.java000066400000000000000000000020621300364116400270560ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * Resizing (growth) strategy for array-backed buffers. */ public interface ArraySizingStrategy { /** * @param currentBufferLength * Current size of the array (buffer). This number should comply with * the strategy's policies (it is a result of initial rounding or * further growCalls). It can also be zero, indicating the growth * from an empty buffer. * * @param elementsCount * Number of elements stored in the buffer. * * @param expectedAdditions * Expected number of additions (resize hint). * * @return Must return a new size at least as big as to hold * elementsCount + expectedAdditions. * * @throws BufferAllocationException * If the sizing strategy cannot grow the buffer (for example due to * constraints or memory limits). */ int grow(int currentBufferLength, int elementsCount, int expectedAdditions) throws BufferAllocationException; } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/BitMixer.java000066400000000000000000000065161300364116400246240ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * Bit mixing utilities. The purpose of these methods is to evenly distribute key space over int32 * range. */ public final class BitMixer { // Don't bother mixing very small key domains much. public static int mix(byte key) { return key * PHI_C32; } public static int mix(byte key, int seed) { return (key ^ seed) * PHI_C32; } public static int mix(short key) { return mixPhi(key); } public static int mix(short key, int seed) { return mixPhi(key ^ seed); } public static int mix(char key) { return mixPhi(key); } public static int mix(char key, int seed) { return mixPhi(key ^ seed); } // Better mix for larger key domains. public static int mix(int key) { return mix32(key); } public static int mix(int key, int seed) { return mix32(key ^ seed); } public static int mix(float key) { return mix32(Float.floatToIntBits(key)); } public static int mix(float key, int seed) { return mix32(Float.floatToIntBits(key) ^ seed); } public static int mix(double key) { return (int) mix64(Double.doubleToLongBits(key)); } public static int mix(double key, int seed) { return (int) mix64(Double.doubleToLongBits(key) ^ seed); } public static int mix(long key) { return (int) mix64(key); } public static int mix(long key, int seed) { return (int) mix64(key ^ seed); } public static int mix(Object key) { return key == null ? 0 : mix32(key.hashCode()); } public static int mix(Object key, int seed) { return key == null ? 0 : mix32(key.hashCode() ^ seed); } /** * MH3's plain finalization step. */ public static int mix32(int k) { k = (k ^ (k >>> 16)) * 0x85ebca6b; k = (k ^ (k >>> 13)) * 0xc2b2ae35; return k ^ (k >>> 16); } /** * Computes David Stafford variant 9 of 64bit mix function (MH3 finalization step, * with different shifts and constants). * * Variant 9 is picked because it contains two 32-bit shifts which could be possibly * optimized into better machine code. * * @see "http://zimbry.blogspot.com/2011/09/better-bit-mixing-improving-on.html" */ public static long mix64(long z) { z = (z ^ (z >>> 32)) * 0x4cd6944c5cc20b6dL; z = (z ^ (z >>> 29)) * 0xfc12c5b19d3259e9L; return z ^ (z >>> 32); } /* * Golden ratio bit mixers. */ private static final int PHI_C32 = 0x9e3779b9; private static final long PHI_C64 = 0x9e3779b97f4a7c15L; public static int mixPhi(byte k) { final int h = k * PHI_C32; return h ^ (h >>> 16); } public static int mixPhi(char k) { final int h = k * PHI_C32; return h ^ (h >>> 16); } public static int mixPhi(short k) { final int h = k * PHI_C32; return h ^ (h >>> 16); } public static int mixPhi(int k) { final int h = k * PHI_C32; return h ^ (h >>> 16); } public static int mixPhi(float k) { final int h = Float.floatToIntBits(k) * PHI_C32; return h ^ (h >>> 16); } public static int mixPhi(double k) { final long h = Double.doubleToLongBits(k) * PHI_C64; return (int) (h ^ (h >>> 32)); } public static int mixPhi(long k) { final long h = k * PHI_C64; return (int) (h ^ (h >>> 32)); } public static int mixPhi(Object k) { final int h = (k == null ? 0 : k.hashCode() * PHI_C32); return h ^ (h >>> 16); } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/BitSet.java000066400000000000000000001003671300364116400242720ustar00rootroot00000000000000/* * Repackaged from org.apache.lucene.util.OpenBitSet (Lucene). * svn rev. 1479633, https://svn.apache.org/repos/asf/lucene/dev/trunk * * Minor changes in class hierarchy, removed serialization and several methods. * Added container adapters. */ /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.carrotsearch.hppc; import java.util.*; import com.carrotsearch.hppc.cursors.IntCursor; import com.carrotsearch.hppc.cursors.LongCursor; import com.carrotsearch.hppc.predicates.IntPredicate; import com.carrotsearch.hppc.predicates.LongPredicate; import com.carrotsearch.hppc.procedures.IntProcedure; import com.carrotsearch.hppc.procedures.LongProcedure; /** * An "open" BitSet implementation that allows direct access to the array of words storing * the bits. *

* Unlike java.util.bitset, the fact that bits are packed into an array of longs is part * of the interface. This allows efficient implementation of other algorithms by someone * other than the author. It also allows one to efficiently implement alternate * serialization or interchange formats.

*

* The index range for a bitset can easily exceed positive int range in Java * (0x7fffffff), so many methods in this class accept or return a long. There * are adapter methods that return views compatible with * {@link LongLookupContainer} and {@link IntLookupContainer} interfaces.

* * @see #asIntLookupContainer() * @see #asLongLookupContainer() */ public class BitSet implements Cloneable { /** * The initial default number of bits ({@value #DEFAULT_NUM_BITS}). */ private static final long DEFAULT_NUM_BITS = 64; /** * Internal representation of bits in this bit set. */ public long [] bits; /** * The number of words (longs) used in the {@link #bits} array. */ public int wlen; /** * Constructs a bit set with the default capacity. */ public BitSet() { this(DEFAULT_NUM_BITS); } /** * Constructs an BitSet large enough to hold numBits. * * @param numBits Number of bits */ public BitSet(long numBits) { bits = new long [bits2words(numBits)]; wlen = bits.length; } /** * Constructs an BitSet from an existing long[]. * * The first 64 bits are in long[0], with bit index 0 at the least significant bit, * and bit index 63 at the most significant. Given a bit index, the word containing it * is long[index/64], and it is at bit number index%64 within that word. * * numWords are the number of elements in the array that contain set bits (non-zero * longs). numWords should be <= bits.length, and any existing words in the array at * position >= numWords should be zero. * * @param bits underlying bits buffer * @param numWords the number of elements in the array that contain set bits */ public BitSet(long [] bits, int numWords) { this.bits = bits; this.wlen = numWords; } /** * Static constructor-like method similar to other (generic) collections. * * @return New instance. */ public static BitSet newInstance() { return new BitSet(); } /** * @return Returns an iterator over all set bits of this bitset. The iterator should * be faster than using a loop around {@link #nextSetBit(int)}. */ public BitSetIterator iterator() { return new BitSetIterator(bits, wlen); } /** * @return Returns the current capacity in bits (1 greater than the index of the last bit). */ public long capacity() { return bits.length << 6; } /** * @see #cardinality() * @see java.util.BitSet#size() * @return Returns the current capacity of this set. Included for compatibility. This is not * equal to {@link #cardinality}. */ public long size() { return capacity(); } /** * @see java.util.BitSet#length() * @return Returns the "logical size" of this {@code BitSet}: the index of * the highest set bit in the {@code BitSet} plus one. */ public long length() { trimTrailingZeros(); if (wlen == 0) return 0; return (((long) wlen - 1) << 6) + (64 - Long.numberOfLeadingZeros(bits[wlen - 1])); } /** * @return Returns true if there are no set bits */ public boolean isEmpty() { return cardinality() == 0; } /** * @param index The index. * @return Returns true or false for the specified bit index. */ public boolean get(int index) { int i = index >> 6; // div 64 // signed shift will keep a negative index and force an // array-index-out-of-bounds-exception, removing the need for an explicit check. if (i >= bits.length) return false; int bit = index & 0x3f; // mod 64 long bitmask = 1L << bit; return (bits[i] & bitmask) != 0; } /** * @param index The index. * @return Returns true or false for the specified bit index. */ public boolean get(long index) { int i = (int) (index >> 6); // div 64 if (i >= bits.length) return false; int bit = (int) index & 0x3f; // mod 64 long bitmask = 1L << bit; return (bits[i] & bitmask) != 0; } /** * Sets a bit, expanding the set size if necessary. * * @param index the index to set */ public void set(long index) { int wordNum = expandingWordNum(index); int bit = (int) index & 0x3f; long bitmask = 1L << bit; bits[wordNum] |= bitmask; } /** * Sets a range of bits, expanding the set size if necessary * * @param startIndex lower index * @param endIndex one-past the last bit to set */ public void set(long startIndex, long endIndex) { if (endIndex <= startIndex) return; int startWord = (int) (startIndex >> 6); // since endIndex is one past the end, this is index of the last // word to be changed. int endWord = expandingWordNum(endIndex - 1); long startmask = -1L << startIndex; long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex // due to wrap if (startWord == endWord) { bits[startWord] |= (startmask & endmask); return; } bits[startWord] |= startmask; Arrays.fill(bits, startWord + 1, endWord, -1L); bits[endWord] |= endmask; } protected int expandingWordNum(long index) { int wordNum = (int) (index >> 6); if (wordNum >= wlen) { ensureCapacity(index + 1); wlen = wordNum + 1; } return wordNum; } /** Clears all bits. */ public void clear() { Arrays.fill(bits, 0); this.wlen = 0; } /** * clears a bit, allowing access beyond the current set size without changing the * size. * * @param index the index to clear */ public void clear(long index) { int wordNum = (int) (index >> 6); // div 64 if (wordNum >= wlen) return; int bit = (int) index & 0x3f; // mod 64 long bitmask = 1L << bit; bits[wordNum] &= ~bitmask; } /** * Clears a range of bits. Clearing past the end does not change the size of the set. * * @param startIndex lower index * @param endIndex one-past the last bit to clear */ public void clear(int startIndex, int endIndex) { if (endIndex <= startIndex) return; int startWord = (startIndex >> 6); if (startWord >= wlen) return; // since endIndex is one past the end, this is index of the last // word to be changed. int endWord = ((endIndex - 1) >> 6); long startmask = -1L << startIndex; long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex // due to wrap // invert masks since we are clearing startmask = ~startmask; endmask = ~endmask; if (startWord == endWord) { bits[startWord] &= (startmask | endmask); return; } bits[startWord] &= startmask; int middle = Math.min(wlen, endWord); Arrays.fill(bits, startWord + 1, middle, 0L); if (endWord < wlen) { bits[endWord] &= endmask; } } /** * Clears a range of bits. Clearing past the end does not change the size of the set. * * @param startIndex lower index * @param endIndex one-past the last bit to clear */ public void clear(long startIndex, long endIndex) { if (endIndex <= startIndex) return; int startWord = (int) (startIndex >> 6); if (startWord >= wlen) return; // since endIndex is one past the end, this is index of the last // word to be changed. int endWord = (int) ((endIndex - 1) >> 6); long startmask = -1L << startIndex; long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex // due to wrap // invert masks since we are clearing startmask = ~startmask; endmask = ~endmask; if (startWord == endWord) { bits[startWord] &= (startmask | endmask); return; } bits[startWord] &= startmask; int middle = Math.min(wlen, endWord); Arrays.fill(bits, startWord + 1, middle, 0L); if (endWord < wlen) { bits[endWord] &= endmask; } } /** * Sets a bit and returns the previous value. The index should be less than the BitSet * size. * * @param index the index to set * @return previous state of the index */ public boolean getAndSet(int index) { int wordNum = index >> 6; // div 64 int bit = index & 0x3f; // mod 64 long bitmask = 1L << bit; boolean val = (bits[wordNum] & bitmask) != 0; bits[wordNum] |= bitmask; return val; } /** * Sets a bit and returns the previous value. The index should be less than the BitSet * size. * * @param index the index to set * @return previous state of the index */ public boolean getAndSet(long index) { int wordNum = (int) (index >> 6); // div 64 int bit = (int) index & 0x3f; // mod 64 long bitmask = 1L << bit; boolean val = (bits[wordNum] & bitmask) != 0; bits[wordNum] |= bitmask; return val; } /** * Flips a bit, expanding the set size if necessary. * * @param index the index to flip */ public void flip(long index) { int wordNum = expandingWordNum(index); int bit = (int) index & 0x3f; // mod 64 long bitmask = 1L << bit; bits[wordNum] ^= bitmask; } /** * flips a bit and returns the resulting bit value. The index should be less than the * BitSet size. * * @param index the index to flip * @return previous state of the index */ public boolean flipAndGet(int index) { int wordNum = index >> 6; // div 64 int bit = index & 0x3f; // mod 64 long bitmask = 1L << bit; bits[wordNum] ^= bitmask; return (bits[wordNum] & bitmask) != 0; } /** * flips a bit and returns the resulting bit value. The index should be less than the * BitSet size. * * @param index the index to flip * @return previous state of the index */ public boolean flipAndGet(long index) { int wordNum = (int) (index >> 6); // div 64 int bit = (int) index & 0x3f; // mod 64 long bitmask = 1L << bit; bits[wordNum] ^= bitmask; return (bits[wordNum] & bitmask) != 0; } /** * Flips a range of bits, expanding the set size if necessary * * @param startIndex lower index * @param endIndex one-past the last bit to flip */ public void flip(long startIndex, long endIndex) { if (endIndex <= startIndex) return; int startWord = (int) (startIndex >> 6); // since endIndex is one past the end, this is index of the last // word to be changed. int endWord = expandingWordNum(endIndex - 1); long startmask = -1L << startIndex; long endmask = -1L >>> -endIndex; // 64-(endIndex&0x3f) is the same as -endIndex // due to wrap if (startWord == endWord) { bits[startWord] ^= (startmask & endmask); return; } bits[startWord] ^= startmask; for (int i = startWord + 1; i < endWord; i++) { bits[i] = ~bits[i]; } bits[endWord] ^= endmask; } /** @return the number of set bits */ public long cardinality() { return BitUtil.pop_array(bits, 0, wlen); } /** * @param a The first set * @param b The second set * * @return Returns the popcount or cardinality of the intersection of the two sets. Neither * set is modified. */ public static long intersectionCount(BitSet a, BitSet b) { return BitUtil.pop_intersect(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen)); } /** * @param a The first set * @param b The second set * @return Returns the popcount or cardinality of the union of the two sets. Neither set is * modified. */ public static long unionCount(BitSet a, BitSet b) { long tot = BitUtil.pop_union(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen)); if (a.wlen < b.wlen) { tot += BitUtil.pop_array(b.bits, a.wlen, b.wlen - a.wlen); } else if (a.wlen > b.wlen) { tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen - b.wlen); } return tot; } /** * @param a The first set * @param b The second set * @return Returns the popcount or cardinality of "a and not b" or "intersection(a, not(b))". * Neither set is modified. */ public static long andNotCount(BitSet a, BitSet b) { long tot = BitUtil.pop_andnot(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen)); if (a.wlen > b.wlen) { tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen - b.wlen); } return tot; } /** * @param a The first set * @param b The second set * @return Returns the popcount or cardinality of the exclusive-or of the two sets. Neither * set is modified. */ public static long xorCount(BitSet a, BitSet b) { long tot = BitUtil.pop_xor(a.bits, b.bits, 0, Math.min(a.wlen, b.wlen)); if (a.wlen < b.wlen) { tot += BitUtil.pop_array(b.bits, a.wlen, b.wlen - a.wlen); } else if (a.wlen > b.wlen) { tot += BitUtil.pop_array(a.bits, b.wlen, a.wlen - b.wlen); } return tot; } /** * @param index The index to start scanning from, inclusive. * @return Returns the index of the first set bit starting at the index specified. -1 is * returned if there are no more set bits. * */ public int nextSetBit(int index) { int i = index >> 6; if (i >= wlen) return -1; int subIndex = index & 0x3f; // index within the word long word = bits[i] >> subIndex; // skip all the bits to the right of index if (word != 0) { return (i << 6) + subIndex + Long.numberOfTrailingZeros(word); } while (++i < wlen) { word = bits[i]; if (word != 0) return (i << 6) + Long.numberOfTrailingZeros(word); } return -1; } /** * @param index The index to start scanning from, inclusive. * @return Returns the index of the first set bit starting at the index specified. -1 is * returned if there are no more set bits. */ public long nextSetBit(long index) { int i = (int) (index >>> 6); if (i >= wlen) return -1; int subIndex = (int) index & 0x3f; // index within the word long word = bits[i] >>> subIndex; // skip all the bits to the right of index if (word != 0) { return (((long) i) << 6) + (subIndex + Long.numberOfTrailingZeros(word)); } while (++i < wlen) { word = bits[i]; if (word != 0) return (((long) i) << 6) + Long.numberOfTrailingZeros(word); } return -1; } @Override public Object clone() { try { BitSet obs = (BitSet) super.clone(); obs.bits = (long []) obs.bits.clone(); // hopefully an array clone is as // fast(er) than arraycopy return obs; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } /** * this = this AND other * @param other The bitset to intersect with. */ public void intersect(BitSet other) { int newLen = Math.min(this.wlen, other.wlen); long [] thisArr = this.bits; long [] otherArr = other.bits; // testing against zero can be more efficient int pos = newLen; while (--pos >= 0) { thisArr[pos] &= otherArr[pos]; } if (this.wlen > newLen) { // fill zeros from the new shorter length to the old length Arrays.fill(bits, newLen, this.wlen, 0); } this.wlen = newLen; } /** * this = this OR other * @param other The bitset to union with. */ public void union(BitSet other) { int newLen = Math.max(wlen, other.wlen); ensureCapacityWords(newLen); long [] thisArr = this.bits; long [] otherArr = other.bits; int pos = Math.min(wlen, other.wlen); while (--pos >= 0) { thisArr[pos] |= otherArr[pos]; } if (this.wlen < newLen) { System.arraycopy(otherArr, this.wlen, thisArr, this.wlen, newLen - this.wlen); } this.wlen = newLen; } /** * Remove all elements set in other: this = this AND_NOT other * @param other The other bitset. */ public void remove(BitSet other) { int idx = Math.min(wlen, other.wlen); long [] thisArr = this.bits; long [] otherArr = other.bits; while (--idx >= 0) { thisArr[idx] &= ~otherArr[idx]; } } /** * this = this XOR other * @param other The other bitset. */ public void xor(BitSet other) { int newLen = Math.max(wlen, other.wlen); ensureCapacityWords(newLen); long [] thisArr = this.bits; long [] otherArr = other.bits; int pos = Math.min(wlen, other.wlen); while (--pos >= 0) { thisArr[pos] ^= otherArr[pos]; } if (this.wlen < newLen) { System.arraycopy(otherArr, this.wlen, thisArr, this.wlen, newLen - this.wlen); } this.wlen = newLen; } // some BitSet compatibility methods // ** see {@link intersect} */ public void and(BitSet other) { intersect(other); } // ** see {@link union} */ public void or(BitSet other) { union(other); } // ** see {@link andNot} */ public void andNot(BitSet other) { remove(other); } /** * @param other The other bitset. * @return true if the sets have any elements in common */ public boolean intersects(BitSet other) { int pos = Math.min(this.wlen, other.wlen); long [] thisArr = this.bits; long [] otherArr = other.bits; while (--pos >= 0) { if ((thisArr[pos] & otherArr[pos]) != 0) return true; } return false; } /** * Expand the long[] with the size given as a number of words (64 bit longs). * getNumWords() is unchanged by this call. * * @param numWords The size to expand to (64-bit long words) */ public void ensureCapacityWords(int numWords) { if (bits.length < numWords) { bits = grow(bits, numWords); } } public static long [] grow(long [] array, int minSize) { if (array.length < minSize) { long [] newArray = new long [getNextSize(minSize)]; System.arraycopy(array, 0, newArray, 0, array.length); return newArray; } else return array; } public static int getNextSize(int targetSize) { /* * This over-allocates proportional to the list size, making room for additional * growth. The over-allocation is mild, but is enough to give linear-time * amortized behavior over a long sequence of appends() in the presence of a * poorly-performing system realloc(). The growth pattern is: 0, 4, 8, 16, 25, 35, * 46, 58, 72, 88, ... */ return (targetSize >> 3) + (targetSize < 9 ? 3 : 6) + targetSize; } /** * Ensure that the long[] is big enough to hold numBits, expanding it if necessary. * getNumWords() is unchanged by this call. * * @param numBits The number of bits to expand to */ public void ensureCapacity(long numBits) { ensureCapacityWords(bits2words(numBits)); } /** * Lowers {@link #wlen}, the number of words in use, by checking for trailing zero * words. */ public void trimTrailingZeros() { int idx = wlen - 1; while (idx >= 0 && bits[idx] == 0) idx--; wlen = idx + 1; } /* * returns the number of 64 bit words it would take to hold numBits */ public static int bits2words(long numBits) { return (int) (((numBits - 1) >>> 6) + 1); } /* returns true if both sets have the same bits set */ @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof BitSet)) return false; BitSet a; BitSet b = (BitSet) o; // make a the larger set. if (b.wlen > this.wlen) { a = b; b = this; } else { a = this; } // check for any set bits out of the range of b for (int i = a.wlen - 1; i >= b.wlen; i--) { if (a.bits[i] != 0) return false; } for (int i = b.wlen - 1; i >= 0; i--) { if (a.bits[i] != b.bits[i]) return false; } return true; } @Override public int hashCode() { // Start with a zero hash and use a mix that results in zero if the input is zero. // This effectively truncates trailing zeros without an explicit check. long h = 0; for (int i = bits.length; --i >= 0;) { h ^= bits[i]; h = (h << 1) | (h >>> 63); // rotate left } // fold leftmost bits into right and add a constant to prevent // empty sets from returning 0, which is too common. return (int) ((h >> 32) ^ h) + 0x98761234; } @Override public String toString() { long bit = nextSetBit(0); if (bit < 0) { return "{}"; } final StringBuilder builder = new StringBuilder(); builder.append("{"); builder.append(Long.toString(bit)); while ((bit = nextSetBit(bit + 1)) >= 0) { builder.append(", "); builder.append(Long.toString(bit)); } builder.append("}"); return builder.toString(); } /** * Returns a view over this bitset data compatible with {@link IntLookupContainer}. A new * object is always returned, but its methods reflect the current state of the bitset * (the view is not a snapshot). * *

Methods of the returned {@link IntLookupContainer} may throw a {@link RuntimeException} * if the cardinality of this bitset exceeds the int range. * * @return The view of this bitset as {@link IntLookupContainer}. */ public IntLookupContainer asIntLookupContainer() { return new IntLookupContainer() { @Override public int size() { return getCurrentCardinality(); } @Override public boolean isEmpty() { return BitSet.this.isEmpty(); } @Override public Iterator iterator() { return new Iterator() { private long nextBitSet = BitSet.this.nextSetBit(0); private final IntCursor cursor = new IntCursor(); @Override public boolean hasNext() { return nextBitSet >= 0; } @Override public IntCursor next() { final long value = nextBitSet; if (value < 0) throw new NoSuchElementException(); if (value > Integer.MAX_VALUE) throw new RuntimeException("BitSet range larger than maximum positive integer."); nextBitSet = BitSet.this.nextSetBit(value + 1); cursor.index = cursor.value = (int) value; return cursor; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public int [] toArray() { final int [] data = new int [getCurrentCardinality()]; final BitSetIterator i = BitSet.this.iterator(); for (int j = 0, bit = i.nextSetBit(); bit >= 0; bit = i.nextSetBit()) { data[j++] = bit; } return data; } @Override public T forEach(T predicate) { final BitSetIterator i = BitSet.this.iterator(); for (int bit = i.nextSetBit(); bit >= 0; bit = i.nextSetBit()) { if (predicate.apply(bit) == false) break; } return predicate; } @Override public T forEach(T procedure) { final BitSetIterator i = BitSet.this.iterator(); for (int bit = i.nextSetBit(); bit >= 0; bit = i.nextSetBit()) { procedure.apply(bit); } return procedure; } @Override public boolean contains(int index) { return index < 0 || BitSet.this.get(index); } /** * Rounds the bitset's cardinality to an integer or throws a * {@link RuntimeException} if the cardinality exceeds maximum int range. */ private int getCurrentCardinality() { long cardinality = BitSet.this.cardinality(); if (cardinality > Integer.MAX_VALUE) throw new RuntimeException("Bitset is larger than maximum positive integer: " + cardinality); return (int) cardinality; } }; } /** * Returns a view over this bitset data compatible with {@link LongLookupContainer}. A new * object is always returned, but its methods reflect the current state of the bitset * (the view is not a snapshot). * * @return The view of this bitset as {@link LongLookupContainer}. */ public LongLookupContainer asLongLookupContainer() { return new LongLookupContainer() { @Override public int size() { return getCurrentCardinality(); } @Override public boolean isEmpty() { return BitSet.this.isEmpty(); } @Override public Iterator iterator() { return new Iterator() { private long nextBitSet = BitSet.this.nextSetBit(0); private final LongCursor cursor = new LongCursor(); @Override public boolean hasNext() { return nextBitSet >= 0; } @Override public LongCursor next() { final long value = nextBitSet; if (value < 0) throw new NoSuchElementException(); nextBitSet = BitSet.this.nextSetBit(value + 1); cursor.index = (int) value; cursor.value = value; return cursor; } @Override public void remove() { throw new UnsupportedOperationException(); } }; } @Override public long [] toArray() { final long [] data = new long [getCurrentCardinality()]; final BitSet bset = BitSet.this; int j = 0; for (long bit = bset.nextSetBit((long) 0); bit >= 0; bit = bset.nextSetBit(bit + 1)) { data[j++] = bit; } return data; } @Override public T forEach(T predicate) { final BitSet bset = BitSet.this; for (long bit = bset.nextSetBit((long) 0); bit >= 0; bit = bset.nextSetBit(bit + 1)) { if (predicate.apply(bit) == false) break; } return predicate; } @Override public T forEach(T procedure) { final BitSet bset = BitSet.this; for (long bit = bset.nextSetBit((long) 0); bit >= 0; bit = bset.nextSetBit(bit + 1)) { procedure.apply(bit); } return procedure; } @Override public boolean contains(long index) { return index < 0 || BitSet.this.get(index); } /** * Rounds the bitset's cardinality to an integer or throws a * {@link RuntimeException} if the cardinality exceeds maximum int range. */ private int getCurrentCardinality() { long cardinality = BitSet.this.cardinality(); if (cardinality > Integer.MAX_VALUE) throw new RuntimeException("Bitset is larger than maximum positive integer: " + cardinality); return (int) cardinality; } }; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/BitSetIterator.java000066400000000000000000000131001300364116400257700ustar00rootroot00000000000000 /* * Repackaged from org.apache.lucene.util.OpenBitSet (Lucene). * svn rev. 893130, http://svn.apache.org/repos/asf/lucene/java/trunk/ * * Minor changes in class hierarchy, removed serialization. */ /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.carrotsearch.hppc; /** * An iterator to iterate over set bits in an BitSet. This is faster than nextSetBit() for * iterating over the complete set of bits, especially when the density of the bits set is * high. */ public class BitSetIterator { // The General Idea: instead of having an array per byte that has // the offsets of the next set bit, that array could be // packed inside a 32 bit integer (8 4 bit numbers). That // should be faster than accessing an array for each index, and // the total array size is kept smaller (256*sizeof(int))=1K final static int[] bitlist={ 0x0, 0x1, 0x2, 0x21, 0x3, 0x31, 0x32, 0x321, 0x4, 0x41, 0x42, 0x421, 0x43, 0x431, 0x432, 0x4321, 0x5, 0x51, 0x52, 0x521, 0x53, 0x531, 0x532, 0x5321, 0x54, 0x541, 0x542, 0x5421, 0x543, 0x5431, 0x5432, 0x54321, 0x6, 0x61, 0x62, 0x621, 0x63, 0x631, 0x632, 0x6321, 0x64, 0x641, 0x642, 0x6421, 0x643, 0x6431, 0x6432, 0x64321, 0x65, 0x651, 0x652, 0x6521, 0x653, 0x6531, 0x6532, 0x65321, 0x654, 0x6541, 0x6542, 0x65421, 0x6543, 0x65431, 0x65432, 0x654321, 0x7, 0x71, 0x72, 0x721, 0x73, 0x731, 0x732, 0x7321, 0x74, 0x741, 0x742, 0x7421, 0x743, 0x7431, 0x7432, 0x74321, 0x75, 0x751, 0x752, 0x7521, 0x753, 0x7531, 0x7532, 0x75321, 0x754, 0x7541, 0x7542, 0x75421, 0x7543, 0x75431, 0x75432, 0x754321, 0x76, 0x761, 0x762, 0x7621, 0x763, 0x7631, 0x7632, 0x76321, 0x764, 0x7641, 0x7642, 0x76421, 0x7643, 0x76431, 0x76432, 0x764321, 0x765, 0x7651, 0x7652, 0x76521, 0x7653, 0x76531, 0x76532, 0x765321, 0x7654, 0x76541, 0x76542, 0x765421, 0x76543, 0x765431, 0x765432, 0x7654321, 0x8, 0x81, 0x82, 0x821, 0x83, 0x831, 0x832, 0x8321, 0x84, 0x841, 0x842, 0x8421, 0x843, 0x8431, 0x8432, 0x84321, 0x85, 0x851, 0x852, 0x8521, 0x853, 0x8531, 0x8532, 0x85321, 0x854, 0x8541, 0x8542, 0x85421, 0x8543, 0x85431, 0x85432, 0x854321, 0x86, 0x861, 0x862, 0x8621, 0x863, 0x8631, 0x8632, 0x86321, 0x864, 0x8641, 0x8642, 0x86421, 0x8643, 0x86431, 0x86432, 0x864321, 0x865, 0x8651, 0x8652, 0x86521, 0x8653, 0x86531, 0x86532, 0x865321, 0x8654, 0x86541, 0x86542, 0x865421, 0x86543, 0x865431, 0x865432, 0x8654321, 0x87, 0x871, 0x872, 0x8721, 0x873, 0x8731, 0x8732, 0x87321, 0x874, 0x8741, 0x8742, 0x87421, 0x8743, 0x87431, 0x87432, 0x874321, 0x875, 0x8751, 0x8752, 0x87521, 0x8753, 0x87531, 0x87532, 0x875321, 0x8754, 0x87541, 0x87542, 0x875421, 0x87543, 0x875431, 0x875432, 0x8754321, 0x876, 0x8761, 0x8762, 0x87621, 0x8763, 0x87631, 0x87632, 0x876321, 0x8764, 0x87641, 0x87642, 0x876421, 0x87643, 0x876431, 0x876432, 0x8764321, 0x8765, 0x87651, 0x87652, 0x876521, 0x87653, 0x876531, 0x876532, 0x8765321, 0x87654, 0x876541, 0x876542, 0x8765421, 0x876543, 0x8765431, 0x8765432, 0x87654321 }; /***** the python code that generated bitlist def bits2int(val): arr=0 for shift in range(8,0,-1): if val & 0x80: arr = (arr << 4) | shift val = val << 1 return arr def int_table(): tbl = [ hex(bits2int(val)).strip('L') for val in range(256) ] return ','.join(tbl) ******/ // hmmm, what about an iterator that finds zeros though, // or a reverse iterator... should they be separate classes // for efficiency, or have a common root interface? (or // maybe both? could ask for a SetBitsIterator, etc... private final long[] arr; private final int words; private int i=-1; private long word; private int wordShift; private int indexArray; public BitSetIterator(BitSet obs) { this(obs.bits, obs.wlen); } public BitSetIterator(long[] bits, int numWords) { arr = bits; words = numWords; } // 64 bit shifts private void shift() { if ((int)word ==0) {wordShift +=32; word = word >>>32; } if ((word & 0x0000FFFF) == 0) { wordShift +=16; word >>>=16; } if ((word & 0x000000FF) == 0) { wordShift +=8; word >>>=8; } indexArray = bitlist[(int)word & 0xff]; } public final static int NO_MORE = -1; public int nextSetBit() { if (indexArray == 0) { if (word != 0) { word >>>= 8; wordShift += 8; } while (word == 0) { if (++i >= words) { return NO_MORE; } word = arr[i]; wordShift = -1; // loop invariant code motion should move this } // after the first time, should I go with a linear search, or // stick with the binary search in shift? shift(); } int bitIndex = (indexArray & 0x0f) + wordShift; indexArray >>>= 4; // should i<<6 be cached as a separate variable? // it would only save one cycle in the best circumstances. return (i<<6) + bitIndex; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/BitUtil.java000066400000000000000000000073001300364116400244450ustar00rootroot00000000000000 /* * Repackaged from org.apache.lucene.util.OpenBitSet (Lucene). * svn rev. 1479633, https://svn.apache.org/repos/asf/lucene/dev/trunk * * Minor changes in class hierarchy, removed serialization. */ /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.carrotsearch.hppc; /** * A variety of high efficiency bit twiddling routines. */ final class BitUtil { private BitUtil() {} // no instance // The pop methods used to rely on bit-manipulation tricks for speed but it // turns out that it is faster to use the Long.bitCount method (which is an // intrinsic since Java 6u18) in a naive loop, see LUCENE-2221 /** Returns the number of set bits in an array of longs. */ public static long pop_array(long[] arr, int wordOffset, int numWords) { long popCount = 0; for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) { popCount += Long.bitCount(arr[i]); } return popCount; } /** Returns the popcount or cardinality of the two sets after an intersection. * Neither array is modified. */ public static long pop_intersect(long[] arr1, long[] arr2, int wordOffset, int numWords) { long popCount = 0; for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) { popCount += Long.bitCount(arr1[i] & arr2[i]); } return popCount; } /** Returns the popcount or cardinality of the union of two sets. * Neither array is modified. */ public static long pop_union(long[] arr1, long[] arr2, int wordOffset, int numWords) { long popCount = 0; for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) { popCount += Long.bitCount(arr1[i] | arr2[i]); } return popCount; } /** Returns the popcount or cardinality of A & ~B. * Neither array is modified. */ public static long pop_andnot(long[] arr1, long[] arr2, int wordOffset, int numWords) { long popCount = 0; for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) { popCount += Long.bitCount(arr1[i] & ~arr2[i]); } return popCount; } /** Returns the popcount or cardinality of A ^ B * Neither array is modified. */ public static long pop_xor(long[] arr1, long[] arr2, int wordOffset, int numWords) { long popCount = 0; for (int i = wordOffset, end = wordOffset + numWords; i < end; ++i) { popCount += Long.bitCount(arr1[i] ^ arr2[i]); } return popCount; } /** returns the next highest power of two, or the current value if it's already a power of two or zero*/ public static int nextHighestPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } /** returns the next highest power of two, or the current value if it's already a power of two or zero*/ public static long nextHighestPowerOfTwo(long v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v |= v >> 32; v++; return v; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/BoundedProportionalArraySizingStrategy.java000066400000000000000000000065421300364116400327770ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.ArrayList; /** * Array resizing proportional to the current buffer size, optionally kept * within the given minimum and maximum growth limits. Java's {@link ArrayList} * uses: * *

 * minGrow = 1
 * maxGrow = Integer.MAX_VALUE (unbounded)
 * growRatio = 1.5f
 * 
*/ public final class BoundedProportionalArraySizingStrategy implements ArraySizingStrategy { /** * Maximum allocable array length (approximately the largest positive integer * decreased by the array's object header). */ public static final int MAX_ARRAY_LENGTH = Integer.MAX_VALUE - /* aligned array header + slack */32; /** Minimum grow count. */ public final static int DEFAULT_MIN_GROW_COUNT = 10; /** Maximum grow count (unbounded). */ public final static int DEFAULT_MAX_GROW_COUNT = MAX_ARRAY_LENGTH; /** Default resize is by half the current buffer's size. */ public final static float DEFAULT_GROW_RATIO = 1.5f; /** Minimum number of elements to grow, if limit exceeded. */ public final int minGrowCount; /** Maximum number of elements to grow, if limit exceeded. */ public final int maxGrowCount; /** * The current buffer length is multiplied by this ratio to get the first * estimate for the new size. To double the size of the current buffer, for * example, set to 2. */ public final float growRatio; /** * Create the default sizing strategy. */ public BoundedProportionalArraySizingStrategy() { this(DEFAULT_MIN_GROW_COUNT, DEFAULT_MAX_GROW_COUNT, DEFAULT_GROW_RATIO); } /** * Create the sizing strategy with custom policies. * * @param minGrow Minimum number of elements to grow by when expanding. * @param maxGrow Maximum number of elements to grow by when expanding. * @param ratio The ratio of expansion compared to the previous buffer size. */ public BoundedProportionalArraySizingStrategy(int minGrow, int maxGrow, float ratio) { assert minGrow >= 1 : "Min grow must be >= 1."; assert maxGrow >= minGrow : "Max grow must be >= min grow."; assert ratio >= 1f : "Growth ratio must be >= 1 (was " + ratio + ")."; this.minGrowCount = minGrow; this.maxGrowCount = maxGrow; this.growRatio = ratio - 1.0f; } /** * Grow according to {@link #growRatio}, {@link #minGrowCount} and * {@link #maxGrowCount}. * * @param currentBufferLength The current length of the buffer. * @param elementsCount The number of elements stored in the buffer. * @param expectedAdditions The number of expected additions to the buffer. * @return New buffer size. */ public int grow(int currentBufferLength, int elementsCount, int expectedAdditions) { long growBy = (long) ((long) currentBufferLength * growRatio); growBy = Math.max(growBy, minGrowCount); growBy = Math.min(growBy, maxGrowCount); long growTo = Math.min(MAX_ARRAY_LENGTH, growBy + currentBufferLength); long newSize = Math.max((long) elementsCount + expectedAdditions, growTo); if (newSize > MAX_ARRAY_LENGTH) { throw new BufferAllocationException( "Java array size exceeded (current length: %d, elements: %d, expected additions: %d)", currentBufferLength, elementsCount, expectedAdditions); } return (int) newSize; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/BufferAllocationException.java000066400000000000000000000017621300364116400301750ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.IllegalFormatException; import java.util.Locale; @SuppressWarnings("serial") public class BufferAllocationException extends RuntimeException { public BufferAllocationException(String message) { super(message); } public BufferAllocationException(String message, Object... args) { this(message, null, args); } public BufferAllocationException(String message, Throwable t, Object... args) { super(formatMessage(message, t, args), t); } private static String formatMessage(String message, Throwable t, Object... args) { try { return String.format(Locale.ROOT, message, args); } catch (IllegalFormatException e) { BufferAllocationException substitute = new BufferAllocationException(message + " [ILLEGAL FORMAT, ARGS SUPPRESSED]"); if (t != null) { substitute.addSuppressed(t); } substitute.addSuppressed(e); throw substitute; } } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/Containers.java000066400000000000000000000046401300364116400252020ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; /** * Constants used as defaults in containers. * * @see HashContainers */ public final class Containers { /** * The default number of expected elements for containers. */ public final static int DEFAULT_EXPECTED_ELEMENTS = 4; /** * External initial seed value. We do not care about multiple assignments * so not volatile. * * @see #randomSeed64() */ private static String testsSeedProperty; /** * Unique marker for {@link #testsSeedProperty}. */ private final static String NOT_AVAILABLE = new String(); private Containers() {} /** * Provides a (possibly) random initial seed for randomized stuff. * * If tests.seed property is available and accessible, * the returned value will be derived from the value of that property * and will be constant to ensure reproducibility in presence of the * randomized testing package. * * @see "https://github.com/carrotsearch/randomizedtesting" */ @SuppressForbidden public static long randomSeed64() { if (testsSeedProperty == null) { try { testsSeedProperty = java.security.AccessController.doPrivileged(new PrivilegedAction() { @Override public String run() { return System.getProperty("tests.seed", NOT_AVAILABLE); } }); } catch (SecurityException e) { // If failed on security exception, don't panic. testsSeedProperty = NOT_AVAILABLE; Logger.getLogger(Containers.class.getName()) .log(Level.INFO, "Failed to read 'tests.seed' property for initial random seed.", e); } } long initialSeed; if (testsSeedProperty != NOT_AVAILABLE) { initialSeed = testsSeedProperty.hashCode(); } else { // Mix something that is changing over time (nanoTime) // ... with something that is thread-local and relatively unique // even for very short time-spans (new Object's address from a TLAB). initialSeed = System.nanoTime() ^ System.identityHashCode(new Object()); } return BitMixer.mix64(initialSeed); } /** * Reset state for tests. */ static void test$reset() { testsSeedProperty = null; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/HashContainers.java000066400000000000000000000061551300364116400260110ustar00rootroot00000000000000package com.carrotsearch.hppc; public final class HashContainers { /** * Maximum array size for hash containers (power-of-two and still * allocable in Java, not a negative int). */ public final static int MAX_HASH_ARRAY_LENGTH = 0x80000000 >>> 1; /** * Minimum hash buffer size. */ public final static int MIN_HASH_ARRAY_LENGTH = 4; /** * Default load factor. */ public final static float DEFAULT_LOAD_FACTOR = 0.75f; /** * Minimal sane load factor (99 empty slots per 100). */ public final static float MIN_LOAD_FACTOR = 1 / 100.0f; /** * Maximum sane load factor (1 empty slot per 100). */ public final static float MAX_LOAD_FACTOR = 99 / 100.0f; /** * Compute and return the maximum number of elements (inclusive) * that can be stored in a hash container for a given load factor. */ public static int maxElements(double loadFactor) { checkLoadFactor(loadFactor, 0, 1); return expandAtCount(MAX_HASH_ARRAY_LENGTH, loadFactor) - 1; } /** */ static int minBufferSize(int elements, double loadFactor) { if (elements < 0) { throw new IllegalArgumentException( "Number of elements must be >= 0: " + elements); } long length = (long) Math.ceil(elements / loadFactor); if (length == elements) { length++; } length = Math.max(MIN_HASH_ARRAY_LENGTH, BitUtil.nextHighestPowerOfTwo(length)); if (length > MAX_HASH_ARRAY_LENGTH) { throw new BufferAllocationException( "Maximum array size exceeded for this load factor (elements: %d, load factor: %f)", elements, loadFactor); } return (int) length; } /** */ static int nextBufferSize(int arraySize, int elements, double loadFactor) { assert checkPowerOfTwo(arraySize); if (arraySize == MAX_HASH_ARRAY_LENGTH) { throw new BufferAllocationException( "Maximum array size exceeded for this load factor (elements: %d, load factor: %f)", elements, loadFactor); } return (int) arraySize << 1; } /** */ static int expandAtCount(int arraySize, double loadFactor) { assert checkPowerOfTwo(arraySize); // Take care of hash container invariant (there has to be at least one empty slot to ensure // the lookup loop finds either the element or an empty slot). return Math.min(arraySize - 1, (int) Math.ceil(arraySize * loadFactor)); } /** */ static void checkLoadFactor(double loadFactor, double minAllowedInclusive, double maxAllowedInclusive) { if (loadFactor < minAllowedInclusive || loadFactor > maxAllowedInclusive) { throw new BufferAllocationException( "The load factor should be in range [%.2f, %.2f]: %f", minAllowedInclusive, maxAllowedInclusive, loadFactor); } } /** */ static boolean checkPowerOfTwo(int arraySize) { // These are internals, we can just assert without retrying. assert arraySize > 1; assert BitUtil.nextHighestPowerOfTwo(arraySize) == arraySize; return true; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/HashOrderMixing.java000066400000000000000000000112651300364116400261310ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.security.PrivilegedAction; import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.Logger; /** * Factory methods to acquire the most common types of * {@link HashOrderMixingStrategy}. * * @see HashOrderMixingStrategy */ public final class HashOrderMixing { public static final String PROPERTY_BIT_MIXER = "hppc.bitmixer"; private static Strategy strategy; public enum Strategy implements Callable { RANDOM { @Override public HashOrderMixingStrategy call() { return randomized(); } }, DETERMINISTIC { @Override public HashOrderMixingStrategy call() { return deterministic(); } }, NONE { @Override public HashOrderMixingStrategy call() { return none(); } }; } private HashOrderMixing() {} /** * @see #deterministic() */ private static final HashOrderMixingStrategy DETERMINISTIC = new HashOrderMixingStrategy() { @Override public int newKeyMixer(int newContainerBufferSize) { return BitMixer.mix32(newContainerBufferSize); } @Override public HashOrderMixingStrategy clone() { return this; } }; /** * Returns a randomized {@link HashOrderMixingStrategy} that issues unique * per-container seed. This minimizes the chances of hash distribution conflicts. */ public static HashOrderMixingStrategy randomized() { return RandomizedHashOrderMixer.INSTANCE; } /** * A constant {@link HashOrderMixingStrategy}. This is useful if one needs to have * deterministic key distribution but wishes to control it manually. * * Do not use the same constant for more than one container. * * Consider using {@linkplain ObjectScatterSet scatter maps or sets} instead * of constant hash order mixer. */ public static HashOrderMixingStrategy constant(final long seed) { return new HashOrderMixingStrategy() { @Override public int newKeyMixer(int newContainerBufferSize) { return (int) BitMixer.mix64(newContainerBufferSize ^ seed); } @Override public HashOrderMixingStrategy clone() { return this; } }; } /** * Deterministic {@link HashOrderMixingStrategy} will reorder keys depending * on the size of the container's buffer. * * This is inherently unsafe with hash containers using linear conflict * addressing. The only use case when this can be useful is to count/ collect * unique keys (for which scatter tables should be used). * * @deprecated Permanently deprecated as a warning signal. */ @Deprecated public static HashOrderMixingStrategy deterministic() { return DETERMINISTIC; } /** * This strategy does not change the hash order of keys at all. This * is inherently unsafe with hash containers using linear conflict * addressing. The only use case when this can be useful is to count/ collect * unique keys (for which scatter tables should be used). * * @deprecated Permanently deprecated as a warning signal. */ @Deprecated public static HashOrderMixingStrategy none() { return new HashOrderMixingStrategy() { @Override public int newKeyMixer(int newContainerBufferSize) { return 0; } @Override public HashOrderMixingStrategy clone() { return this; } }; } /** * Returns the currently configured default {@link HashOrderMixingStrategy}. */ public static HashOrderMixingStrategy defaultStrategy() { if (strategy == null) { try { String propValue = java.security.AccessController.doPrivileged(new PrivilegedAction() { @Override public String run() { return System.getProperty(PROPERTY_BIT_MIXER); } }); if (propValue != null) { for (Strategy s : Strategy.values()) { if (s.name().equalsIgnoreCase(propValue)) { strategy = s; break; } } } } catch (SecurityException e) { // If failed on security exception, don't panic. Logger.getLogger(Containers.class.getName()) .log(Level.INFO, "Failed to read 'tests.seed' property for initial random seed.", e); } if (strategy == null) { strategy = Strategy.RANDOM; } } try { return strategy.call(); } catch (Exception e) { throw new RuntimeException(e); // Effectively unreachable. } } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/HashOrderMixingStrategy.java000066400000000000000000000020701300364116400276460ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * Hash order mixing strategy implementations should provide an, ideally, * random integer that is later XORed with the hash of a given key before * the slot lookup in associative arrays. * *

* Why good hash mixing is important is explained in the * differences between hash * and scatter sets. *

* * @see ObjectHashSet#hashKey * @see ObjectObjectHashMap#hashKey * * @see HashOrderMixing */ public interface HashOrderMixingStrategy extends Cloneable { /** * A new key mixer value. The value can be derived from the new buffer size of the * container, but preferably should be random and unique. * * @param newContainerBufferSize */ public int newKeyMixer(int newContainerBufferSize); /** * @return Return a clone of this strategy. This should use a different mixing * because cloned containers should have a different hash ordering. */ public HashOrderMixingStrategy clone(); } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/ObjectIdentityHashSet.java000066400000000000000000000047071300364116400273010ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.HashContainers.*; import static com.carrotsearch.hppc.Containers.*; /** * A reference-equality (identity) hash set. */ public class ObjectIdentityHashSet extends ObjectHashSet { /** * New instance with sane defaults. */ public ObjectIdentityHashSet() { this(DEFAULT_EXPECTED_ELEMENTS, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. */ public ObjectIdentityHashSet(int expectedElements) { this(expectedElements, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. */ public ObjectIdentityHashSet(int expectedElements, double loadFactor) { this(expectedElements, loadFactor, HashOrderMixing.randomized()); } /** * New instance with the provided defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause a rehash (inclusive). * @param loadFactor * The load factor for internal buffers. Insane load factors (zero, full capacity) * are rejected by {@link #verifyLoadFactor(double)}. * @param orderMixer * Hash key order mixing strategy. See {@link HashOrderMixing} for predefined * implementations. Use constant mixers only if you understand the potential * consequences. */ public ObjectIdentityHashSet(int expectedElements, double loadFactor, HashOrderMixingStrategy orderMixer) { this.orderMixer = orderMixer; this.loadFactor = verifyLoadFactor(loadFactor); ensureCapacity(expectedElements); } /** * New instance copying elements from another {@link ObjectContainer}. */ public ObjectIdentityHashSet(ObjectContainer container) { this(container.size()); addAll(container); } @Override protected int hashKey(KType key) { assert key != null; // Handled as a special case (empty slot marker). return BitMixer.mix(key, this.keyMixer); } @Override protected boolean equals(Object v1, Object v2) { return v1 == v2; } /** * Create a set from a variable number of arguments or an array of * KType. The elements are copied from the argument to the * internal buffer. */ @SafeVarargs public static ObjectIdentityHashSet from(KType... elements) { final ObjectIdentityHashSet set = new ObjectIdentityHashSet(elements.length); set.addAll(elements); return set; } }hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/Preallocable.java000066400000000000000000000007051300364116400254600ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * Anything that can preallocate buffers given prior knowledge of the number of * stored elements. */ public interface Preallocable { /** * Ensure this container can hold at least the given number of elements * without resizing its buffers. * * @param expectedElements * The total number of elements, inclusive. */ public void ensureCapacity(int expectedElements); } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/RandomizedHashOrderMixer.java000066400000000000000000000015241300364116400277740ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.concurrent.atomic.AtomicLong; /** * Randomized hash order. Does not guarantee deterministic hash ordering between * runs. In fact, it tries hard to avoid such guarantee. */ public final class RandomizedHashOrderMixer implements HashOrderMixingStrategy { public final static RandomizedHashOrderMixer INSTANCE = new RandomizedHashOrderMixer(); protected final AtomicLong seedMixer; public RandomizedHashOrderMixer() { this(Containers.randomSeed64()); } public RandomizedHashOrderMixer(long seed) { seedMixer = new AtomicLong(seed); } @Override public int newKeyMixer(int newContainerBufferSize) { return (int) BitMixer.mix64(seedMixer.incrementAndGet()); } @Override public HashOrderMixingStrategy clone() { return this; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/SuppressForbidden.java000066400000000000000000000006631300364116400265370ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Suppresses forbidden-API checks. */ @Retention(RetentionPolicy.CLASS) @Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE }) public @interface SuppressForbidden { } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/XorShift128P.java000066400000000000000000000024771300364116400252240ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Random; /** * A fast pseudo-random number generator. For simplicity, we do not implement all of {@link Random} methods. * * @see "http://xorshift.di.unimi.it/" * @see "http://xorshift.di.unimi.it/xorshift128plus.c" */ public class XorShift128P { /* * 128 bits of state. */ private long state0, state1; public XorShift128P(long seed) { state0 = notZero(BitMixer.mix64(seed)); state1 = notZero(BitMixer.mix64(seed + 1)); } public XorShift128P() { this(Containers.randomSeed64()); } public long nextLong() { long s1 = state0; long s0 = state1; state0 = s0; s1 ^= s1 << 23; return (state1 = (s1 ^ s0 ^ (s1 >>> 17) ^ (s0 >>> 26))) + s0; } public int nextInt() { return (int) nextLong(); } private static long notZero(long value) { return value == 0 ? 0xdeadbeefbabeL : value; } public int nextInt(int bound) { if (bound <= 0) { throw new IllegalArgumentException(); } int r = (nextInt() >>> 1); int m = bound - 1; if ((bound & m) == 0) { r = (int)((bound * (long) r) >> 31); } else { for (int u = r; u - (r = u % bound) + m < 0; u = nextInt() >>> 1) { } } return r; } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/sorting/000077500000000000000000000000001300364116400237135ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/sorting/IndirectComparator.java000066400000000000000000000104341300364116400303510ustar00rootroot00000000000000package com.carrotsearch.hppc.sorting; import java.util.Comparator; /** * Compare objects at two given indices and return the result of their * comparison consistent with {@link Comparator}'s contract. *

* Beware of the return (int - int) idiom, it is usually * broken if arbitrary numbers can appear on input. Use regular comparison * operations - they are very fast anyway. */ public interface IndirectComparator { /** * See class documentation. */ public int compare(int indexA, int indexB); /** * A natural-order comparator for integers. */ public static class AscendingIntComparator implements IndirectComparator { private final int[] array; public AscendingIntComparator(int[] array) { this.array = array; } public int compare(int indexA, int indexB) { final int a = array[indexA]; final int b = array[indexB]; if (a < b) return -1; if (a > b) return 1; return 0; } } /** * A reverse-order comparator for integers. */ public static class DescendingIntComparator extends AscendingIntComparator { public DescendingIntComparator(int[] array) { super(array); } public final int compare(int indexA, int indexB) { return -super.compare(indexA, indexB); } } /** * A natural-order comparator for integers. */ public static class AscendingShortComparator implements IndirectComparator { private final short[] array; public AscendingShortComparator(short[] array) { this.array = array; } public int compare(int indexA, int indexB) { final short a = array[indexA]; final short b = array[indexB]; if (a < b) return -1; if (a > b) return 1; return 0; } } /** * A reverse-order comparator for shorts. */ public static class DescendingShortComparator extends AscendingShortComparator { public DescendingShortComparator(short[] array) { super(array); } public final int compare(int indexA, int indexB) { return -super.compare(indexA, indexB); } } /** * A natural-order comparator for doubles. */ public static class AscendingDoubleComparator implements IndirectComparator { private final double[] array; public AscendingDoubleComparator(double[] array) { this.array = array; } public int compare(int indexA, int indexB) { final double a = array[indexA]; final double b = array[indexB]; if (a < b) return -1; if (a > b) return 1; return 0; } } /** * A reverse-order comparator for doubles. */ public static class DescendingDoubleComparator extends AscendingDoubleComparator { public DescendingDoubleComparator(double[] array) { super(array); } public final int compare(int indexA, int indexB) { return -super.compare(indexA, indexB); } } /** * A natural-order comparator for floats. */ public static class AscendingFloatComparator implements IndirectComparator { private final float[] array; public AscendingFloatComparator(float[] array) { this.array = array; } public int compare(int indexA, int indexB) { final float a = array[indexA]; final float b = array[indexB]; if (a < b) return -1; if (a > b) return 1; return 0; } } /** * A reverse-order comparator for floats. */ public static class DescendingFloatComparator extends AscendingFloatComparator { public DescendingFloatComparator(float[] array) { super(array); } public final int compare(int indexA, int indexB) { return -super.compare(indexA, indexB); } } /** * A delegating comparator for object types. */ public final static class DelegatingComparator implements IndirectComparator { private final T[] array; private final Comparator delegate; public DelegatingComparator(T[] array, Comparator delegate) { this.array = array; this.delegate = delegate; } public final int compare(int indexA, int indexB) { return delegate.compare(array[indexA], array[indexB]); } @Override public String toString() { return this.getClass().getSimpleName() + " -> " + delegate; } } } hppc-0.7.2/hppc/src/main/java/com/carrotsearch/hppc/sorting/IndirectSort.java000066400000000000000000000075721300364116400272020ustar00rootroot00000000000000package com.carrotsearch.hppc.sorting; import java.util.Comparator; /** * Sorting routines that return an array of sorted indices implied by a given * comparator rather than move elements of whatever the comparator is using for * comparisons. *

* A practical use case for this class is when the index of an array is * meaningful and one wants to acquire the order of values in that array. None * of the methods in Java Collections would provide such functionality directly * and creating a collection of boxed {@link Integer} objects for indices seems * to be too costly. */ public final class IndirectSort { /** * Minimum window length to apply insertion sort in merge sort. */ static int MIN_LENGTH_FOR_INSERTION_SORT = 30; /** * No instantiation. */ private IndirectSort() { // No instantiation. } /** * Returns the order of elements between indices start and * length, as indicated by the given comparator. *

* This routine uses merge sort. It is guaranteed to be stable. *

*/ public static int[] mergesort(int start, int length, IndirectComparator comparator) { final int[] src = createOrderArray(start, length); if (length > 1) { final int[] dst = (int[]) src.clone(); topDownMergeSort(src, dst, 0, length, comparator); return dst; } return src; } /** * Returns the order of elements between indices start and * length, as indicated by the given comparator. * This method is equivalent to calling * {@link #mergesort(int, int, IndirectComparator)} with * {@link IndirectComparator.DelegatingComparator}. *

* This routine uses merge sort. It is guaranteed to be stable. *

*/ public static int[] mergesort(T[] input, int start, int length, Comparator comparator) { return mergesort(start, length, new IndirectComparator.DelegatingComparator(input, comparator)); } /** * Perform a recursive, descending merge sort. * * @param fromIndex * inclusive * @param toIndex * exclusive */ private static void topDownMergeSort(int[] src, int[] dst, int fromIndex, int toIndex, IndirectComparator comp) { if (toIndex - fromIndex <= MIN_LENGTH_FOR_INSERTION_SORT) { insertionSort(fromIndex, toIndex - fromIndex, dst, comp); return; } final int mid = (fromIndex + toIndex) >>> 1; topDownMergeSort(dst, src, fromIndex, mid, comp); topDownMergeSort(dst, src, mid, toIndex, comp); /* * Both splits in of src are now sorted. */ if (comp.compare(src[mid - 1], src[mid]) <= 0) { /* * If the lowest element in upper slice is larger than the highest element in * the lower slice, simply copy over, the data is fully sorted. */ System.arraycopy(src, fromIndex, dst, fromIndex, toIndex - fromIndex); } else { /* * Run a manual merge. */ for (int i = fromIndex, j = mid, k = fromIndex; k < toIndex; k++) { if (j == toIndex || (i < mid && comp.compare(src[i], src[j]) <= 0)) { dst[k] = src[i++]; } else { dst[k] = src[j++]; } } } } /** * Internal insertion sort for ints. */ private static void insertionSort(final int off, final int len, int[] order, IndirectComparator intComparator) { for (int i = off + 1; i < off + len; i++) { final int v = order[i]; int j = i, t; while (j > off && intComparator.compare(t = order[j - 1], v) > 0) { order[j--] = t; } order[j] = v; } } /** * Creates the initial order array. */ private static int[] createOrderArray(final int start, final int length) { final int[] order = new int[length]; for (int i = 0; i < length; i++) { order[i] = start + i; } return order; } } hppc-0.7.2/hppc/src/main/javadoc/000077500000000000000000000000001300364116400165245ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/javadoc/css/000077500000000000000000000000001300364116400173145ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/javadoc/css/1.7/000077500000000000000000000000001300364116400176215ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/javadoc/css/1.7/stylesheet.css000066400000000000000000000270411300364116400225300ustar00rootroot00000000000000@import url('resources/tweaks.css'); /* Javadoc style sheet */ /* Overall document style */ body { background-color:#ffffff; color:#353833; font-family: Trebuchet MS, Arial, Helvetica, sans-serif; margin:0; } a:link, a:visited { text-decoration:none; color:#4c6b87; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4c6b87; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family: "Courier New", Courier, monospace; font-size:1.3em; } h1 { font-size:1.8em; } h2 { font-size:1.5em; } h3 { font-size:1.4em; } h4 { font-size:1.3em; } h5 { font-size:1.2em; } h6 { font-size:1.1em; } ul { list-style-type:disc; } code, tt { font-family: "Courier New", Courier, monospace; font-size:1.2em; } dt code { font-family: "Courier New", Courier, monospace; font-size:1.2em; } table tr td dt code { font-size:1.2em; vertical-align:top; } sup { font-size:.6em; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:.8em; z-index:200; margin-top:-7px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; background-image:url(resources/titlebar.gif); background-position:left top; background-repeat:no-repeat; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-image:url(resources/background.gif); background-repeat:repeat-x; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:1em; margin:0; } .topNav { background-image:url(resources/background.gif); background-repeat:repeat-x; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; } .bottomNav { margin-top:10px; background-image:url(resources/background.gif); background-repeat:repeat-x; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; } .subNav { background-color:#dee3e9; border-bottom:1px solid #9eadc0; float:left; width:100%; overflow:hidden; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding:3px 6px; } ul.subNavList li{ list-style:none; float:left; font-size:90%; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; } .navBarCell1Rev { background-image:url(resources/tab.gif); background-color:#a88834; color:#FFFFFF; margin: auto 5px; border:1px solid #c9aa44; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader h1 { font-size:1.3em; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 25px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:1.2em; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border-top:1px solid #9eadc0; border-bottom:1px solid #9eadc0; margin:0 0 6px -8px; padding:2px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border-top:1px solid #9eadc0; border-bottom:1px solid #9eadc0; margin:0 0 6px -8px; padding:2px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:1.0em; } .indexContainer h2 { font-size:1.1em; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:1.1em; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:10px 0 10px 20px; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:25px; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #9eadc0; background-color:#f9f9f9; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:1px solid #9eadc0; border-top:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; border-bottom:1px solid #9eadc0; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .contentContainer table, .classUseContainer table, .constantValuesContainer table { border-bottom:1px solid #9eadc0; width:100%; } .contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { width:100%; } .contentContainer .description table, .contentContainer .details table { border-bottom:none; } .contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ vertical-align:top; padding-right:20px; } .contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, .contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, .contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, .contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { padding-right:3px; } .overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { position:relative; text-align:left; background-repeat:no-repeat; color:#FFFFFF; font-weight:bold; clear:none; overflow:hidden; padding:0px; margin:0px; } caption a:link, caption a:hover, caption a:active, caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { white-space:nowrap; padding-top:8px; padding-left:8px; display:block; float:left; background-image:url(resources/titlebar.gif); height:18px; } .overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { width:10px; background-image:url(resources/titlebar_end.gif); background-repeat:no-repeat; background-position:top right; position:relative; float:left; } ul.blockList ul.blockList li.blockList table { margin:0 0 12px 0px; width:100%; } .tableSubHeadingColor { background-color: #EEEEFF; } .altColor { background-color:#eeeeef; } .rowColor { background-color:#ffffff; } .overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { text-align:left; padding:3px 3px 3px 7px; } th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { background:#dee3e9; border-top:1px solid #9eadc0; border-bottom:1px solid #9eadc0; text-align:left; padding:3px 3px 3px 7px; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } td.colFirst, th.colFirst { border-left:1px solid #9eadc0; white-space:nowrap; } td.colLast, th.colLast { border-right:1px solid #9eadc0; } td.colOne, th.colOne { border-right:1px solid #9eadc0; border-left:1px solid #9eadc0; } table.overviewSummary { padding:0px; margin-left:0px; } table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, table.overviewSummary td.colOne, table.overviewSummary th.colOne { width:25%; vertical-align:middle; } table.packageSummary td.colFirst, table.overviewSummary th.colFirst { width:25%; vertical-align:middle; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:.9em; } .block { display:block; margin:3px 0 0 0; } .strong { font-weight:bold; } hppc-0.7.2/hppc/src/main/javadoc/css/1.8/000077500000000000000000000000001300364116400176225ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/javadoc/css/1.8/stylesheet.css000066400000000000000000000321171300364116400225310ustar00rootroot00000000000000@import url('resources/tweaks.css'); /* Javadoc style sheet */ /* Overall document style */ body { background-color:#ffffff; color:#353833; font-family: Trebuchet MS, Arial, Helvetica, sans-serif; font-size:12px; margin:0; } a:link, a:visited { text-decoration:none; color:#4A6782; } a:hover, a:focus { text-decoration:none; color:#bb7a2a; } a:active { text-decoration:none; color:#4A6782; } a[name] { color:#353833; } a[name]:hover { text-decoration:none; color:#353833; } pre { font-family: "Courier New", Courier, monospace; font-size:14px; } h1 { font-size:20px; } h2 { font-size:18px; } h3 { font-size:16px; font-style:italic; } h4 { font-size:13px; } h5 { font-size:12px; } h6 { font-size:11px; } ul { list-style-type:disc; } code, tt { font-family: "Courier New", Courier, monospace; font-size:14px; padding-top:4px; margin-top:8px; line-height:1.4em; } dt code { font-family: "Courier New", Courier, monospace; font-size:14px; padding-top:4px; } table tr td dt code { font-family: "Courier New", Courier, monospace; font-size:14px; vertical-align:top; padding-top:4px; } sup { font-size:8px; } /* Document title and Copyright styles */ .clear { clear:both; height:0px; overflow:hidden; } .aboutLanguage { float:right; padding:0px 21px; font-size:11px; z-index:200; margin-top:-9px; } .legalCopy { margin-left:.5em; } .bar a, .bar a:link, .bar a:visited, .bar a:active { color:#FFFFFF; text-decoration:none; } .bar a:hover, .bar a:focus { color:#bb7a2a; } .tab { background-color:#0066FF; color:#ffffff; padding:8px; width:5em; font-weight:bold; } /* Navigation bar styles */ .bar { background-color:#4D7A97; color:#FFFFFF; padding:.8em .5em .4em .8em; height:auto;/*height:1.8em;*/ font-size:11px; margin:0; } .topNav { background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .bottomNav { margin-top:10px; background-color:#4D7A97; color:#FFFFFF; float:left; padding:0; width:100%; clear:right; height:2.8em; padding-top:10px; overflow:hidden; font-size:12px; } .subNav { background-color:#dee3e9; float:left; width:100%; overflow:hidden; font-size:12px; } .subNav div { clear:left; float:left; padding:0 0 5px 6px; text-transform:uppercase; } ul.navList, ul.subNavList { float:left; margin:0 25px 0 0; padding:0; } ul.navList li{ list-style:none; float:left; padding: 5px 6px; text-transform:uppercase; } ul.subNavList li{ list-style:none; float:left; } .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { color:#FFFFFF; text-decoration:none; text-transform:uppercase; } .topNav a:hover, .bottomNav a:hover { text-decoration:none; color:#bb7a2a; text-transform:uppercase; } .navBarCell1Rev { background-color:#F8981D; color:#253441; margin: auto 5px; } .skipNav { position:absolute; top:auto; left:-9999px; overflow:hidden; } /* Page header and footer styles */ .header, .footer { clear:both; margin:0 20px; padding:5px 0 0 0; } .indexHeader { margin:10px; position:relative; } .indexHeader span{ margin-right:15px; } .indexHeader h1 { font-size:13px; } .title { color:#2c4557; margin:10px 0; } .subTitle { margin:5px 0 0 0; } .header ul { margin:0 0 15px 0; padding:0; } .footer ul { margin:20px 0 5px 0; } .header ul li, .footer ul li { list-style:none; font-size:13px; } /* Heading styles */ div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList ul.blockList li.blockList h3 { background-color:#dee3e9; border:1px solid #d0d9e0; margin:0 0 6px -8px; padding:7px 5px; } ul.blockList ul.blockList li.blockList h3 { padding:0; margin:15px 0; } ul.blockList li.blockList h2 { padding:0px 0 20px 0; } /* Page layout container styles */ .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { clear:both; padding:10px 20px; position:relative; } .indexContainer { margin:10px; position:relative; font-size:12px; } .indexContainer h2 { font-size:13px; padding:0 0 3px 0; } .indexContainer ul { margin:0; padding:0; } .indexContainer ul li { list-style:none; padding-top:2px; } .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { font-size:12px; font-weight:bold; margin:10px 0 0 0; color:#4E4E4E; } .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { margin:5px 0 10px 0px; font-size:14px; font-family: "Courier New", Courier, monospace; } .serializedFormContainer dl.nameValue dt { margin-left:1px; font-size:1.1em; display:inline; font-weight:bold; } .serializedFormContainer dl.nameValue dd { margin:0 0 0 1px; font-size:1.1em; display:inline; } /* List styles */ ul.horizontal li { display:inline; font-size:0.9em; } ul.inheritance { margin:0; padding:0; } ul.inheritance li { display:inline; list-style:none; } ul.inheritance li ul.inheritance { margin-left:15px; padding-left:15px; padding-top:1px; } ul.blockList, ul.blockListLast { margin:10px 0 10px 0; padding:0; } ul.blockList li.blockList, ul.blockListLast li.blockList { list-style:none; margin-bottom:15px; line-height:1.4; } ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { padding:0px 20px 5px 10px; border:1px solid #ededed; background-color:#f8f8f8; } ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { padding:0 0 5px 8px; background-color:#ffffff; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { margin-left:0; padding-left:0; padding-bottom:15px; border:none; } ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { list-style:none; border-bottom:none; padding-bottom:0; } table tr td dl, table tr td dl dt, table tr td dl dd { margin-top:0; margin-bottom:1px; } /* Table styles */ .overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary { width:100%; border-left:1px solid #EEE; border-right:1px solid #EEE; border-bottom:1px solid #EEE; } .overviewSummary, .memberSummary { padding:0px; } .overviewSummary caption, .memberSummary caption, .typeSummary caption, .useSummary caption, .constantsSummary caption, .deprecatedSummary caption { position:relative; text-align:left; background-repeat:no-repeat; color:#253441; font-weight:bold; clear:none; overflow:hidden; padding:0px; padding-top:10px; padding-left:1px; margin:0px; white-space:pre; } .overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link, .useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link, .overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover, .useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover, .overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active, .useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active, .overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited, .useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited { color:#FFFFFF; } .overviewSummary caption span, .memberSummary caption span, .typeSummary caption span, .useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; padding-bottom:7px; display:inline-block; float:left; background-color:#F8981D; border: none; height:16px; } .memberSummary caption span.activeTableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#F8981D; height:16px; } .memberSummary caption span.tableTab span { white-space:nowrap; padding-top:5px; padding-left:12px; padding-right:12px; margin-right:3px; display:inline-block; float:left; background-color:#4D7A97; height:16px; } .memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab { padding-top:0px; padding-left:0px; padding-right:0px; background-image:none; float:none; display:inline; } .overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd, .useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd { display:none; width:5px; position:relative; float:left; background-color:#F8981D; } .memberSummary .activeTableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; float:left; background-color:#F8981D; } .memberSummary .tableTab .tabEnd { display:none; width:5px; margin-right:3px; position:relative; background-color:#4D7A97; float:left; } .overviewSummary td, .memberSummary td, .typeSummary td, .useSummary td, .constantsSummary td, .deprecatedSummary td { text-align:left; padding:0px 0px 12px 10px; width:100%; } th.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th, td.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{ vertical-align:top; padding-right:0px; padding-top:8px; padding-bottom:3px; } th.colFirst, th.colLast, th.colOne, .constantsSummary th { background:#dee3e9; text-align:left; padding:8px 3px 3px 7px; } td.colFirst, th.colFirst { white-space:nowrap; font-size:13px; } td.colLast, th.colLast { font-size:13px; } td.colOne, th.colOne { font-size:13px; } .overviewSummary td.colFirst, .overviewSummary th.colFirst, .overviewSummary td.colOne, .overviewSummary th.colOne, .memberSummary td.colFirst, .memberSummary th.colFirst, .memberSummary td.colOne, .memberSummary th.colOne, .typeSummary td.colFirst{ width:25%; vertical-align:top; } td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { font-weight:bold; } .tableSubHeadingColor { background-color:#EEEEFF; } .altColor { background-color:#FFFFFF; } .rowColor { background-color:#EEEEEF; } /* Content styles */ .description pre { margin-top:0; } .deprecatedContent { margin:0; padding:10px 0; } .docSummary { padding:0; } ul.blockList ul.blockList ul.blockList li.blockList h3 { font-style:normal; } div.block { font-size:14px; font-family: Trebuchet MS, Arial, Helvetica, sans-serif; } td.colLast div { padding-top:0px; } td.colLast a { padding-bottom:3px; } /* Formatting effect styles */ .sourceLineNo { color:green; padding:0 30px 0 0; } h1.hidden { visibility:hidden; overflow:hidden; font-size:10px; } .block { display:block; margin:3px 10px 2px 0px; color:#474747; } .deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink, .overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink { font-weight:bold; } .deprecationComment, .emphasizedPhrase, .interfaceName { font-style:italic; } div.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase, div.block div.block span.interfaceName { font-style:normal; } div.contentContainer ul.blockList li.blockList h2{ padding-bottom:0px; } hppc-0.7.2/hppc/src/main/javadoc/overview.html000066400000000000000000000314631300364116400212670ustar00rootroot00000000000000 High Performance Primitive Collections (HPPC) High Performance Primitive Collections (HPPC) library provides typical data structures (lists, stacks, sets and maps) that are generated for all Java primitive types (byte, int, etc.) from a single template to conserve memory and boost performance.

Why HPPC?

The Java Collections package is in many ways excellent, but it cannot be used for primitive types without autoboxing (which kills the runtime performance due to increased memory use and garbage collector overhead).

This library has slightly different design goals than Java Collections (and many other collection packages). For example, the internals of each class are open and subject to free hacking and tuning up to one's wishes.

Why not other primitive collection libraries?

There are a few projects implementing collections over primitive types: fastutil, Koloboke, PCJ, GNU Trove, Apache Primitive Collections.

Historically, some of these libraries were released on commercially forbidding licenses (fastutil) and others appeared to be abandoned (PCJ), so HPPC was created to fill this gap. Since then things have changed quite a lot (fastutil is now Apache-licensed, Koloboke has been released), but HPPC still remains a small memory footprint and does the job. If you require full Java collections compliance, try fastutil, or Koloboke, they are both very, very good.

Assumptions and goals of HPPC

We assume that:

  • The programmer knows what he's doing and may wish to access internal storage of a given collection's class directly (not using predefined iterators, for example).
  • Vast majority of scenarios use single-threaded access. There is little point in repeated verification for concurrent modifications, for example.
  • The programs (algorithms) that use HPPC are unit-tested and regression-tested during development with assertions enabled, so their behavior in production systems does not have to be restrictively verified (we can assume the code should break during testing/ development when assertions are enabled).

From these assumptions stem the following design drivers:

  • Data types in the HPPC are as simple as possible and expose internal storage for any optimisations one may wish to do from within the end-application code.
  • Verification of parameter and state validity is done optionally using assertions. This means that contracts are only checked if requested at runtime (using Java 1.4+ -ea switch). When the algorithm is tested and verified, it can run with no additional overhead from contract checks.
  • We tried to avoid complex interface hierarchies, although certain interfaces are defined for clarity. The programmer should still choose a proper data structure at design-time and should know what he's doing.
  • HPPC provides utilities for the most common tasks like filtering, iterating or joining collections, but these utilities are usually more expensive than implementing a low-level direct access to the data storage (which may be done if needed).
  • There is no special support for data serialization.
  • The implementation is not thread safe and does not attempt to provide fast-failing concurrency problems detection.

Design and implementation assumptions

  • We want HPPC class templates to be implemented as regular Java classes (with generics) so that typical programming tools can be used for development, testing, etc.
  • We want HPPC class templates to be usable as generic-collection classes (for boxed numeric types or any other Object types), but at the same time we want specialized classes to be automatically-generated for primitive-types (to limit memory consumption and boost performance due to JIT optimisations).

Interfaces and their relation to Java Collections API

HPPC is not strictly modeled after Java Collections API, although we did try to make the APIs look similar enough for comfortable use. One particular thing largely missing in HPPC are "view" projections (sublists or views over the collection of keys or values). Certain classes provide such views (like {@linkplain com.carrotsearch.hppc.ObjectObjectHashMap ObjectObjectHashMap}), but for the most part, specific methods are provided that accept ranges or closure-like filters. If performance is still unsatisfactory, the internals of each class are available for direct manipulation.

Rough relationships between Java Collections classes and HPPC classes are presented in the table below.

Relationships between HPPC and Java Collections.
Java Collections HPPC (primitives) HPPC (generics)
bit sets java.util.BitSet BitSet n/a
array-backed lists java.util.ArrayList, java.util.Vector [type]ArrayList {@linkplain com.carrotsearch.hppc.ObjectArrayList ObjectArrayList<T>}
stacks java.util.Stack [type]Stack {@linkplain com.carrotsearch.hppc.ObjectStack ObjectStack<T>}
deques java.util.ArrayDeque [type]ArrayDeque {@linkplain com.carrotsearch.hppc.ObjectArrayDeque ObjectArrayDeque<T>}
hash sets java.util.HashSet [keyType]HashSet
[keyType]ScatterSet
{@linkplain com.carrotsearch.hppc.ObjectHashSet ObjectHashSet<K>}
[keyType]HashSet

{@linkplain com.carrotsearch.hppc.ObjectScatterSet ObjectScatterSet<K>}
[keyType]ScatterSet
hash maps java.util.HashMap [keyType][valueType]HashMap {@linkplain com.carrotsearch.hppc.ObjectObjectHashMap ObjectObjectHashMap<K, V>}
[keyType]ObjectHashMap<V>
Object[valueType]HashMap<K>

{@linkplain com.carrotsearch.hppc.ObjectObjectScatterMap ObjectObjectScatterMap<K, V>}
[keyType]ObjectScatterMap<V>
Object[valueType]ScatterMap<K>

The method-level API of the corresponding types is also similar, but distinct differences exist (consult the JavaDoc of each class).

Scatter or hash (sets and maps)

All key-redistribution containers (maps and sets) implemented in HPPC use open addressing with linear probing. Given the speed of access to CPU caches on modern processors this type of key lookup is the fastest one in practice. However, there is a potential problem with this approach: because keys are distributed in the underlying array at approximately their hash value, when they are copied to another hash container, the number of conflicts to find an empty slot may quickly increase. In the worst case this may lead to an exponential cost of any operation that requires a slot-lookup (adding, removal of a key). The "worst" case is, unfortunately, not as unlikely as it may seem; it's enough that keys are just copied from one container to another, in particular with load factors higher than 0.5.

In HPPC there is a distinction between "hash" and "scatter" sets and maps. Any hash-based structure will try to redistribute keys differently on a per-object basis. So the likelihood of the worst case (described above) is minimized to nearly zero at the cost of slightly increased slot lookup cost and lower CPU cache utilization when keys are copied from one container to another. The "scatter" sets and maps will use a very simple hashing strategy to be as fast as possible, but this can lead to conflict avalanches if scatter container's keys are copied to another scatter container. So when are scatter sets (or maps) useful? In short, whenever there is a need to check for existence of a key or for collecting (aggregating) some value for an existing key but assuming the content of the scatter container is not later propagated to some other (scatter) set or map.

Check out this example, it provides in-depth information and explanation of the phenomenon.

If you're unsure which one to use, use regular hash containers. The difference shows only for large data sets (measured in millions of elements) anyway.

Interfaces and container inheritance

HPPC's interfaces are modeled to encapsulate the common functionality enforced from all the classes that implement a given interface. The interface hierarchy is loosely inspired by STL.

An overview of interfaces and their relationship to data structures implemented in HPPC is depicted graphically below.

HPPC interfaces

hppc-0.7.2/hppc/src/main/javadoc/resources/000077500000000000000000000000001300364116400205365ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/javadoc/resources/interfaces.odg000066400000000000000000001230241300364116400233560ustar00rootroot00000000000000PK÷H¦FŸ.Ä++mimetypeapplication/vnd.oasis.opendocument.graphicsPK÷H¦F—\húŸuŸuThumbnails/thumbnail.png‰PNG  IHDRÕ7”¹ufIDATxœí½”$Ùq˜?}fy×ÕÕÞL›ééñ~Ö`±»Àb±0$ Aƒ; )‰:IÔ!Qþt:ÞÓ"%òéïéJ:G@(fA`w±~wvÇíøiïªËûôyñóWUW»™žö=èØA£*+ógäψÿÃkÛ6µûð“ ì¶Ý 8 !-Ë"àï¶Ý};¬)4M?ÚùhÀö1¡øË0̶ÝtÇaŸúw9l÷ËåÞÿ}QÉ>°mwßN ;ÀÙ³gÕ÷w€]ÛÍsss’$>|¸\.ƒ°mwß°ö~õÕW³Ùl(ÚiŒöá°} P¿ß/Ë2Pɣǰ³Ásù|¾ý…OÀ0‘Èb¹ýwßRê±gvvöOþäO.\¸ðùÏ~_Úå° P׆É_Ó2-j‡©È”¦C36`bS†mÁÿÁÔC"eQC1š¡ÿÞïý^Ï8¢™:‹r’¦¿,böíH[ ;Àu ïÈnç­B¨þÿø? ¼Æƒk›¦MÓìlïø¿ñ›ûÈÇàÏp4zHI-FiŸú·v’Lhú¿ûõ×ÓWÝ‚lDäHEð‰l„? ¼®VB–Æ'X6¡ˆú™ëÕãp=BµßœËñ >2¬ê¯U¨ÞDö¢Z¾<ü‹û,á”fÿ«oüÞ<[àðʽ¢†‡ÀøÀ°¾/¾‡MÕвA Jöÿîý?á?à±±‹jxž…1ƒëJÃÛxU0òêWžûk±XŒ(šè}Xv’°´AQïnþiçÕë5) H¶}LÊ4²A2¢0•ÀA[Ç?™…bYZ`0é`/!wÇmØF$³‹,8™F Ø–¥ #£ –a<FctY/Ëí>KÑmæ%Ž2ôòHAp3FÅrkÒf HâlÍ %†²5“‹¸8žE”³FÛ¹)Ä ‚E[+Kxí·ËJò»“âÁ(+›–j!5³EŠåY/gUtC±\­.e,/´ú€Ü)Ý0U“iˆg7±+ÄH4f•¶DϳVßÚyßvž,X¦-œ ¨y*¯_V\‡bútJkB› l`š ´k³yälES§³æXZ›-òí>Þ/éù Ëy8CËþ`Œb9#[(ÞI³n†ÆËÁ¶ e*\wDp ¥3ùK¾YF’aËáÍ¢& ,¡ Ó4ê(^îü[yÀ›l!@Ó–¥ÊÙOÓ~¯ബ…dóŽê4È0Z¢L[ÍñͲ‘(U¦ B³lUL³¬ùŸå<ƒ>S7a[><ìȶ-›ò}X€gyh‘E@ÅÚ\ˆ6ãâ­Rä, Kœ¥š\Hrj3À¢|´I™Ì3n‘HÀ´Ì¹ -óþö I@ ôÎ…nVY 8÷ Û,ëXþ1@³–|†§‘ÀÑ¢#J€Œ-a‹K!ƒ8I »®,{³ í—Ã_8d«†|0„Dži´K7™§,ÌPŒ‡Óã%Šc)ÃôƒºÃañ + ²`34’ÐÊ .0ˆUüΛ~`GÀŒœZ¾™ÍDXÛÅGæKUµãt–I=^„Ïh"Ÿ‡shޱU]Ð)P²†gíŒ «8Ê*Ä`$ÊUq "Mþ`f+¦MÕ•W¸ K3e5o¨j#iñbùFÙ2Y{L5°‘Ø&DåTà\¬£çT¸ ܺª‚ƒ8[jU1¯Š<ÈHVˆ°Úèp•:–¥6Ê÷a ì$0Ž}ð7Ÿûk¿’ùŽ«zÈ(bT!«¦šÂvyÛ^°9?¢ìr»ß}÷]MÓ{ì±B¡P_´±Š\5µPõa,GUË ùX €ßAEnþ^øçªªUdeÔn´XUÿÖ´óêë6«Fó±k­2¶óS?ÕÝÝMí›A·vÞs`}#†Á²ìïÿÛßÇã_ø¹/ÀW`¤P ¹¶§§gÝ#l:ì3À–ÂŽšAA²¬õ9;±û–¦èaµK§ÓÁ`Öòõ …ÅúÚ’OÂ4vŠòê‰ûÛ;¿¬ÛËS§Ú/ùËðÁï÷Sµ4” ¢´«nW!óèÁÎ[Ö d÷Š'b|ØwšîÃÃÂf€ºÙHôûÃ><ìa¨R)~Ÿú÷á¡àÁ °ªªZsä“ »Ñ6ɾö¶k ªU[VÍìZ‹Ã#¡T oêΙtÝ]5ìå×ü`pèÛ3"5‡®;Žƒt&….ê³¹—§å‘²B’„}EîIr6yõ@l{ÉÎd«¹:ð!BüöÊ1M{ÌD³¼qùbVcû;tEƒ©,äóÍpË.^ä‚Á°ZÌTLÚ#r¹b‘¡N>Ïþ°K€¼ˆB.SÑLC­˜CYš$»îܼ勶u·FsÙ´ì 1–RVqdÏóp…i˪$ ù\ÑÏ!^’æ§§DO(páè-›6÷ú[^“§ÇG^zûæwóð¡ÓÉéÛ³Ùh[0â‹^ºvù—þʯŽ_y#£"Æ(½÷Á­ÎÎOÿÌg>j/¯ €ìÃ0胋o½~åz[k/‡ŒÉ©™p´iôîHÏÐѱ›¿÷âžÿüÿ4g¿õý‹‡»§¦'t$>p°¢æÞ~óÝžÁ£-MÞb6uãÖ]w ÚÝÝ©U2†fùÂmŸùÌóô·;<˜ˆåعÇcÝuÊnmnM̵–*&+°ÑHÓÐð`WkÌe£x7eU†Oœv¹±°—Ú!꯫Å;þZêþ¬LJÜVpyÎ\xj¨·»\.:‹u´c‡‡]¾²Õ¶®Þps—‹nù˜%V æÌÙs¦M±–¥Ùv{{G¤¹ •ùtúÀÐ!Çïq¹Êåœì HWÓü6çm›½µénŠ…"Í•p8PÇ©¥%Ü}ƒUýi™ü¸ÍPŸ¦_”–(B;ˆOu ;s¼µ@ÐOŽ·µµ’ÂííU"{ò©æUưûªZ3Eò·k¤YKÁÛlضÙ{8+ƒ m×BçÉq–eßyçø•eXMÓü€®kð« Ùl–ã8ø¬ëºÏçcæêÕ«p\s^ ÷ûýª‰¹äüúqIK¥\žÉdHa98îv»á¾Åb1^¿~rtø †‡‡%IÚ%;@¥R¹ví|l±Ø ôär9—Ëe O½åÇ Þ\ÀïÏd³0o0ód¶3é Çó0Gp$ À¬’¢F0Ïø-Ø”fèpü Çyx;™ ¼‹ÚÛ hš ϵÚ[ÛøqÀ¿P(9rdKßæZw€ÅÖ…Purð;sæÌýÇ!Ê´‰Ó[¨MñÚ’A€=Șðwtttnn®»»{—0 ‡ŸôR¯EœØ=2]cccñx¼««k'`-@âpvÀjA>ìh7à³qb÷lÔ*îˆ-âÍaس6rùºÃBÉ:ëG`ß$`«yàŠÛºä¾¯eM„ÇÂça‘üI€­æÉÍa"|¯6Úxaiz•ŒÆÕX~m¸–õúðY~¢¨¿î™®¯n»z f#—“g›õ‹œo¡Z¬ÅÂyÎÿ¡Z©)˜1FFFà Пàëää)\¢*JÕi¹Œìê+:I#µw¨šc¿>õÈ©e===‹<[µ‹‚A–[@ªÕä°—Ô²@qœ˜˜ œÏ ê-Ǥñ¡j¨.¸O&u$IªÃnÞ êÛæ1$&ÇÇÇã7~#þÁüZ=nˆQ…Ç}بoôëBH_ûÞÛq¡O°ãçý ’ex À‚0°¬@ÂÐUr!Ͷ©Ûv|û}Ý©»ý3͈dÑÕÕŠåÄhÀ8NE <š3 UV©¨úÖßþÒ§Ñ #“Ÿ£^~ó½Nˆ‘H×÷Á²–a›Äf#…ÍZNE‹jþ¥-R-ûŽ7 î¦k8Ùέ fɹ¯ƒN‹´-“ayDè!U)Ó³s2 ‡É&õ­¿ó¥O“x“F$wêOž€$t¶‘a‰XÛÙÙ ËG8Æo|c¹~.dwDƒ:8¹|¾Î®!‘Åì`êø[î`«ì9žexž¡©|ª +…b¡Ðz`˜漘ɈžC›†Nq˜àÓ°h.× ™R19“)»w»UÑ‘Ó5›s GàÐD)ÅŒÆa•JYQ*¡P¨aÀxñ‚ØÞ×ßÜŠŒ*f åEŽÑžg Uͧò¬(xý^ÓÔá`¥X@Œ ¹€Ða» ós£e•í8ØCj¬”rEO(hªŠE1¢œCª¼HRyMÑJ™¹¼jœ8f(Ã#\b”¶á‘m)&ÅŒ’(›ËZÁàn>Íf³ÔÆd6 x ý_ûµ_ƒç…ÏuÑ`}`;åúˆ©fKv’Q¾ÀK°e‚Üb"ÆfvöÞÍB67u嵂AÅZ{§F.5µ e§oU|æéOÝ}ûGñ™qñš¦èjq>_À´•ÉLËÞ–PS³©åG?¸rð±ç5­˜½ùæû¯±²·œ›w…Ú\nÿ©g§š›A±¹töŸþ£¯üþþÑÿù;ÿÇ‘#Gê] `’EþÎ;VÏ!%«NŒÞc íÊ_~=ÜuÈ,e •JØœžžì=öt$ìºyñÁå¯dâ–hŠÆ€“s÷()tðè¹÷¾÷ÍR©Lé°—YJ)Ç ŽåÆÈå³-ü@Ï^³„ØáÓG ³#W8531áòȹ\!ÚÚh=ØÝßg¨v&™þ«ÿÃ/þ—¯}ó?ý§?†uQQ”]’÷CŸîîn@ H‡·Þz+ŸÏÂ]½wïÞÐÐŒI¼LÔz9 ;1x6“cÇŽõôôl €¬¼)ãPÎCšå ·¤“‰æþ“B|æ7Ö=ìö9†fe9Ÿ˜Ü~oHDZ´J>5;Ž8O¸­›6KŒÈy›zbÅTÜé¦;Ò~LMMš6íõøÝ^Ÿä#1\b”xñLËår}ôÓ?5›Ètuu ÔVm[º7›½kê´àõyÜ%Åè>•N§OÈ•9›êò6ÑF.χš;aÛvû‚4Å”KYžy70H(ŸJxÎEùü¾R>“ŽOòr8ÔÜ¢ägE_´µ˜Cº'Å$çê9xäÞû?d¯'‘¼ÑhG¿;†EXÑëõ~éK_‚“š››<¸{z‹1 8???99 @ÂÄž9sf÷ìTÄTèñxV´UnmlG½¤’K!…"‡1ÈÒ—Kº7 [fUn1êAtµÐÎtˆÈá]'ÎØ<0åm R”Sˆ“B%I~¬ó'p‚€ `¬Bâ¢m€Ã?}îOœUÞ%¨Ô5Õô0Úår;µu©Ž£gà^,‹ŠÙ'Š‚²–!ìHJtms&1źb‚'ˆ´aÀ‰êá÷ ÃÃØ€*MÔ‰¨èp05A03ŸøÇ‹‚L“ 0¶Iáb£ÃñÜãzêüã^‚äŽ!q`àD"Ñxœˆ.K-“:¶½:J+®›ÃÄ»¾~p´`Z+Î_ý±ì(DÑ$áæ Gtªf]AËÂΠ õÔs£¬² ÑM‰Y ïÚNë. Ͳb´ Ê[Y–!æ‹Ú˜ð i޶37ÞF‰ ®k$„a9 V«V¡ºjª_åü¥1CXŽ6Ü€Uà ×6âŒCÓ%\Rά§-B¨Ÿeë~‰ Mø&A£Ù§ñ8!µB¡ðö¥K°^ØËúÁ-8žkW¢†Ù°kY(Õ [üEª:5ÁJæðÖá½>õØc«UyÚJ0Aû—æ#j¥P7q®Å9k/ùO_ýJYû«¿ò×réÈ õ_G *''WJê—ÿÚ¯åÒó°Æ ’‡Â&T–Zì %K×ÓŸ=}8U½…·øÕ\*úîæ,Á³šcR»¸®Š¤óh»Ð ºÜìCžennnJ’zVÊå%&`bä‚™$–: pMÕŽƒuƒ¬eÄîÌ0¬³x™$Ç"¶&|À¤œd‰„ï†áÇ–`fY¬$Ý~íµÇîel´A?™>ŽàßÚ¯ªyIÐÿ÷ÍoÇãq N?¼š nÉÉÀ'/w7VcÉ>´èÈÆÍ|ëƒ]§°v)jnnn››³®\áVµ9}áYe!»¬!— 0$J !Çì\;™ªZN çæ¾V ~—‹Es•hG-`ƒ°ÜŒ³Óíaðù|}ê©Æ‚ªël+®\›Ã$«í€åF¡}X7`Ae½Ù›ˆ±¬vÂÖÖ^¯÷í·ßžŸŸ_1R›çX6NŸ9s¦&½0ì ?ÀöY€¬?ýéO¯v1òܺu+¿ß¢tÀ­@» féþ«Ø®ðl¬ÏM»ë†\.·<b©Û»´²Pb´Þ( UXHEªýD5©GET Ò.’õë¡Ô*©Æ»Â°îL"»ÖÐ¥þõþ"{ã™”³6ìQÓ.‡û„B Zì)UÊÐ "~1ËÐmŠfp_Cœ¹d[69N#Ú‰¿‚Ï@®vµœó,H±go· ݨRm …Ø ¬ÏF­¤³>¬+mɇ}ØDX1«¤UJ¹\V Gܹ¢b›¦$JùL’aÝÁ ˜/©™ZÊ;!Sõ3IÜóê±k8Ό㜅¸C>0¬ #jS.äFïÍN”n^þWY”„øÔhÏ™g](sãÒ ÙçÉLϵ9É)Ùä|Zµ*±þã!½ôý¯}“¢ei3#ã=ÇN²¦–Mͦó…#ç?úØGÎkNX|ý-n_(ÄýÄò¿ùâ„â“EÓ8ñÐÀæH̬ED<8NÃqUÁî†5 >hšNÓÌ÷î\6-³V¾›œË1>Ùt >¶“±n×6 ''Øhç³_þ¹O˜ ):9òÄdVW›êÉòKެ÷1w…RGc«›ð‘‘ ¶¾ÙâV´”'Ô$ ³‚»ùôÓ-á¦æé˪ê÷ÀKž{®d!ö‚Äñ\13ψ®HwgTt›;öø¼9*“Nõ9lnuKB©-kfK›“!Bžh NØÅj°;üÎìX¼»©ï œ€¥UÒ©L ñðç h¨ÝPJùl¡é`3H…Åœîò4Î ³µŠÅ 8Vß&ûƒaëº]ɦréB «ß” Íf9äDÑR°a’„Å ìñálLË.— ^¯·Nñ¯?ì’l¬Í‚­cB¼ ›€=/ܯAœxøìY§c{è=ÿdÏ9Jæ8³1œ¢ZÚÛzâO4ìõ«(yÁÖV`#8bÚT ¹ÉñÛjC†>ÁrîkÞW-Ü:QúAé15§ì<ǎ߸T,Vâ7.–E–\ùR®¹¥7;7’/+ýG›¾:—˜¹—Ï(.Ÿ$¸Fn.™­tô êJAWLo¸IÄÑK¯x¢ý–ž)æÚFËIÍdl£ÂJ>—ÇßÖ‚¥ñÜÁ"XÌ—þïÿëþçÿõ_ÿ³úOŸ}öYRUstt”rl»•J…rª»5Ùë’R}êééáy~ëvŸÏW~ûíÑùy³Áå²`ð ¦!›ÔÇ Ú1µ#TUú­±ƒ]µ Õ¿/N&Zõ »™óÉç9I²¢¹as€ÔLÝ,°q9ÁÊÝ&}=;7I‹rIN3¢×Íj¹`*¹J©èò…K¹iݰ8 ‰’\Χ•RÎ噺b B¨µâÄàãj:~õâ5´~õǤ…d¢š¬ïiþölƒÛ‹xÙFFFÎ;·S¼DŠ)ݼyî>00° @´©©éKŸü$¡Bj5ñ¯D-"ñü´F4œ¤U«Vçf S"IyÚ ÀBN0Ãby¿eàh°C=bëбB¡ŠÅ°•ËÑV+† q=8;NÅf`CÕˆû4¶›Áõ4‹ Ë>lé¢Ù‚ì?ÿÓ—Çã• Ýæ%¤+6I/†íÙåv}ög^øéÏþI·%Ž0"ÑuuuÕ%¢Æ#ll /cƒCmŸq‹€<þ[5æWaù‡-…º1ˆZ½îàæ0,¢º~IN°{Z¿*>$’£x—tlȸSŸ½îóp B½`>ª/øGP§á¬JÒ*ˆíŸnP‚«é¶,ÃlƒÌ0ŒåÀ‡ÚÔ ªn:ûÕÝ2o¿ývcY”úÂ_/n·¹÷} Võ²(ËÝÈd2¹|…œ`ÇÄI  „èíZÕÁ:ØŽÔèõûÿìÛÿ½R)î _ȧS8‹”ªŠ7 ÆS"hÖÌ©uëòtÛ-U‚ ÔGØY}z+nMÆ<{öìòÂX@ú~¿ÿw~çw^xáØýp¡Èmÿ`æ8@l•Kî»+”`´Þœ`œ§‚Øoýٟߺuës_ø¢Ë"¦½õ!°T«' …“ݦP(üöoÿ6hÞÃÃâ(6–/ØR¨«Ý$i˜¨€õ÷½9HlðaÖ ÷UòÈáüSž ´®‡ªB¾wÓmw3,dëËår_þò—S©TãÁÕFhhÇZTO…©9H—ˆ6É ^¡>Eu(Tôé]áXw(<ž$Iq¨¿îÜy¨ûRû;À¦Âò÷H4Ÿ¶¶¶_üÅ_loo'GV›sòM\(WKeŠ¿/ˆ«×ÞU*–cKù<âDŸÇéÖJÙs÷ *Ûß×…¿™z*Sˆ4EtUÉ™å8 ´CËš‹Ïq‚¯)ì]œ›Ãn·{SÆyXX¾Òì“ò.„ú{Õª¡üýÊ;i,råõýàÍ«R\°-âžžlî;!ÒÊw¾÷—n_ =7-G»Û›¦Æ'r•í >{áÜ‹ñgé|ÉRqîc6“Ž´tIŒihêt&é¼=ƒCá@Êå=ââ±ß“®E í hƒ°Áû°Õ€jýèë1c«íö¶S- TfÍBmí-<£±rÓ@gK¬µ9)Ü™jïèä8.è÷Éd å²;…¼3s‰P8$¢1Ÿo>“Cáp¨£¹©˜s>_g¬äbݰ™š`U—ºw‰`=€VÊWÜßv'7•L&Agëìì$.v år¹LÖ/^dYáy¤Ù3O<}ÖÑW5Ý`±!»æ ³mÃ0ŽÅzB§Î”u¹]YÔóÙDI±=ö8þª):ÃõŸvÆ)—+ ‰]*tù=îÍÜ6ê؇Gˆebxx”àû·S¹víÚÓO?}ïƒ÷Þ½>A›EÎÓùô…Á×Þ|›¶Y·×¯çM!zæpÇ›¯´ÆšÇÇî•tf°¿O˧“ù¬bRLJ¼õÚÓù"Kó¶¥eòEQ”4UkІâÉù€'Äó¬äñž8qŒuö]á؇GÈÎpà>§Ež&ÆÇ'ƧdASæ+Ía.JE¢J>yùêõ¦Nã*«‹…t†/K-ߺ~%›Ì°n ¶ŽR©˜Í¦sE½µÙ˲­[7MJèéí+g“ÓsMÇÚ]<]QK†I±}Wøöá‘»Öôgªªj™æùä“ÃÉš¢è–}üØ1¼—r¾¦ØÐð!Ë4xŽcÚ4-Žç4]†ÐãsIšnö÷÷â[gšÆ‰Óg8–#*ïÓ†!p\29SÖx‘­&a> Jð>ì~ ;À]4ˆ¦f‰z'J²X³ñ²÷Ô©“D…%‘0$;Ràx1rÙ<'X8hÇÐ4Ãã”K'ž€¢x–…B¡XˆÚl%x}~€u§7Ž@5¸T˜|LֈúÑn¼pØ6"ÙV¹4¨ LÚýçjãï”D¯ˆåDQ“B£öb——eW{:!3òÇFÖ¢à;"CW›lÒ°>?Àºý_ËG¨]ßPuÕÑ®_ø°#4ž¼‘GÞà¤Ýÿä¿Ó|>·üÚ%8S‹ñ¿VˆZA¶p„\²“"½8˜Ä6SË“€ëäTCm çm'9ÁT5'Ø™ø… ·%ÉÄ«¥דƒ×Ž6ȩ侨Ѫ¼Bs½òÞ–±á¯©”ò¦V*—òœ+}¿  @7P’Üõ»¡Å‰ÔèÕC—Ï'LšËåªMZ©\ªG¸Oòôjh¬69¦içó:µ†•eùŽ‘Ï[™ŒÖ€IcäÎýÆaäõrõ1x ð4#–eþŸo|RóËǰœièÕÛ"Û¦î~ ;“×ãÌ Ž”=ˆFÅÐ=õÝ[—°´WmÁ[ÝÚ«”Eãb8_W*Öâz}4C—£CÌýÕ/|w^þ Ãüèµ·^¼ÞØ ÇñüJÀ†ª8¹ÎÈ4LMgßúÓËÕ¢,ð€ÇÙp%H’µW^_H«xâ¦Á¬•ÿû_ú¸ ¹ˆØ‚©©_²rR5žhwÒu˜ÏïÞ¾âÌÀÒäé¨ ½'ç7þbjê÷ר(ÒÁq,2 Œ¤¦+o¿%è†Í²4õ×0Åqhzºòä“¿ÛÓÓ½ ðP~€†l '‚_pGúŸpqÖü̬;ÔÄÁs3‹9™º­”tNf‘ÖÊ:l‚È9±"8DZ­•|V3˜îÃÛÄ­•MN¤±Ôgá `Þ2lÄ Cµ MÅÝMË•ÈP‹(²8ñ’E¤µž©áä`kü%»U'®áeãs4ÎDš‚ºn×rˬäì’G LUòÅ\6ío‡ žÑ„´ªY ÀZ¹THg9¿»µ-'ÀJFneÕæ”“/H tâ*öíå9Xàj‰Ô B3¡§Õ’ª•BQQÕX{ÈÄ)´öªv%WKžàœ!†]êàËÑX6OÎßòÉ“™¦&N6»/)â{¬Ìù¤nhËÎd w@‰9Ø8®žèx¿A`Ñ“$æƒòºþнêvÀ0::ZK®¥9dfÓYo7•½5=1!Ž2éTÜŒfÓ‘¶>½”JÄÁ¦ŽµJ<Ÿ-¹ÃQI Óñ¸·©½¿«±ÁC'.\ù-¸´|*ŸË±<èýœ©ën_ Ÿ›syš]>o9=9=1wì‰gÇ®¾¡–†ÒÓ#¼Û_Î¥=!øµ©ãÀAS5œõú~°|Q±4ËÒ(K·à5²›[áŒRzzj<Ú9Ÿ»—IÆ]>œ ·ÌŽ^áý±€×}ûÝ—šŸäìTQ¡³c\*•EN3l¯?ÜÔ=ìõxª­á-'ÃÛl¬€¿H {I{Xƒy~å¤êÌü˜R¬¸‘é›vjn:í¶¶Þ}÷‡žfœ<ÏÄž.æòð`º…– P½å h¬@±ŠÂÂ?¼:Ü—xa©%füNæOÿ{bxØWÈé°è7ǤùxÙ¤¹Oº™­n¤!FU×CÌÛW…‚c_INŽôOs_Éå‰pLp#xâš_ ])”3ñò‘\.ëhØUK ùCºU×XhN#ØÔ°Â˼ë@à µ¶jD‰â챞¶i†1ìZg¯^õœ ðžØÑÑ‘[·n}ò“ŸÈç Õ:¯)qlÔJâ UBÓuC0mYªpô˜äöQõ³ðì©Í^ÁºÅÓÑÎm½vöB^ÿâIË9YDµ3í•X e“ƒ_î©SÏMO3 ³&™ Q÷9ëþ¿ÖÎÁÏ{ò$°©‡ôêì¤'˜ s`—ÛNN0˲¯¼ò è_úÒ—¢Ñè}RÖŽÒZÎñ9ðPƒ†Ø~ãßüÆ7¾ñk¿ökõ&­Áóago+&m9b똜M„`€õƲkRës›;¾¦R©À+$­ÈÖQï ¶ ¯éÂå²ÜZ¯¯…€óÐÐhMn·»ÑÀ²ÆûÖ%ª–hòP³WG¾«« ¦n“ÖˆÆ}ƨÉÙ ÔoºŽj§; ±Á*#’$}ñ‹_„ð" KlõŒ/—åÖá_þå_f¬±Qñúp Ö5{„4ögØoÓ'mÝ“³‰°;ÀNuˆYѰr‚þê]‡·áúF´ƒ8ì*ØåÑ7{+'˜vlDäóöS^]|Z£†úÈÃöù6êïrÉÁíÇdB}®~’'mûüû°»~‚Ú¤îÃ>,‡]Qnöa§`76ÈØ‡}Ø6ØÛ¥÷a6{Û°û°AØ„²æ–eùý~Rþ'Ü«²{6ÄõX†|>O|òûÔ¿{ 6ºPŽŒa˜T* …öw€}Ø[Pe€õñ†ÁóüW¿úÕ¿ûwÿî·¾õ­çŸ^×õµ”HY1|oa¡õ~oõ¯k¿–j]_@åÃ<Úk’·)Ñ Ô&MÚjÑ {ªÄº¾ >BëÏ>ûlGGǹsçÈ‘uÄ'n0,tãìê]n0tSšäm$tÉ…;Û«oÇaÑ iÚÈÈU-1GrçêIÕÿ¯2p®µ~åW~%‘HÄçâT5{œ„³òÈðõAê µö²få³³³NrSÛV¾5ªuwjز$œy¾ÚÆ”—¢ì…µª1­©Ó4@,[ÇË妧§ ¶‹O¡Ú9 h×?Ð4“ɤÇÇÇ››c€mm~œ2)µç%•B–Ìü¥Z˜1ªöV›´…;×i|_¸š˜(ŽŒŒÚ¸(ž4œFÊ­aÒÑx`ŒŽŽ^¼øË¸Å"µw\fÓ™<‹gÒ)¬„s±uÍ2M›¼ª'ž`ãñ?¯I5°4â2V°ªT*&|°HÉ·j~g5˜$q"ôÕË2†{啉¼Èq~R’ãi'=”r6ùj¹–A†a;ù£ä­ØI‹òùàÔô4>‚ Ýè6Ù‡XY¦­¨³°‚ëzöêÕ|þó¿í¤ ®u9·,“aØwßý^±ø¿D"˜žGºn!Üo¸:KNQ'L2dŠÈ#’ʦÕÒjOOÿ{ŠÔδ‡‡à ³ÆÐ¨R^:oN2±vëV(þSRÿŒà¼Â¤!Ê0I«ðêk…ypжa6HÂ#¼D¯Ïæ9zzÚ$i¸«MBõÄ\²fUÑ¿î÷ó$¥a§o ,•×úö•˸§4PÛë9$²M~^i–£å³z¡h$“jg¯7èc” ¼bŠcaº%XCX• z>oÌL•UÄœ;ЃãÛ"äK‘B1$¿~S²XúýÜ‘#>šöÚ¶ ÷š-¤Jv¬I¢áXäÔÆ2’3àgÝö¹YU³––á³%eÊvK”ÇÕRQŸ+{£ò‰“¾B^EÆZŒ¼K8rñ"·¾‰º³ÓÛó§ãÅ;JW§ #ÊÍò4Ìi"©-š–ðs*®mUdZo¼•9pÐׯE€L'ó0w<ŸS*Š•M©©Š}þ|P[©~üãÍÓ÷ ¯Œ”TÊd*©œ=<ì¶«bQÍ~úw Ï>N'•¿ü󙛣•€™O½]R¬Ã}|È­¨fý^äÙ^aiÇ;mâ¶ï%ýÚ2«[ßÿóÙŽ£¨'Ëf»ÈY‡:ø+7Kír)§MƵ“Ç^L–щ#òÔxqz$ŸÎ†n&ófoç ÀZ7]ßÄÁrX*›†j^ù ¯hÔÔíü\Á=“ÖŽ zRi VÐlFõD·Ì¤æ+°Þz8S£9]5þóå¼?ÌsˆŠ„¤Ù©b‘¢‡¸îÞÈ™¢øÌãÞÄTùËæíèAO©dà}f±¨¶dÒ®Þ.I}ù¤ÆÐåŒnph Ã59]ÎdôÎ>/§ë㳚$â‰Á ® qóf~|ºÒÖâjïSS¥D ?"ÏN•n_N%óCY:Í´FøCÇmMœnTõÿ|¾ôæ›o†B¼aà†vétÚëõRk+[´Û`)Y8ÿ`wF¾ äæ¦wÖËVìÖv×Çé%óñVR°¼!^Q©¾á@%Ã_½UñûÅPP€É5të#>™•˜G\o¿žt{Ħ(ï Ø½=.˜2\…Ä)ýGnDnJÞ©£Œáƒ¸Ô£È4øLÙ>s28ÔÝ~1Òʈâ}V¸UÎåâ"aîöõ\g'2X{'p¥=ŸÑLÃö…¤–f)àg[š$gÒ¸æˆýÊ”êó‹/c3LO—ðñøU­e¶(Â# z{{IFÔ^Ü –2€eˆŽÔ´9}–1”AR2¥ûƒ<‹åKlüÀ12û<®v)œ½ j0¶NDÆŽN,(švö A§ÎÌ”'×E x£–U-©[­D‰K f寧£C´Sô”ͤ/³°e“ÕšÆ/E44\VëÈ1÷|R %G µ Z vPZUµ5X5B€ßåæ–àÚ ÜβÖÉ‘SU¾©Õlj^°::å|É 9ÃY)‘ËÓº¡>óœ\.éšIù\Œi›ƒÈèÅ"-¹q·7g2µh³S¨ÔTAh9ûøÒyÓ ÎuËZþ¾MÚà0íh ¨£G‚§ Ö4Û)¨(©mm2Yk.Óo \9ï¾Ö'M/—Œç^p‰ àêc à*<”óâij VƒAŸ[b<Ø‹†ÑE Ùûï?].s¤$j­š6pY0ST+¶.|°b'f„õ9 ×áp—©©Û°qolVïëó:à+áÈÅ‹º ¸÷Q»¹ó:qL«ZmÕª‘SŽÞ' Ü•KF=NË…·P­ MÌXÿ£ã@ã‚mE·ûHレÈ ¼ÞŽ›7ŸžöT“k±~Hœ÷vUJ±«ýAØÙV‰$]=OŽE,HN•Ïêÿð?vù¼á 5%P×ΫMlµÛ¡…b޵J<©¡äY\úsaÒaŒ^BF¥$ÚyíÕ²euïÄžã*Í+‹}á ¿½ä {‰%omÕ£ à}PØŸðóõóukRiçw÷ …Â?þÇ¿I¾®å¢ÅO>zôü[òÓVLΊàÐFc#“–ÏçÿÉ?ùʺ'¢ªæÚ=Z¹Ô ëÎrV¶ظ¦S¿¼ÅO°Y­gØxæê·v®Â¾õ­¯MOOÿÖoýH–õà‚ô#8¦ f~GèZÁ¼Ej Ù(ˆçz±'xC“öþÑß{¨I[ŽÆ^$úFXê &M“¶ú¡Èøõ»Ô<Á[Ü¡jbÿ‡ÿð·ÆÇÇ …’Ïç{(ýÖ|UÝoMS[?Wµ›.ü¥ÞȤ¥Óé\®lû!¶.Ò©Ç®A#76¬k !»œCöpwG² !v:ÔO¾>Ô ¯ªú«(Œë¿R{sg_ –LPÿFês­åv[4òfÁf€ºÕ™„Õ>ô¤W59ÊÙ×±©t!§Öíž´ëÝ'mdd„çyEQ6‘L—ÄJìï[õ•»‘L×3ÝØäa–JÊ2ÊŠ’λº:”r^3L–áuµXRl¯Ï³«_ãš¡>?½½½ðYUUbÞ_÷€Ä¼tîܹJ¥Cõ_ºt) í`}ܵÃf€ÍeôΛ¯dó…÷Þ¹ìv´G¼wFﺾl"óÄS/´5óÓóÇí®¹ºåà[&Ç1¤SÉFir-0€iš]]]$(8*×K/îrØ]/uG^¡VQú¦ÞÚÚåóùó…Üðñc¼ÀòY^,›¼Ó¹äNcºÖk9 Ѧ½'H?Y2&UluN­û ¨F É… £-ÏphL6Øý°Ï8Qlkë€]]P.ÈË6 f¸l6cí²@Xûú_|ñ¿T*ïñ¼Ë0̪ÏZ¬¸/?Ró ÔÃÚq¯ãm$ž¯ú-H©Ym X BG”¡(ÁO|â7®F_×,o9Û0›Ký¦i Òh+eÞš9»ÀêÆ2Ø4I¤µã4xÀ™|…kèóÛˆ 6"U± Kš^Ã4€Èœâ5óÕ`õ[ûí6ÈMóꡃ?`„ ,bÁ†D¡Û ¯À®rÒý ¾¸’¹i¢x3;îÈË bA§9ÆëfTGÂã>OˆJ§5¸ÜëeáLÇ $ðêk¯+•¿#LÍ8û¦çÝKý,»Îð๻Cˆ·¡ƒ LÕÉäú3ª±•|ç;ßI¥R¿þë¿NV=`KI’zº±Ym“«w­ +èíw-Ð6ËEÕÔ²á ðH7oÝ+{pÚ€ÕÔ$醅 3•Öâ ýÄ™Àüx1§Ó‡åLÖÊN%tÑÅ$fÔ–n¥i©ŒupÈSÎ(7ïV^:U6ÏŸvÏL•y‰54“¹XTF´”N§€©8Ž#:µl>ËaÑËåÞ}÷»>Zˆ¶ˆwnµÓa>[0ŠŠ}éD"¥÷ð~ð~êⵂËEûR,̳õÁ{‰ñ¸Ò×ë½qÝôÊ Úª=ýþV7{÷Jò¥·óí­Âä¬zhÈ[*sº.ݼy+Æ +Ž¢(ëhεK`ÌÎÎ)ÊÿÖÛãRTÜHGŸÓ˜”@Nu•|e˜ELJŽm‡Ôp"¢ê §nìxCÆÙF 2±åv2¤°XÉñèæÍÒÜÜ1î“›FF¾ÙÛû† PTm9qRÀÈÈ–‰N|‚(ž¥aU3-§Ë§i…Â,ÇR•ŠŽC”W¹#î j-Y¢ÓÌÜ»÷¼Òc·.¡ø_ýÕ_™Éäò.Ö|ëÒíPÐUVŒOž˜Nv¶µdsÙÖÎÞHÀ³Ýïj)à „ÅCQ/ï œ8å¹7R’¼|[³PÈé º áu‹r‰t±d245:VîèñÜt6§_øp ÁòŒK@óIÍåÆÍIi†öùXMµÎž§òEÃïciÓúéVW4&Ê0äs±Õ¤ûZ>Õ§iXÈqî*ËÑÙd%]Ô (>OK¯·¥Ÿàóøš›«„³³äOž"k;‹Ãž†Å"EÅç“GzËe… "OÀDøßë¾×‘~WQ`á¸Ç š€†ÂX1p»-CÏÈz8€ SQaGdç±N ºÕs€QT&øn¨•d%“¥@ß—¬•J%3ŒFUÛMcjŒµ1–Y@.txÈFŒÆ1šåu¬k€R(J™–jB†‘ËfïwÇTenJîµâìT-ž4Êf²³³³‡ÂÍ}OÈz¸£<@žEQŒbÑ ëÈ’ÕwÉzŒÐ¢s~­~\íü%Tî´egÜnîш\dmnnžšúÊè(MÌ/ CDÔðªñ„,wŽÀÿ>øàƒáC‡fîU?R=eŒ"×#"Rõì+C$É‚;:wÇ»yOÏÏ$“GëV böÁ—8›0ª¥€!jÁUåÜή:.èêO«Ý‘`µÄ ÔÓÓë|^ÙxZ§‰—_~ùOþäO¾öµ¯U֬ƛø&Ëóñ; ó² xq±18±úÌÕA#ïMÓvJñ4Âj_‹û!.o㘈µx‰Å¾J©XKV'ލBŸ› }ö³àrqËUÞzŽØ6͆aø|¾gžùüÚ/&*ãÜÜÜ¿ü—ÿá¯ü•(ÂúôÂzŽE-ͱÚ xxõÕW_ýõL&Câ‡wòGPåÜÉ“9øÌ°v>­ä\Hg*0Hh`¥l&’ª¤G/ Ì`êV>oxýìJIŸRZÚeDçr†ÛÃV*¦ª˜©„ 2æÉÓnÆYÁh\Ï56÷ÙH’ô7Þ€‘ K]`»aix(Ø'Ø0 A_|ñû?øÁw_ýµøi]×Ö\¾Yžà:æ %2×¾ö º'x!ɸV7³îP#ó•¯|å™gž!ŸwÕÛL(›cýKŠ¥XßHwöyfäT;,ÓWo—^®ï ²+å‰YE)™yÅSY5ìLÙ>yœ¾z%cÑìРûÞõ¬Æòǥ˷˙”}w¤ p©¬k¢1©§CRU¼ß* •N§ÂU!– HØiX,wÕ,Ý6ä &+÷'?ù©ï}ï{]x8–[wmÐux‚ë°¹@xpƒµßëõ®#çfKÁ6lœœIS"K•Yä•Ñäd‘µ)“A¢Éú\ÈÏæóª˜c£EÙÍwu¹Š9m>¡òqYu>^É®.ÉÐŒpTTL$¸³§¼ï¾–œÍàr…Š‹Ç_UˆÒ4õÖ­[¤,ÊrB”\.©´ûaúøýþŽŽ’±ýÄAôÊ•+¹\nÝÉÝ£ñ|^`,'ئËé’›k<Ž]’¤÷IC:énœ`=Âàªîòº~Nƒ€¼ÝNq¯ ¸\×L ·BÁ5Ü‹EÓåa]2SMý¶±D7œ` ÊŠŸŸŸÏdÎQÔy“»ª ò’ÌÄd¯Ãæ0€ËåZûÉ4í¡i/B¦ Ðó3å«7‹ CÐÛ³9-îÜÈ >0+V®…‘›¹LÉ„„Þ.8‚Óù2)Ü™H)œÄµµ å’I³(¢ç§Ì{“ê¡×»—²g·ËY•X¥ltøxM»1¥ÚëÚò¡#¿He˶Ä!ÐKü^®¹Ydhª¯^*U¾öµo^¼øÆoþæWVyá p‹išÛ"÷EÑívïžÜ£°}Jp,œÜ…ÿÙØ£Q´]HU&ÓúüŒ06Qêîtç3ZÀ´["\!Y™ÎVwuº‹UC´ËCp©ôÞµ‚K¦a9즧çÕÞÏ[?ÎÜкz¤æ¨hkf:¥ ïñ“Þ©Û™×/⌾{ã•çôäiß+/ÇýíÞ'¤ç•oþE2Ü,ÎÏ«íÝ®p€÷‡X ·{ÂÒHPcccüÇ/ 555EÜûË=ÿ‚ ܸq#‹--5¾eDÜ9>>þñ–ž}Ølq¬ýdXøI‘{xmý^Q®.„rI%™·>ñÉf–¦2Y#â3)õ؉@¾áx6k¸¼œÏÍäóúcN:'0"‡Í8ZÕü©¸ªÑÌÑCîbÑY¨¬˜îvV÷¦vW´Yô¸è\ÖT û£Ÿh¡$°hF ?þ©€„XÃBá §k6)‹z©dzýõφB ¹•bƒ±b£ëúÀÀ@0ÜZ$7Å™ÀªúP{ï>,‡ðܽ‹ÃàF” ßOÇK°Ü Œ=;£8ŽL46ªƒz/,Çê2 ƒ>e.Jç«;5Aćƒ +¼ûn†øg°ãÓÄ*2ÎèKk™>’Ψ4½P ~Ò*ÆÄnœ[¨wÂqìü|Þå™ áp“Õ}‰ CŽxúnt‚6’J5›f¥Ÿœˆ€¨Ïg¶¶¶V/º¯c¿±÷õ¶I#ûbϦÀvûxž'%)7âñ¹ƒ7Xõï}š{ô`ûü1 ›îD¬ !›uT÷JD×>¬¶ÏP÷oE;†ºÒµ`‡®ŸLüKµL2ÔÊg:@7áŸóÕÜô<áÆ¸Œ}ÑÓaüÛµ`­jB-p5CZÖ‘–g›}‹…¿ÔÞ,=²›asÀ©I¸ë€T\üÁþK±xÑi$Z5ã, ¾À:5]˯×'zw —!z6C³³s³³³>Q«qÈv­<²Q­T#ÃÒø¦&)'Y§Žœàt®•@õΤø.$.£¿ÿsGžs6´}ylÓàQ.NUU¯œ<ù#šö“‚s+_Ð@úª•+™üN™6Å㚊XWsHk{'é3 q*Fc«‘S8ÀÓmÇ¿‡õEÖ1Ñ3—iXÙ¬.ºX·‹ehÌðWQ,à7Ž£Ë%Ý0‘ÏÇâŽÈNhHRp5.AYµÉ⸌l ØWH6ö|>À¦y ~šö€Îó+_ܽ™«XtÀÏŠŒY6ì—-jFsŸ/åÔÑÂÎ̪Ñ™CT:¥6¦Ý¡!÷å‹Ù`««%ÄËz%¯ç˶,£LÊèéwÙÎN"ÈŒÏÅŒÝ+dò6m†€N–§§·›ÍäôSg‚³wò%ƒù \¢¹ÇϹ2I•fiU1E™õù¸h„w2¹à8šVW«Ý²hˆE·ÔúÆÇ¼ÿónd³ÙMg+Àƾ]¬¤âÅQ劆»0ƒ/³Õ ‹BZ¥<\SXÎ'µ‘™J¹htëpŸWÇÞVêvÞŽÇ•÷¯eºÝzÅÐíq1/ýåœb „í¥Ä\Þ,ç´ÎnŸK° e*Dß{q>•š[„¦°`”´\‘:v£•Œ¿|qHºTÒy«¥Cjoç¿þ§3ù=.ôÎkq`!S7f’úð!o (D£Û°œúì´£^¯_ôoˆEßceKÖKó>Ï»9 {ô¦Œ³°PqÈÈB=½~–/ûÏDò‰J²`=÷| ‹¨\Þp¹˜|ÑŒfʉ¬ÙÓí¢-«¢Z’Œëâã2R ’%ÖÔMÍÄEïN(‡{Ë>胟4Ýr»±„ë\#ê@¿ofNíðÜt¹bºû†Q1xY¤-;¢±/\_ød»(3ÀW ñ \¬Wf`'‚­CÓ,ZÀ›9X¼è>Ћþ²ßﯖóoP&¢jíaìz©àÕ´m¢«Ô‰ª¶Ü.Êñ ÉDKFXX‰ëÊNƒ[²>,Q“è†-‹ª9B—Wã[º§‘’jÎgEQ>ñ‰Oðüý’÷e€,™‹*.:3áöÐj©$yP«Ë64U·)Y™ˆò€“)¸¼HrS¦¦˜±)M­¥“›T!|€]ɰ.wµS¹TÈpç9J)/¸³Yuu!¥˜œÊ9MY_@µÍP–¡à 9;>—¹_É`\Ã!Ä8Ý]4ô;Ÿ©QCM¨7ÂY78±è-CCC0' p8Éþ8¥Œ¡iM7DQÐ5a9Ë4àÄq<–i.T‚!”D;Z‘FŠcQHxÃ0ê"f6\‡¦Nc9ÞÙ{)ŽeàÿX–sºøÀaé°`®@ûáy¸£ ƒF¦Ó aËV•…ßF‡Á) ”,’æJÌ%¸Ãà1Ve&¨d8dË25ÃDñwÞ)—ËÀ÷™“Ía½:» ðuuýT"q˜ãRukÛlˆ„îÇ…_—å¯×W5âƒÅ¬¯ï$µ†"v÷ì‡*T?øÞ+œ+4<<„ ÅfÄ–&ß»ï¼{`` Ÿ™qy|ªRiŽÅîÝüÀæÝ‘w1`ÿ%ç]|vÚ`¤]­6b)5ÿÃ\:|ìðøØdgw'Ïq’((åBYµÛÛ[Ò‰8-¸%ÖŽ§ @¦ª¦¹Ýî\&‹8!èwƒ– ùgggd—»\Èݹ3ÚÒÙð¹*żn³½½Ý“·®ÜœH>yTQÔ`À›HÄá?W )âá–ªš–]”¤Ñ»÷<áXogË||†“<>·¼¢kh9l|ÙÝ„VŽ¿@Qv—Mƒ7¡€•Rvyš[£s3é·_ËP’ïÝžûÊoüÍé±{·n]O$s73:›ÿÍ¿ÿ÷3“w'“ñø´Š˜S‡]yï )Øy°;v÷Þ]NòÞýà½èc§züo¾ñV<1S(·ïÞxÜ…R~jb4Ubÿå¿ø­?ûÚW™ÖÓÏŸŽýû?úÛ[;Ë•J8u ì•Ë—(ÖýÂO&àb^üÎwtÛœšH4·Æ.¾wÑæ˜ÛoQlSK[)—þñ_¿3|æVÏüîïý‡Þƒ‡Oœ>¼õã÷.·¶t³”137 ‡&ÆÆ:ûMܽôòß<ûô'?ó±§ÈVóÀÙØPAUÜ}@üßÿþ*ß·#Ÿc¨f¬Vù%¥rãëXváx}kY”v㑆U‹'U+­C ü4‹êà«jÂk½’3ãH<Øü_—kÕ³IÕ°Å~^~˜Ù„ª#¬kVðÀbúuvšƒå¢îÁŒ$»N>yíöH¤¹½»«ý¼aŠ,}ôÌã]ý™T&ËJî–H°¹ÉïÆš|¢/îìj»våJow‡/ìþâ/|Žb8QU¥$€dIé¥Ò™bYeitöɧYOÌßäÿä'?îõEDKD ä´w´Ù´0|°WÏÍÆ:º[[›•z(Ð5$R¿×8rÈì>õ î0Åð]=]Z!ù™Ïýlss,ôÜÌž{ìý]åR‰rÚ–N]^ݽÝþ®©ìÚôÒGY 4¤ë×NŸþ1ñÔª:Š&( G›†Å8»;ö?YvƱ٠N{%ƒ.¡ØwV( ó¸œ)r8Ä&ÎC· ÓbXštS„«œ`lT.ꥊårãÄKÒ< Ö¬àL Ç¡Ky½ úR¦…=¦ã)3ÌE[ƒà‰ÚsmÄ’cƒ°]ÊÍŒL%öÌϧC‘¨/È$çÃ-Oµt€tŸ/–•b>?9~»¥{ø\ߥ÷Þ+ifOo¯aÓª©9~L íÇžx"ŸNßÍDc-¥b°hÑM^9ε¶vYfåÒ»ï¶uõ œLå{ Àƒ@ÿ¶,‘çÞ}}†öøsÉYAö|ô#ϱ*¥B¡¢˜šì „x޶Míí·Þ°99à„CÁÔüŒäò´5‡¦çg§§Ç€ÊÖš™š¤y¹©)ï/•¬Øˆ* ,/YöZ7ÉŸ ?@l\ÿNÌ–ß»ZŒ„èlNmi“•2=W˜¯ŒÅµH˜÷Hv®¨F›„\Á€¿Ù¤:7§6:xP (ur¼TÑQG§$shb¼lÚt(»],¨Œœ’f¼ÿ~Îãå“)µk@lòÐSsZÀÇ5ûÜÉàÅw3¢@¿õF±cÐ?ØÍŽUA¾P4|>>}¬i.ò@;ù™Z©T)—õrTfzhm¬àª•k—Þ»tñRÅ0²Iså\þùŸù…ÇŽܹúö¿û£?3^Ðl#>öÊØÝÙ?=qOò†<´ug>óÂÇ?ž˜¼ûê[ï„ñ[7¯1nï¡îé\"“){¼eP½CG?ôÄi{m‚â£ïpâDM§é†Y;B±ÎÆ´‘©ì{·ò³ñJ2^qùyƒâ%³)Ê•óêØHñÖ j&¡z8–2yûý‹)¯½x1í J!7óÝëé®OÀEÇãJ.]ºq·k‘öZe#•R×?ìö‹Ô·¾1IËœ¡ê”Ä º›èÅW3GÎøCþåïÏŒ'Í€¥ŠöáWK§;ìwkØðRÅ߯Ùú˜Ðggg¯_¿®ªëìõ Å­¿½¡ØÙÓÇïNLK ÛÄš`7)²Ma¯¦i b~âS/´wö²–Og#Ù°èó?qéÊÕP¸¹­£ýܹóáæˆ¦kèÈñ£m¥J(’%ÉÔÕd:†Ž>.rv×>·Ûïrñ@‘¦ViÝ#£È2DÙmhF¬½Ã×Ü. ,êeE󺹎CŸð´tvv¸\’¦ª¡æ¶–T†nkïè홚Ïõ=óœ×ã*esÇ%I)—Â-OV”)M5ЧÈ#òy}‚ÀkªâÖZ¦ãÑ÷TËÇ⸱šB}ý^^äÂÍâðQÏøŒÖÚuKt> oˆá$Ô$=á›Rbm²O¦AX8T¬˜>/[.™gÏX,ÔÀžb‹n¨®ëX"z:¯¥²æðk[@íJÅ€íǬO=Ù©­U„kÕ²ÞÒëù©°$ËŒ©YGÎ†Ž º­MÙØëçyår-¼’žV,Ú}}N:ê˜ü÷õyÈ}9<àòG>vpWðLÃ4q@)J%n~2Újè ŽE–šžšN§æ[;tw¶&æf/‡]U'gf#m]ý^·éÔ†x®µ½[A õÊå«]ý‡£~a.‘;Õ7œ™L?öøS•BúÖÍ»­íí}‡K¹L:_ }€©XjíêëààƒeƒhÀôõ<Âᥨ«Täá­€Ùå”ß´´‰©ÙÞþA”bÍ‘L¶iŠÀS ÛLeó~¿·ohýöòx¨¹Û‹P/Û¨Rè±»E8D Ó 5eá¬Ël^=•wIL>¥f“¶Óÿ-äuT+aB?6©¸LéW³©)çØõA¾\k$%¢<ÌÎV€i,‹´á¡A˜›®Àå3ÓË^ª×t€¼Ë…ýŽ5Ò²×_€ëj1ýß¿ýßI*ëvwSóT2òxæâ‰¾¡#ÙøH²P²)ù³Ÿþè×þó×{‡sÁÎþ.UûúÛo€B4ŸÌkHhï¹|íJk×€@«JYñG:l}éG/I¾–ó§‡^ûñ+wÆfž¯Ø²¥$ ÞûÔ… o¼ôƒ;#÷Ê ¬EšäpZi2£ õu•JÙRÁxüÙv„ù¼øªò¿RÉçË’$¤òY‘£ 9½oèî•ÏÓϲÆÌ\š¤öÖX¥˜RlÁëæž8Ïæ&¾õâƒþHïÀð…sG×h$xôýõò±3RóÚ,²ó4¢ãËr5§ªU·0¯^jñyµ¡Hž'ZòÛBÚg-ne92 ù™,Ë-!÷‡Üp‚/ºúA·iÖ…h•2#ᦞ¾ƒ;%Ó1ËJ§³ÃŽéªÒs ßÖ•®¾Áî–n˜ ná¡QÛiÝ)?@cšåò;U>vsa³ó3m–åÓ£sI=sãöÔìààÐÔø]Ñ åælêCŸŸûõ‘ÙY¿Ço|l°ˆ¡ô‘ñIšb ~çÛß´h9 }ä™g}.î½7^OÊ¥RK¬Ý-˹|š2ÍlQ‰„ñT™zÏÁ3Ï?{¾K½ô£7€ó¦fgÏ>õÜ,Ê¿íM‹½½Ý³w¦·+ÜÕá¿zu4õ:qöè@O>5ÿ½ü@QÑéÇžC{[¨[Äë~ïFâ¨e„í–zΛædj´Çróãl{7'‰Ùb©¹µÓçó¥Ê…¶.PÛô#–ž™Ït÷ö·DðZŸ 5ÁÊÚÙÞ¢–3 H.ÇаˆÇZÛ56 "[ÐŽå‘Köõ ¢V)€”Bé%X…A¡¹»§GùöŽöBzÖùXK[¤©™1KÓ³ó}‡GAÛ*|.Ó¤}^·mÙ,/AÑmk‰(ª ø®Ü•D¹­Ã×ܺòöë&-C•\S«f˜V{K´’O¦3žå“óɦ&ÿcg7‡îo´u@–Ãb±¨(Êìì,ˆ:{z±ßpÂú^>}æ,Åð>·4=Zd±È¡± “N%yÙ3<<”Jg½^ªf½Ñ6eå²ùήŸfhŠfh§'}øÔùã¸+ÒÔJYÕŽcXö)Žcs™,'Jǰ¢ÛöüYÛÔS)X¶=n· ;ÁmiJ¤¥»µ­.‡¯ÇOœ.•5Y@œâDׇŸÅ•®¤£…[»žiíD8B/vŸ‡•½!¿Ç0°µ<Ó4ûK¥"Íp¦¡ã–6k£‚Íaû–¬ïÝ$µj+HÓiSÉ¿öÚëÏ?ÿüïÿþ¿ý›óohš¾ñNaK AA»ªDîzÀƱ–¦’ñûž*þ@ èõ–˯–TÃÅÉ.pçέ¶ÎÛÐ<²(#nÖ¸76¥(æ‰SÇÞ~å/3ßÛ,šì'†/]¾n1¸Y2•ñx<éLº¥½CÉÝ^ÏüÜtQ1ÜoÐïÊg˧ϟ›¿•Jç E•¢í–ö¶r>“X(–ž¾r=üÌSçU¥ŒÃó,<‰w"1Û$‡ÁªÆo›d]55Û–Y©(䙀I€ÜáB–åˆÑlíáR›C+>ŸoùÁº|‚}ý[¤ÕÀéÓ'ûû>õ©OPØ#ÁnµÌ³‡©Ÿ4PM)«ªaèJb>žI&a-Öm6ÔHσ² °î“¹ëW/‡{ˆyÉd(…µ&iöRüìäÛߦT€†óš­!›vyüx[ÑÕT:tû ™øÝÑÉÞÞþb.c™ª,z5µœN§U‹>v4;7yóÖm‘ã46 ÓëâSÙù3gNŠ Â)¥¸h>j,±j×C¬j_Ñqfœ¡j§ÝúiD÷{à„ld2™å N¹\î•·Þg9qµÀ e?ªßÒ2œ¬ZT·26¯%>1Ðÿê¯poúÚ©ÚiÕ±«ÿÓl—dS4Ú2— -Ã$ìîîêÜmR DQxΉýÔg¿À ¢®”Òùrk¬Ys¢Ç,S“xžc;Z£ÈÝt £éà‘“ðžº³£f–~F7 XÔž¶Â9gv(‰$ /úy¼;QwâXl€îloE4 ²“ÚÞÜÞ?$ œ({Üâ;P­£Á­³ËúŠ@Ú“®÷?s •`ò$ ;/eèºãcb@¶ÃQ@¬Ó^»^ QÞÇN\.Upˆ§xÅé,Ë[–—šº†¶Zž³Lxmμp^—×¶ÀfË„´ Èͳw'ötU’»wïRNªP2^’h J:ŸEÕŠCÈ ÚÃÀ "UL¾in¡QÍ9Blk vî-¥ÒŽŽ|ÆogQ̪M:M᥄Á•] xÞgk9hTcæ×¦„¦§§Ïž={ÿ37‡î/v‡Bþh“¬)"Ziá¬>¹¥\y›b%P’<Á0eë¼$“Ó™lÞ4o¨Ö ?dššär•³Éù™ ^”$OÐi2TÍÔÌpØŸOLefæµR¦¤ÙÃç+e2.—¬Hk851JKüük©Låà¹1fÑf$^ÂKhn÷ßG²Á¢„s`ï‰@h¡0+&H¿ß_'ÜÕœÔü¢WYVs ®l§É’&Y››«„ªÝ,Ÿ|`¸ÔvøtÃ-E×a™_á m§ìs)5_¨èV~jròn¤m(=uƒó4É´Ïä†N(1z}væC‹ñé‘ö'xžÉ$fMÝìt&$•§®¾~çÚe8˜˜ië;,û¢‡Î=iéѸVÄ~ümn¯®ýh+ ³î~Øò¤x·Û}Ÿ_qT ¢HÅòå¿Âj`›”'ÔLÅ™–ÎHg_*™‰=þiXéÕ|¦[rk•¼øB ¹%1ï8tV/ÐÀ:Ûr¹=^¿;3?ïõ¶w÷*åB¬wXÓmP׌R®ÓÛnéê355=çëhë?~Ö×ÜC™úÜèGB±îG(ÉõøÈ$¹¾«ìyÿ=«þ6z ·È"·ÛÀ^[7Ë탪°P«¤³:R A5õwðìòu¸l¬»­]N„ŒmšH}'p º{j*@s¸):تŠW€uû%j€Ùvô)œÓ£˜)]£ŠŠè:d¬:p²™ç‰_Õ2‘f‚Àu¿E§¼ üÖYÜ&@56~´€Ø-¶Ï ´¢€a‘òÛìèlk] M¿Ù‡­,Ÿ0È*8÷홃†`°6ëxkd›–mÚˆÅÆ0Ûjp{Ù¹C^½î GS†³³;)o ͤÉ1Á骨 í¤ÈÎÏÏ—ZZzVÊåÅ„Hò);C;ݰãÒ4á³í¤É‡¢ªã–¸jÚí¢…ÈvZǦR©‰>èëéQHÂÞ¶)Á»³?À>,LU–åv¹#QžIjÅë ¼r2¸0©÷dÔH—Ô™2‘‹lõq¬…É]7m“bŒP¾§#^©ÃcuàÞ-­1Ö¶b0n<î ‰¢‚ nËš÷P6g#Üä\Óx–ÓLCd˜²RáDC#žTn¢lïJ¶nÙ,Guz&P”²Ò>€~4ÍìâÔ¿£_e–3LCMî¤h¥9Šë›–ž{sRMiVYµ€âÕTmy(ê=É~o q •ñöRš^þË1y°‰óù÷fš>{Ìò;á$ ”i;%¹ ‡wèÅÑlÀZ1óÃï¿jo¿r%vp8qû†ku‹Üà©s•Ì\j>Șm†ó†ƒjjîÚû7O}ô9‘¶T\6‹9xä Y$Y9ŸoôÆ­pGWG{óÈÍ{í½8˘¹{ë¶nÊ_,äewamËQ ‰nW{o÷šÍK °…•á¶-#ìò•+_þò—ÿõ¿þßö3Âî„ÄÏüƒOÿuS¿½ZøÓCA5_é Å2‹ŠWc¡(1>5625ôÜî8f俯fãúÞ¹ôv°õ€RLȾ œ7xÁzï¥& ªÏß„, 7ñy+…|úò¥Ä¤|í÷Ÿÿ+C›ýà•ï¿BKÞcçÎ_úác<ÝÑfYW©¦–VÉ/E»»éV,‹² a¸ï E=ùÄGúüç?Gíg„­l;¯—qz­µ ô_] lPcø >hð¥k¸?•ÉùÐÓç?öQNáÔRYu¹äOžc9 ¤–çÊ…‚×-µ?ÑÝ+ ¬eÙNv¥«B´ pG{Rö¨ÈÙ¶Á ƒy¼ÞîþN†—mCã]>Ú¬d2%‘¦ŠúC÷Ù(‹Ë.ÊãE›T«[œÛUÿ©G—×|M«¤!ªÚˆ§š9Fîÿ}æ~åê øW½EMûZt-EÕ.¯"¸è§…ˆ jù…LF§l;½9AM‹Ýëu›=üœ½8ÖÖû3_ì#©ŠdZn\£/àrÕb´ß¯SÔñ“'l§€ë‚ëÞƒÿÂÉ>·o+¼Ç鶃ÏñÄÚìÚ˜6%ù½8w\5(mØÂÊp‹2Âz† KÃÑ" ö †Î08ËŽå W–4‘SõÆ4 Phá//H¦¡-.åFYð+ËáÐP< _¼$)ç½pâªêøá±ç™¶I’ žÃ.œ†•8–ÅÙa8­¬ž •N2Òìêû³œÊ¤% NdžLFØöN(ãù{—/—2M%¥#RG Ëв¿+É–ö +×BA¿…1I X&“ÁÕóf‹Þ ˜Õ ò5·¸ eôæÑ]^·×oYšà’·5M3-ÓŒèŽï·l3ðNÞº&ûý–©y¸Ò h:@ҲߗŸŸ¡™gPbrÂi …¼å¢ªäãsé|Gß®iÀ&¹Ä¼äñ,£” nÀÐUÛ´y—Û6Êñ‰[–¦$ñ³&IaÈÖÅPÈ($ŠJÄÓ‘Û#ÝG ‡=¥’á’]·$Ÿ‡ã‰Z±‡3¶HÒzGGGÐëÅéíOc4âCÇ6@}œåÁˆ¸¼^·ß¯8qksuXä±^ˆf[$äÕBÿ€ÝÊݪ×ë.Ä«0À̉DFGG+å8/93 ýô¯eÊåH¤{jäýhÇáRrÜBO\{+•·+z^Uœ|òÞÕ7xw€6ËÙLÊlNOßs5u÷ôJNŽZ,“½îŽô²èõ¹'o]’›zŽœ}fäýW¦'î‰Lº^ÈÎ&ãñGÖœoï?/I´èòܽøjÿ…b-SW_½sõ²¿)<3z÷̧ÿF_×å?ûª«©?Ös ˜{ÿ{¯Š¾P.1líwyÏ?ï–˜=¶P' o(Ôhü Hiëul*µL«hkêŒT‡ÕÀ‡8Â@U â¯ãñ&͉'bhh¨š€C¢%‰Ä✠òÍ{*–ãb݆q3öÄOæÇÊŠ}~ð—A(fJn—¢T^øØüøÍ|®4ÜÞðzDIfÝÁP$åÐîõÍò>Ôò^éèáó~Ðî,[)q74 ÈZ4”<â=n·„×QšÒ5[r R¶ÄJœ(ò¦i3 ~söÍ€®Ïoâ+¸¯ìAmwƦ’éL %–˜›‘Aƒe“©Œièélö¤é©é|¾ÜÞÑïP¿E ó,}>ß'?úÔf¡»È´ñÔSmõ]ìuè‚b3ÅŽ¼ùÝÉ™ŒÏͧÓYY6'£±ŽþùbrìÖz¥ jÍ!¨-=v5S2_(¦&²Åò…¾+àæáî«8–¦gŸáI¼aá `'Μ¢Ö-SäUÇÅP?ñéŸÂ)gÔã€DzŽz@לå[î ®ƒÓŠtCÝsïŒ'xǨ²¿¹‰òДu¨ïD>1lëš¹ý.,GáÞH’Ë«k‰\2ˆ´<ÿÑŸ'§'M%‘/([ÒÌ ñN¯§Ÿî´%8A—<Ë:‰gÉ;`å¸j¡%·Þ\ÇÁ°M ó>õ¯ðÚÈØm‡Å g¥d¨æÞ.мÁ0E³¼Ðt¼­‹ÂÚ–‰ªuøM[†nÑ -Hb79óï~J0µbµÀ†¤‡Úc5PÄý×öá'¥Œ¥¬øÕ×´@À0jêZµ£8‹c¦kåAÙQÕdr'óÒ±Ç3Ÿ›àš7Óù3(µ4p Ľ¿BîÃ2€-º¬¨çO=:%‚A„“„—Ä¡,òwUòÌaÉíyi³¨loçòÖbp4Å~BÌ.†ªÅ2Áh3µG˜ekš¾‰oyo3@=!†=c?!f!YÐqçREò–V“b#—½IGXB^/·‰6•½ÍÄÙüÖ[o}ýë_ÏçóŸúÔ§PÍGlÛ’$﫯~;ŸÿG 1¸ÃåÔ‡uZÂ"¦iØš‡­fÝa\Õ8Žžž®>üOVs„­v€ìš®c`7؆²2LËh¾¬Tþðÿðì…spD3u­÷¡°ƒ ÿÇ"z•àÄ}X?8UÛ*çÏ—B!ÑÀ€—óbNWMœ5ÏJ,o[é¢ÕÑŽíŠå²é•žªšU§ÙÈ2sõjD •M¬ v€jÑ@gŽyt4FLŸçOŸûü§?û‰½@áˆp~ýT»,´}ý˜íÃJKJ¥Â”Ê Ï¡7_Šß™5¢^z*©3–åm’Â6‘‚^ê—SÉŠ-qØúS*è¬È}ì¹&ǕϨ*©L¹ V -ƒªæª™ÿê¿7Ï8ÄV+ð;Ôb£>•F°ÔW`,' AãŠsf5æÿhÛ¿zéß;¥šªçSõ²J ÁäøÌ¹Ð´«i3 ÷D:e4žø™¿EóûúôV~¦í ]dýÔon¦2pÈ{÷ƒl©›ºÏ6KT7›L”‘À+(¯Ô]bðc:€­ß7/õ«’ÁR¹©ÚÃŒªC±4&hÃ2Ë:íâIïÄ9á@,ckFý8œÆ ò†šÄ¾Ý4‹íÅõ›ž^ÛIzÁÌE™8´Õ*©VŤÝ<#‘šÓÎ¯Ž¸ 'UÖuCüŠAñ{¿úî˜iI2eÙèè)7ÑwA:8ÈÃßHÀ[Qm¯½ð3aÄàæ4Ä«ê¬Z¶e  ‚IämJ;Çåæä …”WæPPbݬ­Y@¬VÉ!k†B<Ëm®l–MFÐMÝf=œ¥[b«§xi–BŒàåiZ7 |ÜÔJr@Öf2FÉ¢.Þæ(ÃPÆÓÈ%rÖ¬˜ÀNŒ‹-_›ãÜ’‘) ½aÎeh …õò¦bp,w‚ æjñ»˜eõmöa3Àé!&½ñ†+ˆ#lIÜ2¢E¼yƒJÀˆ$j‘Z¨AOt”`ûða®Z=3`ç¬@¸r˜ehº¡Ê•iix¿X¹—fƒ2”ð:MÑ®./ž5Ó%e®`añG¾£ÑòDŽöË´Ÿ5ÒŠ/˜%Ó2L¹;„Ûl*&Ûá)ßš+ßËÓnVžZ½ÀZR_ØšËjé çø-PÉïܦDÁÖ4$ R§«Uˆ[£kî0»'Á¶IoÁí~H ßr¹pôèS…ŽY¬š5@£õsE )Ù º»‘ÇÃ)ŠBdµÛ‘gܾڠëâ™ Ë÷L—Ç0q,‹Ì’“B!`õØ6)8¡PÑ2*q‰ñ‚ž×Åv/œ&ôø™5Ê*ÛºÅD,_!Ze Ä­Ú.òAdY¦v"¦•H›~ÿBu\îÄVÚTÏvE›ÔûyÚ\±Ì•E‹³É»Àò “nfWþµé<®ÏÊ ÊHË0­Ïq˜>GeƒÚ°p|¶à Jj ‰Af®B9VføO›É;' ªöòmK›.àÍâ¿ÈFÀZ\®t¡Þ&õÑö–ØÛÜ&uÀ¸ù?záŸã:îµÝ°^îd‘!’T;mŒ q¬@T5X{‘A¬‰g×rlêüOâúÙ—Rµ‰–L¢*„£à¶åÏ¿½@ÖËÛ¤>’€¶¹MêCA}óêééÙþ»¯%(y–ý6©ËaÇüv vÕ“9·:ƒg›¡>çûmR—ÀŽíK’¦w!ìrô ês~ÿ N*ì®`öa÷À>ìÃO4ì3À>üDÃ>ìÃO4üÿgÝDb4üIEND®B`‚PK÷H¦F settings.xmlíZ[sâ6~ï¯È0}h§C¸„ì&aGæ>K¸‡Ýð&laÔÈ’G’ס¿¾’”CXwv:õ[ú¾££#Oî?½zäêâ3ú)\ç3WˆÚÌÁÔ}È»´6£ ìž‹²n½ÛŸ1öf´î°Xdx1Ÿ/åÖß·­…‡É¹\ºmÖfž¯lž“ï|)öÎ…ÑmF½¶ê´íå7Û7“µ"ÅLuÛ0¨Þoœ³~Ëb‰<#W›ÛÚÆ‡Œ¢¬|Ã(|‹žL\¿ïûL±ÐÁ ó3Û‡r嫇˜ÊL5[¼ûxŸ;Äù!ì.ZÈXðÛÅbbô/Ø‘Ë8ø›ÒM¡”¾°»Œ5¿PþP¼;?ëA?‹©ƒ^‘³Ï…ÂøÉŠú¨xã«s,FaÇÙ3SH®"!SÕqQ0óD‹c§#6þ؃Ÿ3F¤™ê’à79£û>¾zGŒ)ô'L³ƒ—€.z„ÜÅT¤G¢_»˜¢£pSþ'²e“«›©³ ˜ZDé f@цÔ!HÂUŠá«CW}¨sèŽÕR#ǧÇ<{˜B‰Œ¬"·uÕ 4]ì¾t›Ï›Žæ+)ÚÌG®TâÛLJ}(YʾÊTsg_wf¶ Ô)áÏbM—Ù/Èyß”ÜûP=¤ÚÿçiL`Õa‡&&öQ@7á˜ãë½ú³ÊÃû™rɸZ:†ëfŒˆÚÑ£Á/ ÜQ(<2'WtDÊÉ5‚í— z• MÂIh"‚ÚRØú BLŽ v >baü$ŠAí=c©r äû¡í¹†ó»…î1y9.«³ âÕkbeü=2ܦ|d(› åƒ\ £Öò¦‰ÿð¶'Bo*ézÔpcÁ²E>nu"h­W#£¿öÔÁŸCÉxŠuDY$¾âYàÞ8žÿ…q<§3ŽŽˆ¯¦iP­×Žè’ä…ž‚®ž1æõiŒ:8#½ÆÜÜ­ {¼)5Ä7Hž_TZßx”·¤º|Ÿ¬žâu(áåu……¥èD‡ÂÓ¨{¤òñëo2à÷ ANlRøµ`s3V%c8TZט§+Ÿºn7Q”•}‘¸6™mFZ‡biÌér¢ ˆT´c¯& Å[S äÍ‘Ód—:Á/à5ŸcÇAô-6’—óºJ,1§‰ÍD jXæ?‚Ú² ¥äÔï6¨gœT-äbªk[Æ êœìŸt}?B+0ãõãšy¾ ¥m¾h—¦™ø3â5烀Ú2HëD×QqÆbì… tÊû´_Ò8þîrœ,t'&Q‰6"g„ÞÄò”„INÐŽvQÍ‘J=âÐè½´êÛÔ®Ÿ&8ûõª6RãíÄ”–Ag„ Ã(ÙOL—Õ#‚"àè‰Ô¶6íÆ¼¨NSsÄUþ÷`ìáÓ°à4P2ÂåÐ_ŽÏKks"i@‚å¾Û“Tž"XÄ;*sê_ÌUNìÂÕa jM„…Y¥¢ ô0QƬê-‹.D­Œ‘ ö5ê÷¿tÁà\~æÏ½éÐöHà€Ÿû)gSk¿Üæ;õçSM¿Ð·³ýÞ`9ÖïzŒ…Q>ƒ‘kù U³¡5í€C+íaB+ÖpnƒVhb©­©kÈ–þ.À°¶y¯ëûÃ!È'$=¼šn­u œÆLkýe·^oæ7v±÷^ûÁÝ ¬…V?¾[೚'=þz ‹å‚Š3bc«?ûjŸB‰ü’NÅÿ×ñKÇ8Ü„¢ú½ÁdjYÓf¹1Z£ér1y*7FÃ5§ÃIcúüµ0íó·ƒi¾dø{á~CÓõ¿‡ú´F˜HCŒmHP:U½údQÒøÉw”VrÛ› Ï''„ñ•Þ¢ÒYîàZ¹cÿá«þ PKè/–ºÿ(PK÷H¦Fmeta.xmlTËŽ›0Ý÷+ílócfSU]´j¥f4Ë‘c;©[°‘í éßטMT±±ï¹çœû€æñÔwÑ«0Vjµ‰Q ãH(¦¹T‡Mü´ý”àø±}×èý^2A¸fÇ^(—ôÂÑȧ*KæÐ&>E4µÒE{a‰cDB-)d&Ah¾9uRýÞÄ?ã8¦cžjs¨®k¢ ”³ n8š. 8¢“‚(E`ÁNï55a×–#¬RšrÇ:gÍ¥µ¾˜žÒæë„˜Ï Úö²»WqÂ&L÷ƒ×ÜuW=¥Jö÷ÒLØ7®†óîÖP¼çø®SG“W)Æ÷ñÕü¿ÚúRíy V‹—Åí²eÓ8Ú& E*é$õeA6íG:J= imn"æ¼pò̉7*Ú "˜À<ÉðåU$¯S˜Ÿ ®¡ gdÉ)èßj‹¤¨ÒºÆ0< X`³œàÞ„:$ühWû}›Få×òÇYä à:ýa°-š˜ofôA(aB‘_äΈo¡[ Hó¦Å‡gé';Ú—®¢Uüe0ú—`Tå%Fã‚f{–‰òC΋²¨*\a^xõZ°ÅÁ?±YüòéÛiÇ­“, ÷z7±û=<*·‰«*m® ný<Ú¿PK–ÎæzPK÷H¦F content.xmlí]Û’£Æ¾ÏSPrÅåT-ˆnÎcïºÖvRÞdÖÙÚY§’ܸÔ’ð" €4#¿D.ó~y’üÝ èæ¬Ò*{±3êÐ_ýŸÑ|óíý&v$Iý(|=CŠ:“HèE ?\½žýüéO²=ûöÍノ–Kß#W‹ÈÛnH˜É^fðS‚Ùaz•÷¾žm“ð*rS?½ Ý I¯2ï*ŠIx˜užb÷Ê[ÒlŒžÎó³3rŸLÇ sÝÛñwfƒùًĽ;™ŽPùéËhìäû4— ¾‰Ý̯=Å}à‡Ÿ_ÏÖY_ÍçwwwʦDÉjŽÇ™³Þò½r\¼M6jáÍI@èÍÒ9RÐü0vC2wìóѱü#…ÛÍ-IFCãfncWㄤ0–K‰9îBü_»ÕhvíV0{k7Í36X¤Š¶OmÁÏݸٺcíù{èdÿ½¿®x•lÆÞ‹Ž ò?½Ì|4??Š¢òQé„ü°³ÇŪªÏóÏÜè»Þáw‰Ÿ‘„îõ÷ÜÀ+6m Á84‡2ÙQÊ—‡ˆ‘vLÀ󼻜.:/ý÷÷×7ÞšlÜj°?˜»¤¹æØ˜îÓŒlNyÆ÷n¸jeUÙqÖ»û^¥Ñ2“þáþHüNtjã.‚Ì¿¹Ù¶ñ©ì8çÝ?¹ëˆ*÷ÆÝËŽSï>ï’AE»»Í"ª¨=™]§NìáY1*oVãr–~&IþbVµ€IDà}¡ižgšõ%]néÚ—¾q“Ï$¹Ì9š5å;AÝUÁÞFì£*É$ºû«¿xQè¹;ÒÒvGQ<þ“˜º÷xK7θô4K¢ÏTT¹ézÆ7É´åõìç KÜ¥J‘ ‰,ZHö¢™gž™y%Ï￸†ºÄâìžÅµö•‹³Z\C¥4÷4v¡!v¶ ý4þÆ 9tòŸ¬Ÿƒ>Öãl=«± ü´ébæ ÍøÙ‘ ý·Û ™”wÒv°­fùǼK¦E5¯gÿýÏ¿Ëuq©V7¸3e¾¤õÍ~s•Ù´mJ@„Ô¸`# \jH4Ýø=[zßbŽX*~ÐRó9iL“D·d%„yGTs±ªº÷æ”j­PßÏ!m2„P®Û_Bú„Ù/!c2„°¢¿H„ÌÉÒ^$>Ötø¼P9mO†þBå´3!B/SNÓLÃDÏKPsÝ…9=ï,û):n£Å¾üPÔ÷¼ù†E$h•O›ÈÍoú•iö*à …ŠHH Þ-+*ú~ KwP_‚ Hˆ—5/ÀÊ…Ê ˆÌùWù^ù‹×3q&~ Ü=}]~DÛ,˜;¤),ìG[¸„Ö¡éžtø´Ï•Nñ «`Kä8ò캣^Nã'Ɇ¢‰ƒÎ™F94;b¶YÎÖÛ°¸ÙÕd¶ñqAa¿Òeb‡Í~pýÞüõöWØ–ïihÊIòe}ý—Oû˜|¹Ê¾.(E'èÃ/åfì+îÜWßW,ì+ÜW½W)LJ*“s§aôxMKì(8^Û$D°&läAÐÀ´‰˃éSê]¸ ÷dq·¼( áS”ð²È§Σ*eMˆ¤Ö‰dܸGôPq` Âe¸Ö‰Y§J,°˜qºvc‹§¼¹:Ø~ÑC#ÆåpÌ5òƒq~3Øè÷†m¨’¦ªêNFMÐú¶ÂwÍrHª„$è(w'žà,1œ†~º@?}j9¬Op`B £G+×§”j#Q2”ŒÓQrí,§ôò¯-™ }œØw€œiý©ŠÎdOG£¦¬&«ȋv‰/£[|ilj/}¤ø2M&¾´.ñ¥_—F!EíƒÕª>æ¨òéfVcXQ+Bj…«a¨kYÓ6t¡6Œ'p¶…kÚEÛBR¶á«‡/I[Ýž€¶'êS—æéúigR(7${“ksúcmÔµÕ~¬­ñÇúDZ­Ax¶Â;£oYW0?qJ'ø:Š>oãgå®ð(Ro…§…Çî6[ÖŽ‡Ar‚ÚÁ”¼N«ätT îÃy;2¼` ¼µOç-ž8ºðÑ Ñæ­ç‘4}¢4Ó†¥-ð ©*øË‘–e+Ïìž©Ï4fYÚ”g†Šv² Òp ŸÑ>¶Ðº°ƒðÙ,!ã¡8›ŒõàæÕ>88Gô6ŒaŒM¬‚êZÖAAíL­_èCôÀ÷D©ÂÙ.?NæeOçD¾Mwÿ`WûÑ][4ÉÅ~¦hP'ÕN6¶ZGF9£‚ïa·»¶Š%Ã>…xf'Ž'W% žW9O¬IëñªU©u¡Åë,þ: W[ý¥=z¤Ö"tÂñr§~¾ŽÏµ‹ò® 3çÔS/Š÷êœz«õp94Ìlqé½mšE›üAÚ´ûä„»XeP~ìá`S¸ãÊFË…»%B<:è c1ö÷CÕù°ó¡‚‹„kúUœ9‰6$KöM(12Õâÿ{ºg”¤n¸*_‰-/³ïp}/ÑÉ×Åtá2RõS•þ)ý4«6‡ÛŒs€[šG1úÒ,ÈV€{#ÓÒèÈjç)йSàeªÅ¤AD0nök›iC¿qù¾eø´AétB9¦–FsZÊ lÕá‰î(º*V êŽY‘Ýø6º?,aPÜ*nÚT7_ý¡]䎿f‹ïºè¼öàó â!¸ËøÓCðÆŠ£;-x›˜Ç[W4Äמ Âi~ÚqâoüÌß)‰çéü}ýæôÈtgþ†‘5xUq&ƒåP„)E»~m߇ʼn.ÎxLÀù¨ª¥ ã§/Z­-, áг(,rÉT·`{ª z›¦rzÞ›™çWÒß.[‹Ä,?‘æò©5Åäö…‹=uAöeÙ—ô8¼aÄ;ãy ÇáÍ¢Cl¢Õ.ê®@Á­vQ—óÍy†%óÀwHíŠó¨¨|Bb §ð“$:s ž¿$yïÆ'ŽÇ&¿Q¥¾ÛÈoö8ö‘äïÊð4Èo`JþÇ rŠeÒh¸NÚ¨œÞ.¬ M–â©òŒÏ›‹XÑú¸˜ Œv.:­ŒQÅ’3kÀ8¬w0:Η°xpˆ 7Ô˜!‘ë…+¨ð ŽTd­åAXí@–ËXà\‘±*JÛ ±®vßÞ6]§¸ö—ð¨xǰֵGwª.u\ó60åô3¹c_ÝV"ÓrŠ‘hNÙ 6q‡ÑÖò}kL)9ã!²óp«ºÆš‰;shЩiO 4¡n£_¼ÚÚ˜Ãñ~¤à6·Vãˆ*ÖIR¬­xª|&ûôÁ¡n;¬VSÓ"ÅÔM…ƒ®8À )ÈлqhQ¾Æ°òý´öS‰‘¥µÇ9ñÖ{iAt—J®”ú?p)v38ì!ô$’Rf¢Sad¸È/âE›[?d!§T‘n¢WÐ%Õߨ“n ŒƒiïB¾®ýÝ>#UË+¸\’4ŽBú‡ƒ½"½=\­4[ù‹Ñ  m‚+Ñ_¡>½’„þ!(¸‚wÉÖÂSJÑ2_ƒòP~¬F&/P·Õ6\ùÕB­‡*Fàxn †y{е¨E1¿(¼LZÑ:Ù¢ýñÇï%ö÷£èßQ9gôehíƒE ºèÏ$Xÿüñ’¸i:Ÿ ƒ^‡gÚý·&@€í?ƒàlyõV¡ ©kú½ÃüS®ÿû£FnFœ*þ¸Z¯†ÏÁž ûÔ€¾˜fÆÃVºÁ¥ìÛÙhŠrOì^¿[0ó³ýóq³ëv»ŒlWVªÛæ¬É,AÌ_dBŽà„÷¼Š,øí2ÝÍÊt·áñ$Ç´¨å®Y,Glj;Ùn÷ÓUS—Ld=ÁÚB[±Q½¸ @sEœC0·׺Ë\Â݆g0ESÓlÐ4Øof˜¦dZc ì6ñ»¢$–òãaƒ)ºÕjæ­:PE˜OðÄ~°´sÔ<¡Så¥XH'(¤®½ïŒDÉK^R>¡84ÅÌîÈl4âÞF’‘¢Ue3mµœ¤&Äá/MôTãîÊáÖbN4"þ‘Ws"U+Ë9iDc±xH[˜–Ü“ææÎÿk°ñp öÑöÓŲ¼ýtã±@ÈÓ38TÅÚ ÜŠº/Œ%‘Œ¸úÔE&âž/3(mà±æS×ë£\!7˜N ò1 }Z¬Æc£MÛclJÖÏ;ê.ñ*äÅ|bÄ´ù*nà ÌÝ¥Œ­ÈZ"l²òDë aé«/ôa¬6Ó š­Ë¼¥†Åª<\Uò«Á™HJòá²à ¼¬«}¤ Qí[¼¥ëýÎBÜ]fÞÎÊ™ÍBï#¬¤J‰~“Nñ²~«÷¤j@á7Я­¾å”6±ï/ ßnZvÑ^†ËdðóÍÿPK$MƒÞÁ†PK÷H¦FÏ£€ï[[-Pictures/10000000000000200000002000309F1C.png‰PNG  IHDR D¤ŠÆPLTE€€€€€€€€€€€€ÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿ3f™Ìÿ333f3™3Ì3ÿ3f3fff™fÌfÿf™3™f™™™Ì™ÿ™Ì3ÌfÌ™ÌÌÌÿÌÿ3ÿfÿ™ÿÌÿÿÿ333f3™3Ì3ÿ333333f33™33Ì33ÿ33f33f3ff3™f3Ìf3ÿf3™33™3f™3™™3Ì™3ÿ™3Ì33Ì3fÌ3™Ì3ÌÌ3ÿÌ3ÿ33ÿ3fÿ3™ÿ3Ìÿ3ÿÿ3f3fff™fÌfÿf3f33ff3f™3fÌ3fÿ3fff3fffff™ffÌffÿff™f3™ff™f™™fÌ™fÿ™fÌf3ÌffÌf™ÌfÌÌfÿÌfÿf3ÿffÿf™ÿfÌÿfÿÿf™3™f™™™Ì™ÿ™3™33™f3™™3™Ì3™ÿ3™f™3f™ff™™f™Ìf™ÿf™™™3™™f™™™™™Ì™™ÿ™™Ì™3Ì™fÌ™™Ì™ÌÌ™ÿÌ™ÿ™3ÿ™fÿ™™ÿ™Ìÿ™ÿÿ™Ì3ÌfÌ™ÌÌÌÿÌ3Ì33Ìf3Ì™3ÌÌ3Ìÿ3ÌfÌ3fÌffÌ™fÌÌfÌÿfÌ™Ì3™Ìf™Ì™™ÌÌ™Ìÿ™ÌÌÌ3ÌÌfÌÌ™ÌÌÌÌÌÿÌÌÿÌ3ÿÌfÿÌ™ÿÌÌÿÌÿÿÌÿ3ÿfÿ™ÿÌÿÿÿ3ÿ33ÿf3ÿ™3ÿÌ3ÿÿ3ÿfÿ3fÿffÿ™fÿÌfÿÿfÿ™ÿ3™ÿf™ÿ™™ÿÌ™ÿÿ™ÿÌÿ3ÌÿfÌÿ™ÌÿÌÌÿÿÌÿÿÿ3ÿÿfÿÿ™ÿÿÌÿÿÿÿÿ¸ÿ¸ÒOIDATxœcà'FŒ*U0RËU<4àðIEND®B`‚PK÷H¦F styles.xmlÝ[ÍrÛ8¾ïS°4µ[»˜"õIgj2SóSg§&ÉaO.ˆ„$LH‚B’—Øã¾ß>Év J¤L9vœ8©ŠCô »ÑÝènÒ/¿¿IoÇdÁEv9.†e‘ˆy¶¾|xÿ3™ ¾õ——bµâ[Ä"Ú¦,S¤P· +<˜œ C¼le¶´àÅ"£)+*Zˆœe夅‹^è­Ìˆ^¬ït vg+v£úNFlc.]ößYƒÝÙ±¤û¾“ :u§¯DßÉ7EBV‚D"Í©â\Ü$<ûx9Ø(•/|¿ß_ìGB®ý`>ŸûšZ1U¸|+Š#Ÿ% 7+üà"ðKlÊíËb]–²mºd²·j¨¢G§šKVÄE»ì·;§a_»uoëÚ­;Ôm¨ìmgÜ4•QÜßTF±;7¥jÓq¾3ÿ ˆúŸ«7µ]É´ï^ˆm¨*’<ï-¦A»ó…«8Á8»f7ǾyvÐû“ð½äŠI„G4‰*‹´Mi€ |@¶C“¯äNyÒ[jÀv ÍxoÕ#öÈT%*¿S‰/Y.¤ª²êta—° •&Ý!©%t-㸠ìŒ|à¼dÇÙþ»Aã68móCСõ®)äÆÞ“‚¡˜Ê}Á4ê‹B®««l%¶YlÎÁ(ÝäLr$ÑDO[4VpO+÷XÒÞÎ 0S#Õ¦ï÷øH#x…A¶«87w8xU^Ó+WôŠFŒÄ,JŠW/Mx­†=óŒÌ]~œÂqCä+`ß·õ¸;)dÍ2v¬U.XDÑ +±áÅ0ŒR;,E™F+ŽV$…MdØ<4ß;$û(IWàó(á»U¤ ç5@ç 5 zKåB]±ôx£c¶¢ÛÄvSʸj2„Æ|ãA‰µÏ$—êJÅ!ë@{²ºiÚÉKÊ|EèVb±‡¥ˆÈMLÈÁçš©œJª7kl¥I˜{ºU¢È) Äc& ”&ù¦º=òm¦Ö×k×^nè§ÉR2ú( îUR°Þƒ0GRÈS žK¢–û†g1Ãâ[PzdD·ªV4)X¥,(@©"/ðBê«‚£\GÒn Fö°£Ø½¹Õ¤’[Ö`ª#aEkrÁ?9çJ%p]l!îB˜3 ª%áÄy}´,ÂŽf])_Å=J¬ÙÉjÚnVÒ>mJŠÝµ$üøöxo,qvÓšè +@ë–uÃ7­H¿½Ô'Ôð†òh\×0ŠFoŠ©Œç;ŒM`‘ð:TætÄt\nÏcíìèèwy¢¹[ˆÎ/:ïT­~QÇÇ=À,ÃØ}€™J5}t8]'?-“1X4•Ò>jJ™»‘î´MãtòC:òž:!)z'…hA6BòO‹hˆ7| f+ùz£a;<í¨¥<Ž1ø€¯å4ÆÎ6Ð€Ê Â ªÇ!,…RØ8j£%l¥ô‰45ÅXԆƺ¹›££;ƒ2á‚)rÓ<Ÿ&ñ¶•XžÆlˆÁÔuC;†œp–°K ˜,·I”gˆ8®/4ýhHû˜—ƒÿý÷?•W9‹ÔŽåwÒ2V5œÐ»Ût)ª ðdm†ÐñDgÔþ)aÎ5¼—¨f޾ÿÈ’­„Ô÷úJSRž‘„.aNå‚S÷Êÿ–44z0 &Œ=; PC³g©¡Éƒi(¼?K MLC£g©Ÿ§Ÿg§g¦¡ñ3ÓóÔÐóŒÓÁðÁT4ù¶µC¶•§ßU@žl‘ÀÞPb­Q`S(Ø*Á–EBsÔ"ͱª±ÃºÑ±af¾é;èÖ×­íÔiïn†ž(¶ 7¬ŠC‡¤Q)¶ë ±í³Ld'@¦ÇëbœŽ‰}ÁxxäñÞñÀ‚™m¾˜±’s™Úý5ãeÅv$Ñ”,M·É•¹\noO¦\Ïz SPb¨¸3ÝŸjí•Ý—îW?w¬RJ`×;š’^k¨£{dTåµ³XjSFGü€;{IV’RØ Ú)n…踂tˆ\Ñ»…î€h«ai¾¡ÆüŽì_²„ã{“#S»6KkX÷­]Ùi¤ÝÑ@Ë?Y¤ö\Aˆ7oLZûhe3—Êêƒ?rÔX8«ÕÖÒ<»&÷ìŸlš½8Ý43Îx²gvmšò˜ê´jÇ ¾¬^>tSé’üGÝt'µ;ôæï_š?ì$"ø3ø/®…?aëzªd´ùúÈ,ãá^&<œíÁTü¿;éÝÇD{ëÇ·ÁåRÄ·OÉééœÔæS¸-ΖêÏm.Â:_Z|9éºrWónÏtÌ‘[¾º=_L“~½Bž‘ 7óë²jé©®’' } y<>ËQ¤à)dê|%54÷Õ™wcxên<"ßý½Èd}#<ÿ8ÂÇ9޶4mX¿ÙjœÁjEóù×u}œÜìrX‡_•xEh9ßóŠñæ¡ÎºL6ŒÆOrôR½Õæ8ìRgô×ÑyŽQêèIBÕÓ)©Ùá([K‘Äç«î‘ÂÊW«ºqKsˆ+pòès5š2Zlå—ðW÷’<·X>úŠáÖy"9l\ů8É6ãÊVÚ}"lstÿà»aûˆ_¡á¯ÏD¤$”Ê\3Å”¤£øýj8hÁœ²¯Ó]Ù3RI½ŸU\^̦îxÕØÛKÖò(9(FH^ÿ\6QD4w‹*G”n3¼Šó£ph‘à•bÜÁ#S[ÒèãZ⯶Øó2:÷(ùüÎ3³„”JÛåmýi8…CØ¡¯ŸÝÏ?ÔÕG¢Gôšß>ÓÌ(º¡ªÉ „õv ¡åÊa”b…E7Né'óù[j#­MØùt•8‡ë|w K¿ý7w_ýPKÑ—&+y ù;PK÷H¦FConfigurations2/statusbar/PK÷H¦FConfigurations2/images/Bitmaps/PK÷H¦FConfigurations2/floater/PK÷H¦FConfigurations2/toolbar/PK÷H¦FConfigurations2/toolpanel/PK÷H¦FConfigurations2/menubar/PK÷H¦FConfigurations2/popupmenu/PK÷H¦FConfigurations2/progressbar/PK÷H¦F'Configurations2/accelerator/current.xmlPKPK÷H¦FMETA-INF/manifest.xmlµTÁnà ½÷+"î¶»l¨i•zî¡ûFœ Sµ¿$R›LS§Uë¸`cû½'XmÎÎ'ˆÉx¬Ø‚ÏY¨}m°­ØûaW¾²Íz¶r M‰äÕ(º:L7·b9¢ô*™$Q9H’´ô°ö:;@’_óåÀtó&–l=+F¾ÆX(»úx³›lm+&îŒÇj£Jº¨˜ Á­¨K'¬ù ˜Ouò6ªp4:1ñˆŽÃ1»TÆ&AW“lïè0Nµ úøC, ˆºÁ$Þ5ó2Á™D~Ø©§ƒjÔwôÙ¸{£)GHb1Ÿ®åd™¿íÛ],<¿ý[is.fZ ¥5Xè\…Î1þÜÅ¿qýò¥¤Œ½ž ×S„ž|%¾}ëOPKè|à)YPK÷H¦FŸ.Ä++mimetypePK÷H¦F—\húŸuŸuQThumbnails/thumbnail.pngPK÷H¦Fè/–ºÿ( &vsettings.xmlPK÷H¦F–Îæz_|meta.xmlPK÷H¦F$MƒÞÁ† {~content.xmlPK÷H¦FÏ£€ï[[-’Pictures/10000000000000200000002000309F1C.pngPK÷H¦FÑ—&+y ù; 8“styles.xmlPK÷H¦FéConfigurations2/statusbar/PK÷H¦F!žConfigurations2/images/Bitmaps/PK÷H¦F^žConfigurations2/floater/PK÷H¦F”žConfigurations2/toolbar/PK÷H¦FÊžConfigurations2/toolpanel/PK÷H¦FŸConfigurations2/menubar/PK÷H¦F8ŸConfigurations2/popupmenu/PK÷H¦FpŸConfigurations2/progressbar/PK÷H¦F'ªŸConfigurations2/accelerator/current.xmlPK÷H¦Fè|à)Y META-INF/manifest.xmlPK‘m¡hppc-0.7.2/hppc/src/main/javadoc/resources/interfaces.png000066400000000000000000001530511300364116400233740ustar00rootroot00000000000000‰PNG  IHDRèA‹Õ3 pHYsÄÄ•+ÕÛIDATxÚíý_l[~ç ž6ܶºå®«e‹®*]ªYV™Û’³„ºyÙª¼¦,èż3·»ŽGÅ^çøjáé4µÖÂØz€r¹°f·™ ôÒÄ`rÌ5¨‚S¨'„t?Ñ@>ÐOä#ó‘{þDœ8ñ'ÿÿ‹Œü|n\*2òĉˆ“¿øÆ7Nœ8G\Ã4åN¹§ÓÓSÊ} ´Z-Ê=àíÛ·ŸŸ”†™d2Ÿ!3‘Ó<–ûÓÒÍ\áóZáa­àĦœ„\xòÕÝš^R+Ü͉ûꫯäÌç{+{(÷›&‡½‚L|7wGf%×_QîÄ{*õ],åN¹Sî”{zʽY©4¯ B 9ß¼¾®—DVʽ)G—™äÉ%¥º·¤dþŠñŽÎ QîGGGÙ.Ç~pBå~~~žír¿ººBgæFgÞŸ 8*ŸvN®û ¯—û‹œxÒ”;±&Ä‹Úõr®"§÷µÊŽü¶V‘ –s%"µŒ*ÁvsmïzY¼ M&êcÓ¬(6ê*OùÑÏÄûVÏommïsï³á#;T¦§özpŸš÷ãF]ý­]_ç •“¤ô\WGTî}N”;õ3”;åN¹£ï”{R¹KÓ²WÒϘm`ê¹JóD›!J«3®rϼÝNi¼›B”¡-o&åŸW'uyÛi–¼Ò_ä æ~ug»)÷?ÿó?Gß“Á˜2èû”‡r%MïŸJòrÊ}J?K…r———²@E©~]/y ê^ã5õÜ\SiÊrPÌmÑSîܯÎ&ƒ=:¶PZ­ÖQGd¹wNЮ.þhPÎÎΆ̡¯ÙÝÝí+«Ñ”ûÛ·oC· úæ(x·ÝìzËjÚw¸~‘úÁ^ºkBÄÚ3¬íFk•~ï¢/.¾n7UÛ%§±—»¼Sí½z@8åÕµÜãÓ«Pqïô[îî´W²Ü/¦Rî]¹uëWÑŒ\WfýjŸ¡Ü)wÊr§Ü)wÊ=ûå>dÁQîÄ{*Ë=é6wµÇû`3Ÿ/?køËóÅf¦Ñ1·{fˆâj,Ÿp•HãA$OûK'ìp8±Ì3ŸÐ×^M¦ÜcSu©C¹÷2E޳k¹›rì«J$±Üíï7L¥Ê,éÌ£GPôúâ}ºå^¨4ÕCaÝ֡Ҥ܉wÊ}0Œql„}T#æ^Šò«Æ×5¥ÏGvôïÃ<‹ü<ÍQ•{RA·›Êù…i•»ºñi”ôN{£Qn|]KyáíV^,©oõWñr/V½àr?ÊòBÈ»*¹–\"t¬Â(”þÉ“/›æ(ÞÑ÷ì8ë4GC÷ƒTíÿf“ F+§ºÆÊ™ê’[K#Ä‚Ñ=÷2ð4Föã}å>“ñ”;å>ÄYŒ½}¹Û+˜ôéÒõ7Ô}À’yâ!—Èo¥‹7Uá‰âq33pÇd÷)›ëx§Ü§åN¹Ïr¹ùåg}Mùüwû]…rïtU¨úu³ÆS[«êμ 5Ѹxfž¡«—œ‹«êâ¬o2‹º¶6Ÿ_2Õ¶ö&S8Ë)÷ ]/ÎÊýÃ4˜—û¦å~qqÑ(çmŸù|Ñü½¨Ê™¢œQóêÜ’éÊ (VÕ¹§ª²ËrÞdRTµåj¹N¬Ê¥:ò®û¶«ï×Ó ]ån’ا.RÍ«J¯伌¿jy©aÂè«‚ûØÄ>Šé·Üzò¨ê0AíE¨ ^Ô2€ÍG5sa¾ôfŠÂ›‘ñŸW Ë*eµ¨þ6Ê2öõ‰1OñÞqœBwhèÅ o>@•æ¬Ç{:ê‡ûFÛ§.¸?’ûj‘rOˆ÷ªV•HÙ•ÕµêêLb Ô“¿ˆ«JJb…®—5ÌÃtʽÝkÁé‰w}ñhC£Ü!¨Ñ™±ëL¿š3úr¾Ëê©w²w4 ÆUî¦ëÓÏûŽê“ÝtæP7]ý­îÃ@NMÕ_D­"’zu˜­Î 'WO°ýþhÜ厾gå~5%åÞû0—¦Ô~q~>X©_ªš™ÙªáIE¹ßÌ>?ÙT~rBN¦äÂÛ⎪¢ªêæ¾^¨êm¶7?¯îÖz+÷½™Ræ 7¡s¨©• åN¼£ï”;Pî”;´/w¿¡R½T¿V“(˜–LÙ  §©Ûcé£+ù£`×Í_ùUxGg¦OÊ»”Él¹Sî0írÿæíÁ`M±¿.½uóYüþ½”¿pœÎroš7†×DA/JjÉ^iGoæMëYýÑ+w÷-SîªY}­²¶§ßGP™¨r-9#s6ór²#ÌË…2±y/ùz¤¯õœŸŸ¶¬ÝWYˆ÷™-÷AβöQÙjµR"n¹—Þ¾ ½¸¤_œ OÍÎ/:¥¢Üg‚NåÞÿD¹Ï±ÎPî”;厾C—rׯÁï•„y[Þôaf¶›z*"ž'½þx´Üõýª~󺾳]0¯tîè·=î°J¶{+Yîû·;À'ÓG_Úõ] Á`[œp¹‹áþ3©ïSŒ÷Q N¹FgÔSCïyaÛº7å>}/„z‰re¹Wš~cÛ}IS–{ÓŒ"k~ƒfSõ—iÊ}r~}Ÿýr_obVùæ›ozÉpÈ]²å>p>~¹aË=éFÔëºêENèçsö&f¼Ú¶ âWnnmú5ë¸oÁZrOäÍ]‡l©uèÀ Cè •š––'Yî=L=ô&J¯ŸÍöû´/Ú£YÏ¢õ^î§1–ûTØÝÝåº:†o4ÐK”;~†r§Ü)wÊr§Ü)÷¡Ê=…¸ï”ûpåžt›ûÌý¨º¦,?Kùqw÷GÞ`ËÅU›8”²‘\}±½ýÃ{v¡·h³Ê“3)úfÆÇ£LH¯÷Ä­NqGä0ér·Å×㈛¶ÜÍpØÒGrîZî&=\j(,z*÷6S£Ï‘DçTg2Àœ–ûÔÍñ>¯å^¨4ÕÓߺjGVOSÑà#)÷Yqߢx>ªè>kþ=Ë3÷>¥­oVFrlOž|1Ø4ÑrŸn¼ãg¦Ìâââ´t&]÷«µZmFcÊ€Ò𵻡ês¼êŠê’YÞ(/ÈI.´—Ù§að3óï@¹Ï}¹| O÷ìÎN¹WÍ%«ñÀ^ÁÌÅJˆ%5„WûšI y /eùò3÷jvpppïÞ=ÊxGß)w˜ÉrÿòËÏÆ:Qî]. þKÌ æy·œ+çõ3¯[«ËƃrùYÞ¦qÉ}˜N¹Oî‚Ü×ÅyÿÃÄA߯?}údæÌçËñÑ:å©£G°õæ =cW1óż“ú²Z”g¢I\•‹U?eñ¢QΗ&=ñ”û_r¹»IÌS—¢–{ù·(Ô³¹°œ_2#*›G.yçi\Õ´ö 7Fë±Üe,ÊP•ÿ¨àyõQ‡³{¨ùF¹Ñ(Wýy“> Zl$•²nS¥Ïþ â½k¼W—ÊÆ–xÃùÛçK-ô}´:Ó˜II¹…'2 äžÂøKlä+¡Ð Íå±á_Ë s-†ýU>oI®©N”i•{Ú:ËïïÉìÊz£<“×Õô”{#lûQ—òÊ}È.«§ÞûÑ4K¹;=—©6Žb£®{Ì«¿?i®é®ó¼¾ jÛ“^çÞ¨K`ûýѸ'Ê™•ûÕ4”û·¿÷/{ãÒÜÀݤRîÑr—oHX=sÛŒòº·òP}uGÎt(÷\¡" •åN¼Ç6²×ŽÓwÛãõvSÍÈ¿v šùJwŒ­zÈÖ‡lfFYîSq»i(÷)Ç{‡.Ãzét-Þµ›Îi2þ}VýÌÈîKƽŸšÓrÏöà«Ã—{×x¿­ÜCè¡vTµGéå>¾rðÅ“Îå>ßõikâ;t¹w}ÆK¼¯ÜÕ;Ç Þû¡¦÷— YÃøË½Ç»í®Ó½·O‰÷þÊý¡©ZÊ­˜Š$ýÜã+9}~bþ–t•“ªxº™+˜ÄŸ× *¥ÿí¬•{ ôý»«?Étkùw&Vîù|þˉƒ¾§Êr§Ür ÜwÂ}B<}ú4…}åCZÂýíÛ·£ªHxr{ðŸúÎȉ Ì~¸ßÌ„œ„¸™[QEk±ñÕÃp ý}]µS'“ îŸl>ÔµørÉÝšüjż÷ ¿*Ý͉‡'jݛۛr¹;ꙀüV?"x8ŠpW;³¡8äVnߑ۽¹­¶xCxßêgf»rwÂu'Üñî½^æ$Üß½{w~~.ÿòCê@¸áN¸áîÑÔ“(ÕõßR¡ +ê^5B©nÞ@óî©’ƒBA¿ ج虺ü«~,ÿ·Õ'ùhëß·bFë“óòŸ¦þ‰›óî¨;`fÒîÇÇÇéÙ±ÃÃC«_NOO ÷™T÷V«Eø¢îɬ¿|3Xg{[ÿëlÅ¿}Ùa¾óÛ‹CöøWÿÛ¯èGpñë%:-áþÍÛƒhO4µŠØ¨ï˜Îhj•åœP}]Ôê;Û·oP¹Ðt*¯©ƒT k{A?$záµÉÊíŸäëÒÛk=Êh¢ /~ÿží”hM”T&r¯öJÞ¦sjížÈ}߾ȼd¦gŽmÕK鋜0É–7J~â’·cN';f¡ÍÙv»syy97'"}$ŽÊÊpŸÈd½6ܧ8¥™±ñ>FÓ óL{w·5Xìîîby{÷ÒÛ·w48ª)³á~ppð«_ýªÇánݺ5@mI­V“+ߣ ÷fÅëá´Yñ–ÔK{%±wô|*Juów£.?6kZÑr¦`ý( 6·á~M½;êN¸ÞpWï’v…P&ÜQw Ü w½gï^ë¸ÄŒÖ1/Þ=mõî0æ[Õz®ÒLüjø¸Ÿµp×/õsJ±ã=€Ôýèñ—EéEM&à-— ͸-µÊš(-ëG°öê+•¾`².‡‡ ‘á~ûöm.˜Ô}, ð‹pǻϪwŸÃpýúuº¢e¦ ýôôT†û¸Iî wÔ=;á®Çô_þlz/ÖKæ¥Pùíµ¿¼àŒK(?šOBš2‡‚êaμ¦H¸îS÷õõuûïåË—ÒR›×rF~” ///Ca?ÂgE×_?’CÉ }ÂpOµ™‘B¸¼~Ç/ö%tÂpÇ»î„ûÃ=±Æ0›á.#`ê/ õ…“ßÃø)=õW«âáÞÃè§#ž––Óî‘æ‡÷îïȽò_w_W•_Ô®Í˦ò¯™ßÙ.¼Ú;Îxíjù^iMvô;£6¹|ÇsT=¬­UÌ›£ê‰ìÞÈÂ]ïs}Y”¼­è7\½ç¾z+roÍ›£¢ ÍÊ+wiÇ–yô;@¸'ãIP€n™x/ÑÊ}vLL4Üòy5s¾üLýÍ?ÈZ¸£î¨û©û<{÷©ïj«Õ’—SnU wnU wÂp'Ü wÂp'Ü wÂp'Ü wÂp'Ü wÂ=ÝáþæÍ›««+ÂpŸ½pŸäS1w»»»?šð3¹ííVd“|?¥'¿óîUý×kÏÐý-Š…†üJ»°ÜøºaÒ›Vú¯(®Ê¿Åjá.3)Š¥ªÎÖ¬nʾ!7$Š%µ­²Ú ½Ä›ìîéíÊÝ6û`Ž0Ü{ßI{øÕ¢“ÚçêÒ…)ºÆ¯/üñ_õîÉ?“œªKòg2­SäÎ\øùëý\ íïÒnëfÊFwk¨;ê>ˆºÏê·ªsÅãÇçùð w Ü ÷Œr46÷Y w=æ·(xCK‹B©n–^›ÈlE$ê>PI¸&·H·') w]]xÑx`jån«*Hÿ]8ù­ª Õõ’º^ø™}/N¥ÔµŸåü‚©¾4ëšú\¯ÒVW›ª:Üü‚ðk$#ÖeFǧ"²ƒÅQÑ_¨Ô …Š(©¿Òé î™ºU5páŸôþü’‘ó<¥aEâbUNRªEaa½ŠûŽmÃyW®+œç]ýœW‰‹ya—˜½Þ^­…"dd,xÄ“$J%3*8ÒzwÈN¸øð“‰Mîvÿò/o’›–ÓÏ~v·—J§·9š8TD~wee嘒™Ij"¡&,åÅ‚»$~}køíäEÒ´tà©*ÌWÍLƒp Ü÷nF& 2÷‰™Î6·_ùÑ*N•æYdõ÷^B­þ¬ëm™µªÄ=á>–p·¯GŒò«}¥{§¯ú¹3›| ÝÁÁQ‹wŸ„;áN¸î„;áN¸î)¸3NõD¸îC†û3ÿµüU}ÏêU•ó¦µÙ3Õ}€®ªúËÍ* çÝÈvÁ_q¡!×Ê/]éC[,Š…¼XÐïü?ó«–â_‰¤á+wÂuïƒOŸ>]Ìx÷¬1L¸7Êyóo>_6KäLQäó"_¬ªåfI¹qá/¹¸¨Ía–ç‹&#¼Üh¨ÕËy¹¸èE\µ(DÞfÞ0[•›ÓËz¹Ê­XUßɯì†ôÖmÎ6«†ž÷’é¬Lž:u5X‘pGÝ£áÞƒ@j'æk÷Ôr§yQÌû§AŸ4ü°åß@Ý{÷Ž/Ž8¯¶4”}·¯¶Tõ;%B›xóšKCeµd_|‰<ój”ŒG— ŠbÉn7òÕ¸[ÞFÌL£ç@“ÜSÐ÷¾Ý·‹™„/¿ülÖ§†{U;q2¤¬=ð‚L£ rQ÷º‹¿ þΠ›‰¾È…*óF9Ön«‡öÄß7³KƳå_j”ó6§—j…*cf 9Üe”ÈØjô(¶râ—=^¼³È9œ¯”ÝïÏ&Ù%*ö«îP3ã yÏ.¢1:+ÓnÓƒ­Õ˜·[ÕGÑn±p÷ÍŒ‘r©Ü…ñ0!‹ÒˆÄ“[ŸãU”ófŪ#äžѦE-i”Éñë…ŒøÙðîS{cFϺºSï>ýpQ“›Ë¹ÊŽúXßÙ.¼ß+©¯j•9±cÓÔ*2Íòv]ά ™ )gäWËB¨¿ÛÍeQZÛVQƒ¬oÔÕòØWk{sϑº·ª@¸Ã|ÔÌàÝ!ãáþíïýËÏOJjª„Ÿï­qÇ.ñf¼i3üQMj•ØÂH´ýâü\ú¾IN_=ËB¸wõ#¦=ätïíSÂ}Œá>Д©p¨Û'Ýßwk2ྺ)Äí½ÒÍ\AþU ˜öVL¦»9ñÐ&«ÄÆWŸŸlº‰e29c[8ÝwdšûµÂmqG®"Sʵ:M L>2Ûºå“Ép†uGÝñîܪî„;î„;á@¸îsîoß¾Ívi>}ú”"Ü w ܳÅéééñññãlj*Â}.Ôžæ wÂwMBÚ9::šþþ¬­”„;á ÷»9a^æbEl|u;'¼ŽjõWúÕ¯næôÛ^2ÅÓÒÚ~Ÿ#·¢r8)ÝÜÞ¼­gäêæ¥ 3™…2ç‡~‡»Ü™ûâáö³rF¿Œ"ä&Ì«¯j…ûæX„0;–؃.á>¯ê^+Ü*nLGÌj¦VЯ8©p—“yóH½¾d¾Õa'ƒ[NjÝœzÅ鿯Êmqç¡íÄÙku2Ôü·¢Fî7õ9yלibEïÏWÊÝ9õ6–L£vl{u'Ü13„;áN¸‘sî74üŠ0᾿¿ppÀ¯˜ÂwÂwÂwÂwÂ2îÍJ¡Piú3u½HΘ/ëz¹üÂ$ ÜÓCAJuý« ýû5½QþXÑ4××%Q¥ºù}ÍëýÖMïoI”æ%ÜMD3#KGÎ˲0o3ØwLÂ=EánÆsÔJø"e;“Æüvuôê÷5?®™o6+æ[÷$ÁÌ`f€p'Ü!KáÞ{o„;Ì|¸¯¯¯î0/áÞ{î0óá~~~N¸·ª„;d.Ü///‡÷í÷Gž:ïêä÷'2ýÏ}8o±¸µµ5î~©FûþþþðáþþdÒSg&¿?‘é¯q>‡ê;î6GîÏŸ?m¸ïœ\¯‰ÒZN¼¯UÞï•äõD7W1ßÊÙå ¹°ùj» –Ô*b£.Ê™WrÅ=¹z]._ÞnÊI¨9ô·:ŸH¸Ÿžž¶“/Y­b7±£7-ç—sbYïŒü¸£÷AþÝq’íÔ¼”jÓ9õHrYÿõ¥ôÂÏA®øjC-ï¡ ÷G¦]æåÏ*ÒǸÂ}$õîî/­Ât£.WÅ–(¨}ø ê2V^Èڨ˿2Í‹\Á̼÷Âýú•ÎD¦Ôß õmR¸ËµK¸Ÿ4M¸ËLô4×DÁ„¯·'2vkòä,¼ò“™ÓÌÿ¨Oƒ½’Nß´ÇbÂ]ƽ9[^éœí·n¸Ëm§<Ü_¾|9GÞ}ä᎙™-3C¸î„{FÃ}$Þ=µÕ ¯_¿¦þ®÷p?™öTêø+ Ü{¿—y¸/jz=³…hµZ}ë]¶.ÜkúïF¡Rsæ 7,pçc=uá~uu5­pßÒô˜øãÇ·nÝê+ÿ7nÔj5z¤áÞÌ™p¯—öJ*²s^|«å¹JÓ= ¶ë•“fe»y­þT%œ™r¸ÛNÀœ˜™ˆÌ§ÔÌœî„û¼xwZDîsT3Ãë„;áN¸î„ûTyÚ££#—pŸuçúC¸ìh wÂ}æÃ½w@¸g>ܳ_™¥`"ÜÇîñ§¡íŸnĆ( öø‰p'ÜÓîº9@Í]¢[ä*ªj/àÇ·(Õ7ê^ã‚“ëºmz`ÛÞL'ÜGbfRÒ˜pŸŒ™ ·›)33’[UÂï>á>Ž×;^ä ÞË{¹JâË{v¹œÙ©U¼×ç䊵ëe!Ì€æm:õ^œNì¾'§üÇŒ¿ÔH¸S33ép×1z5[è8ö^õ—¯ õ©yEÕ¾Ù-ëwU½W¹ã/ªZuÿõ_ÿõù ÷1Å%᎙!Ü ÷öÁ”’Ž÷Áª³æ¨ã)6ni¨ˆL­ §íÕÇÙ~½£ÃyL¸O=Ü¥e0ܳL„û¹ºº:88è½ ÑÙ÷)¾šM¸§ÜÌÈpïo;”]xL»f8‘*ÐP2ƒ«…Ó›‘ׯîSìxƒpOy¸÷ÞãŸPïW(T̘˜ÞõR]u¡Yò–ëÆæ¯þW xjVlêÄ2i³}ÄÏQ·J„ûäý÷+ÿ̘^ï ÜÛñæÍS“!o[¥ Êh_“ó»»»Qg—w¤®†p'ÜÓ¡»¾™±Q‡}®†p'Üç¼;áN¸÷ÃH«!Ü ÷Ù÷‘ EF¸î³îY &ÂpïÂ0Ã¥€~Ã}º{x­GP,ŸõõõQíC ‹eBá>L‹È© iøÞõXä¹=õ¦ù‹ß¿—¶±}dð]\|=ái:á.5cÈp‘¯6ìpvþø{¹Š}A)òÞ?&^ÝMœü;©÷úÄtÂ}¯äS™4íøc Ž0ÜÛã+ýNcPJ=”ɸÃ=ŸP j¾ñ@M3î½×»Ë«p¤OF'XÕ êç×/Úíá®Æmô^Ku_ÃÓ‘äG©ßF5c;š½Ì0¨þOë~ª¿]v~ï‘„û«“P<½÷7äîðš(Øoƒp×g…q²Í‰Ýk¸·+F{^©w|Ãe" pÙ¾èØþäG¸W‹¢áÅÕ †{œEçy§uÜÞuVw=ýî’pxÄf¦çb4᎙™R¸§Ï»÷îx÷ì‡{–ª·º†ûLà™#÷)ŽM·«™‰pïwп±üØs?hælÿÞUU¸|WÛ‡?î0f†§ªí•p'Üg>Ü{·šp'Üg>܇©ˆ$Ü wÂp'Ü wÂp'Ü wÂ}ráþæÍÂpŸ—pï½§(ÂpŸùpÏ„;áÞ…´uŒF¸îc ÷Þ»D%Ü ÷™÷Þ»U"Ü ÷Ù÷ŽÐ@¸îcTwÂpŸ£p§‰á>“á¾½ýɽh¸´´èn:%o:öò®êÔwõ³Ï¾3/†ÎX¸—ó¢ZùüƒH— ùò³r£M¹4…:ÜŸy=„s–«±ÍÙù†íÀ¤úu£¼0þpïy'«KºRñv»ülàpo÷35ü̃…b)o{wñ®vÝú¼„».ÁUUF²8äo¦‹Ï”£÷;éR+—LŸ!yèy?ÜEqÕœæ«ÞÃÝü2jm›IâÿŠ«6ŒäG³\ˆ7ÜͦM&"¶Æ{ï;©‹Îûë)‚w6JÕÂ]Ž=QåQôî~¦†îéÃW¥áåo;3Ò;oÝL‘‚2mfìOÕÏdÂ}|fFt¾ŒtÛçɘÑÛµÎKÙæ"Ы™ègêºõyQw¼;Þ=ËáÙ®™ÉvwÞÙ÷C á>‡OHæ1Üg¨Ÿ™”W–Zkcf÷Nð˜‰pŸ£!Ü ÷ù ÷T C¸Oï®Y1Ã1ËùJÁKEìÂ}f(J:¶e—ôxâMQªËÈÇî˜ Ü ÷ ’§ª„ûL²¹¹9á^Î ·•žÛ¸Ò|4GÓÍ–T[½|4e¤=jc—_h×ȇpÏè=kê1ê^Î/Tu@Ë}6m?ºÁcU·É”ËeÕ@U7õÂ].l¨¦{&ÜMãM¹®iYn<ó›‘>3ç† }™¡üÛ¹f&Ã}Λˆ½yóƆ{¡P‰|ko^Óefz”TÅ=f†pcŸªtÜËè/Õ½y¼{Ã]¿ ñ,/„jàßPc½ÊËŸ¹´I‘0 õõqÕ¾Ö`^í1¯ÉäÅ’yÑI¿i±¼OpñÌä#s0—ÈîánZo«‹²ð/¾ Ò\šk«yyÂ,¹ðß,±ûSUKÌ; ù~Ìh¼A¥PHÛoöÓŸþñ“'_Lxʪº?Ó¯e,¯hÈÐÂÜóú%ˆB,‰ü»"¿”×óî[sÞÈÈz‰ÌG­ë¼Ћºj¼¦™¯^¨ÓLúKµé¢z§*äD_ä“iòKß®è1Ü!³‘˜Â}ŽÂýg?»ûáÃO&3EÂ}bÛµSážÂºšÓÓÓ£‰CEä,UÞõÈL„;·ª„ûXÂýõë×ïÞ½KÛлn¸«Û¿=ò)Ò Gç¾7÷žxþüù µÿ@ÝSÞˆ ¡*¬–¼çMÅÕP¸ûÞØp75l‰}oØþp‚o;v¼g^Ô±™Ò`fzïác°¾7²ñûÎ|¸ß»wo¬ùÓDŒp1Ý¡Èæ0Üašá~vvF¸Ã¼„ûtqÇD0öpŸîPd„;L4Ü{ïÇëøøXÌõW%"ƒpO¦÷¡È&_¥0ÀÔµ Ìo¸÷^ ÷Ã%t}RèuLî4Þt¦N ã=—· ÷ýý}âƒpY¸wè‡?ô¤Ð³ÀæbY½œÖ¸X-ç—„X*WÕã@¯i»ÿ¬ÄO!롯bÏVd¸¼÷I˜÷pïÚO “ºã)”Ë«½µ€™!ÜÛ²¾¾Žw‡y ÷ézÜq?fÂ=Äåå%áóîÓ…p‡‰†ûùù9áóî»»»„;ÌK¸÷^33ápÏç¿÷å—ŸÍôT«ÕˆÑt…{j_ïøôéÙLÔ{v˜ˆQÂ}p÷â†{Œ2ºÅR¼Ç(Ó”ê4´(>k4¼>¤L÷¢fØõ|ù™·¢~Öëõ¥ÛGØCU·gÕ%•Þšf:+MüŠp'ÜGî^¿?@ùQu‡ë7ÑñúT]í­Êà3}I«îÓt_ª'@Ó[ ê ðÊ&e¾¸ªwÁôhÂ]ž6æMçªß¯ mÅ “µûŠpOu¸O÷}ÌLW>ÌOž<™D¸O÷vŠpïÊÅ|0¡poµZTD¦7&òù¢ü«;¸•4Êêæ¡¨oŠ&ºWÉ—õßb£œ×KŠzùrCA³DÎ7eÝWGYuWßšÕMÎê£\¿\ÕõSêmÊL¼÷hü å‹vë*g}ÿsaVi{Ul˜@橾ðw{rá>]÷>ý,#H\Þ ¤‹ª‰NyC^½ð"UE’ú+“éTUU /­œS§I¾aÂW/­–óº#r†ù(ÿÑ›ñB³áýU'[µ˜÷ö@mÈìU³“‘?ßðÒ›<õ_y–8»=©p?>>ÆÌ`fæÅÌlmmî3îF\GJ£ãǾð_m+G®ERÊÂçíõ¨Í±L(Ügï1S›qAâ#—˜Zvû–‰Wçhº\4},ê~‹þ˜%ºÖÒ³Dço†õ2•Œ^Åeì«o±Œ8Ü¥'‘Á£¹ã³/ªžÇÈGȳãÖ.耖Õm'ªÖoT‹ž ‘_ªÊÙPþú«àSx£:ЫyíÝíÝWóÚ©7“c]áÞIÝlj\"Ì=š¡Ä›Yõ–èpׯÿ©%ExGwÌoCÎ#¤F0zÏמ.É̘›¿^õÖ¹ œ(ƒn—pÇÌôgfì=¥µFÅ{Ï¡á;)ö¬žˆsu¹pÝN9_$Ü2ÐDl´áîÙ?ì<«`ÔT/´µ®K6¦þÚØš m#²°óêΞØUŒò,“®Ð”3Ö´˜ú"s0u¦“63Ùî5c‘3=¦ifR[ ápo$8 ] ž\%R¬æó1ݧ!iWWSíņó·:Åpç1Ól„»ÿ”'d9<ƒáU‰ØÛDíjª2äåMx¹Tæô∜ÉÛPàLòe9S,šçSUSÏxJã·­äÑn~†fõª»34"€¾ÍL»*‘ÑUØÃU“‘KJ‡=sëÜÛíØ„Â½÷.QGÎÑÑÑý¯ÿ•.Ø{ w¿©Lï^¤Ü!"{|ÆÔ˜”³ŸP¸÷Þ%ê8 k»ýa›µ8†ÄÖXÏà6­1á^.ªßù“5-‘p÷ìSÜðÌb¸O·"’pïÛÌ´ ¸6ža Í ²îçççïO®g}šõWŠh"F¸ÏQ¸Í½ôf7ÞŽ7z w±QÒ\bmïú}­òjC¼¨]/ç*ò«¹‚Y(?®íÕw¶ ;raíúÕɵœYê[! 2ÁNaS&0ùĶ|%77'ᣠ÷Ý*õ¬îMñ˹’~úB¼È©ˆ\“k•÷{ê[!J"W‘AÿJÍ »ŠJàœ¶ßuú«ÿíWãÞáN¸Ðá5àÝ w*"³X™Ú.Qp}¸§öõpÃýó“Òh§>DîäúzÂáÂýf® „3毙†ãønM%“3·õ_=mî„û ‡»7Õ &Ü…¸#—ßô¿Òá¾é%–ij…›fÆ9O÷få¤^Ú.ˆ Q° kî·i÷鶈$ÜgÏÌè€Î¼°®5+Û…‚ wµ°YÙë9è竽;áŽwçm&H÷Üãvúû¿ÿûÄpÏ•êí¢Ó*ºt2íT¿—)WiN-ܧ íÝÓSéºpá}SÑ_7á^«öJB·œ©i3#—×t¸Ëù•·J½tâ8ïd0ΧR˜Z¸O·'Â=uá^Q7¸=:øÁ¦ÚÍLç~fÆÝÊùßý»7îMî}…ûüVDÒ"’pŸÇp‘êŠ\Å #ùqy[µtß ‡—zoc£Ò.øÜÄ2Û5Qp3L^«VYk÷2Ç^‰p§Aá.ÙÜÜüøñ£©¥‘3¯_¿– ?~ìb}Y”d|›ÛÑ åß5Qz¥#R½r¡ßÒØÑ¯n˜¿Ëòÿºz¡É tïÜ0KL|û šò£ÉjÇc‰z×ɾ»dÞ‡r£\.‰å¾ëD¸î=‘`fÚ¨©èùUºá§>¿"Ü ÷AÃï>OáþÍÛƒ! ²áÞ¬ •¦?S׋äŒù²®—Ë/L3î3î%=X…™)Õ•ëánj»m·I@¸î‰ánîÄv¬Wô ­wG§oáÌm›w÷å¸ÊY23„;áþÞôØ­š÷æšÖSîkºó3.áN¸cfwHk¸ï_ýþƒ/ž 3î„;‘„;î„;î ÷ËËË·oßN·£½»»?zpYÂÝ=Ú»ÏH¸7ôd‡ ·ÕÔx@¸î™÷ê’YžÏ?PáÞxPn|-Š«Á9¥pù›ÂÃO„;f†p'Ü ÷‘„{­p3WxèÏÜ×½U™þ«L>ªG«ÜÛ{ê£îé꫇Ûwú=]Ùķűñ•œL@ú+•ø¾ŸêKwts{ó¦X¹½]¸›&™¹íKˆp9†&Sá~[·Ž03·Õ;èÂíæJ¥îºM%ð»z[N·o¶›«ûª+¬¯d4ßß&Ü…Ÿ³íN®(˜íªÓÃíL‹p§"3C¸î£á»«?HÛ”Õpÿr>ø£?ú£ìWDôQmMá@¸î„;á@¸‸Ïoß¾=‚YæÑ£Gœ¢ˆ{‚¸óÏ4F¸ÄwÄq‡”„¦Ïåå%¥€¸#îáêêJ*ûææ&E€¸#î™bkk‹B@Üûw™ …=TN~J,¨££#JFMk«È î3/ø¯¶;ϽÎå™è´©*‰ýþå<£)oë…ws"ÞÛv÷Éïã^äîøõÒwR.î7Ínê’i3mªîû;ä`º(GÜ÷Å]K§Ñ"5ćVá›F@Í` ÛjæáÞŠIcGQ'x⵩ Yñ Ñ-¸¹yÚ[ _TôZvs2+àþ†0»l¨V¸[Û´bgfîê‘ú)?÷wϤQ™„g¦"îÁBø«Z/WƒXè¼½­ŽÂþöÕø*þˆ.^Qø‡yÓ^S»\Bw@Ü©–•®%9÷1LJ%ÛßRP-ƒ¸⎸S玸#Ϯ¸§ÞÓÄ=kâþñãG!„üK âžq·/aˆ€¸gGܾ…€¸#îˆ;âˆ;⎸⎸##îˆ;̤¸7+ÍëëB¡Òî{ûU‡4ˆ;ÀhOÉQÑî´Ìé é÷zÉ]"„üX—s5s]¨4eQª+êôõ’Ú¹\}Îqh§ªæ„ Î>wÆñ[æÌ wúü’hó±ßº>,8 ³\þsíž×f[ö,Ö5i +âž2w˜qOO>€¸#îˆ;̇¸I-nµZF‘í¼\^«ÕÞ½{w~~n¿2OOOwwwäLä«««+¹ÊÏ~ö³Á²=дËV®8Âl¥¸·Ë1?zü'Åèþæcü'«Ç¹dòÙÊÜ&™­IÖK¶&D'–mM“Îl÷pvv†sw‘QˆŽ'"ÏU ˆ´™÷7oÞ îã¾Úeé)˜QÇ9â>ŽnÍgZÜ‘°vÈ[f °ˆ;⎸ îˆ;⎸8c-,.."îY÷oÞ¼?¹ÎöôuiðkÞâ÷ïe¾|ºNý‹s´o~ôç>,[[[)÷9õK«ùZeÇ,´3¡©®6eâµ½ä¬Ör;¿ìÌ·¼ ÕE®àû‰ÂÅýððp`qï«X:l‡¯‚M´-í> Ó¤YbÙ/ʵaÅýøø)Ì»»»3Ý`&EíÜS-î{%_h R¼^\ïlŒŠXÞnzÊbnÔíºf^ ½NДR¢fj#+f~Çä¼W2¹y™X©ªU^Ôšrž<é)y*™N©vÆ®«Ó¼ÚÄýñãÇÂAÔÓÞø­oݦX¬øÚ2 GˆW~2“›=®ÈæÔ¡…“¹…i ÙÝ™½,‹‚*:=¯ò×Wbóë˜Ý“«ØuÝwÅ}ssÓ-@)îO¡7Úz/_¾är2Z©ä Õ!ªe’-êÄ&%aìCĹŸŸ+©eµÌHŠe²e«®=ÞEÅœ{«Õzþü9¢Ó 2ØwÄ:wêÜ©sGÜaöÅ=%Õ2GçOþäO&¿Ñ‹ôìììhÈ4)qÿ·/_¾?:šóé߆KföÄ}×íô7…<>>65¶£–2©ý³Þ¢Ò,oO®¯ç|*…ulöÄ}>Û¹Û'r£ÍÖ>îë½2}0¶¶¶Ì†Ö××Q.H—¸7+µëë\I548¹VÉkz‰ùV~ÌUšv&W¨Ô*ùQÎÈÄÛM9cV4K®kͺú[)x u¶Ûò“^1HÙ¬lÈ¥ºÉYÍÈ%±‡¸Ï›¸_Óå/ îc÷@¬+'VÜ›©¶¢`gä·ê£L/Jr¡J¯>67ê×RÁOTá}{]÷r“ÙÖU†JÁë%wÛ…‚ÉD­ë\QwÄq§Z&+â>ŽûzÄqGܧÌ8„q˜iq‡8³'î Ö€¸CÅ}VîwÄqïƒqtЃ¸ÏI⎸§WÜ÷÷÷wÄwÈš¸£ë%Äq‡™wZËÐÎqGÜqGÜwÄq‡¬Š{Û×P½—KÕ»¦_U5ݯ¶ú¯ªšN̼ªªgötz½Š7lTok¯$Ì;«ˆûÔ„Ï;dXÜM›Þ]¤(]˜%Zg£iü¥Ëõ’‘cQ(¹ÌHá¶=Ò„ú“Ñ×yÍP#†•J^&ášNfjóéÜSRçNîˆ;P-CµÌ(IIk™öâîr§†…ë×âî¾”X-©„ñêLtÕJɽ¤¬¢F¤°|wTqGÜgZ|¨– ØÚÚBÜQIÄqGܳ&î4…D%ÙmÄqGÜwTqGÜGÃ8z-DÜwÄÝFܧL«ÕBܳ&î2Aæ;øíeêPPë¤<Ÿç¡ »^¤¿oÊaHq?::º¸ø:óÓÒÒâ‰{‡‘ÞwÄqGÜ÷Y÷© Öw˜ºæ‹šÓ®iÆÆ3£Ü©ðNêò«í‚]¸,Jrá+3S«xéÍ zfÜ;»®œOe«‡ÓóÇÃ+™<ƒ|üœÍx~;z-oÞÏG ¼çŒÀ'g옮f>[sm[¥T£¹ûŸ<_Ľ¿Â÷ËP¯M°Wò#ôÇ)´¿…\"Ìx¶£(®Éˆ{¢wà•3|£ ÅÄ8QƒDêÒx¥Çû]V…Ót£W—˜Èž¸çM7’ÅՋƃ†ü˜ ÊUó­þX¬z3ˆû sîêÅ0캒 n{æxËõûakò< ÆJmšsLʇ:+öÔŠf€l#v]ùï²7p¶0™ëµìVT>*瓺\¸fDÊOÕË'2<·ÿQø#©Ò /6¹`Óv„Õ‘;÷Îu»=;÷~ _²ðÇwKxÍ/ó5Yh{¥¨B¢¸&åÜû)¯ssoüEá…ÙN›÷ÄÝŸ±ù'”XÅ]Ê·÷¢ -î• ºdfÌrÄ}4L¥ëNªeÒ$îTËP-CµLÅýððp*âþu‰éí¸Å}ʰ«¸ÿÖ·nÍC9 /îÛÛ?Ìü4_âþüùóù¬Ê@SÈ´5¹“Áè<&´ÒÖ‚;µ#Že3R²ãh 9§_ÊÇ ›Eq7E:Ž-fˆõõõ†⎸Ϧõ§TÏV«5Ž– ó)îf¤uiÞOOOçv 6iØ¥ŒšªÎTÝ#îˆû|™÷4ïÞ,:÷kÞPMëϣ¸Ã…¸#îˆ;â™÷ýý}ÄqGÜwÈš¸_^^"îˆ;⎸CÖÄ}~ÄqGÜ!Ãâ>·¿:⎸#îeqßÝÝEÜwÄq‡¬‰;­ewÄq‡ Š;íÜwÄqÄqGÜwÄwÄqGÜwÄ@DÜwÄqG܇essóàààèèèõë×ië¡qGÜwÄqJà$sÛë/⎸#îMqO¿Æ!îˆ;⎸gGÜ··8oîîþ(óã7ÊŸu’â.Ïçy³ëEú³Ï¾3倸#îˆ;⎸#îJqÅU=ó¬Üø:/„œ)V¿Îç\44.¾®å’UùU£¼ V—‚uu‚r~AÎÈ:ŸÕjãAõâë¢ðÊd2O5Óx gþºùò3“CUå ò2½Ý®\½ªÖ’Ç"îþ!˜=—[‘;`ŽÅn]í¿,™ü‚ÞáÕê…W æ@TA©”z¹XR{^~аe¢ó/Êå:OùWèÜòù¡ó—“,Ì·¯×i÷q”dq)ˆÕ¥†$7äüàì`öב ì¾ÙµlHqïïlÒ¿²0»­¨°ñãGG…*¹–KöŒS™´­aŽqÏžs¦âKe>¿d4ÅœœÁr5·TÔQXÔáhÏ„¢s¦™0&tîVü& =q÷eÎnWFvWQÞ¹—óþ!HIÊëc4»g·®ÏºêŪÈ/UíykÊ; åZKæ 1«›³Ô|«æ´f…N9=/K©aÅ}¸ÃOƒs}Iêf¹¨þÕÂä…œóUç3»äí[|­Ñ;÷~Î&_£Í•O}/¼c”G¡×zf®j>"?“¶¡5̱÷.î@µ Õ2TËP-“ÁjH‹¸ÿìgw?|øIö¦âþ—ù{™û÷® îwz…œç^!?~ü¨ dWþu./*ÍJAÍÕKRƒä3_)x/»«¶7×וB‰³‹jÄ=Õâ^Ö·„^oýNgÐñÉt$íz“F‡8ð ˆ0Ž ß2c5˜;GÛËùŽ¿ÃÔ hË“˜8¾Ðï²ü"lÒÐå¯÷’Pò]P›¥úµüX—‘$çtûÈ’(åçìBÜ÷T‹»/èvÔ¥5¡Á•|m²÷‰¶V±j”׌Daúûo8c…¯F¯ýAv¼ÊG³VpÛ "óÀÜØ†Ä]Þ!ú›SŽv„ðøD#÷®‡yì°î *ÆÐ‘VýC°ÃyCÅFQð _/ ¶ÕÃ9ãëÏ`T îÓ®–©.õ>2‹©@œØ€ ÉFx"Õ2c?L¿Ø;ß?!uîÔ¹@ÜŸ>}ʉˆû,‰û$yþü9?F é*î=’·,§§§”Ug¨sGÜçQÜÍÀŒŒ>sâ.OEáCY!îˆ;ââòò˜]ç~ͪÈ»ß*A5?´|7­×mË÷üBC7ZÓOã¿6äí#ú¢XŠ6{÷Ú°;«èoU³7óP*h›° ü§8àÁþ’Û˜Ýæi›€¸##îÉÎÝ{}T«m‡wV««R‚ÍK§¦õ”^O5»RmÊôÔÐiìŠî{ª^Ë]¯ùÙªˆ¶RS¢ß·*öÞ´Ê{¯¡öØ^€q2Ïu2oÞ¼yšVÞ½{‡¸S-3±jÈ ¸Ïs“»{÷îÍôþ#î½ðíoÿ³ííf~â‡FÜ£¬¯¯#îˆ;dMÜç¹­t;q—¢y4 Ð+$⎸÷!î¼ ˆ;â>qG½íÁÁÁ<´O˜ØôäÉœ0ˆ{Ôj5Äq€¬‰û8è,î~Ç–ÏT×»z¤1¯caû"Ÿÿ Û¿qû7 Co æÍ·Á°8ªÃdóþHU©ãõ\^Rcåä—‚dvÀÛýoâ;„ºŸaõê`x$·ã_“ÒtÄß}­noq?::ºuë–9¸ÅÅEÎÄ=uânÆô;Ñ ½Ô,×/êwÿº¿I¼1è~é&/IÕ/‚›q/½‹DCwËnÄÝKVö3ŽL}‡ÐÌØ=·»QKîÛðkåíÖê×¹¿yóføî"æá]s„¨ ̵¸ã<§Z&åÕ2ˆ;@öÅ}kkk £ã›o6wÄ÷þ )䂸 îˆ;⎸ îˆ;⎸⎸#îˆ;âˆûXxóæ ⎸#îY÷ããcĽ/>}zFëÌ©O]µq‡y÷yf<âî¾¢õÀ}*2õB÷-óÞS0šVN>æMÚ„ ÍÀž±±ÜwÀÝ¢yÃV8ïa%Nöí°¼ßLÓ¼ÊÛ¹@ÌPsÞKj½®…¸â>­V q¡¸‡;WÐÝ”Ÿåý6•Žû’ï\¡zô£àu£P\r?¯óôú6ð3Ô‚«7©ÙëäÀw­È A‡î+»Õ¥FÙïÁOfÞËU“w±`¯+þË·á •Ÿy{UvKIuaÞàíq­ðêˆ; îýsxxˆ¸»Z&Ù8·›’{ß“Ríarèy7̆âÇX-. °Î÷ÑðüùsÄ}ÜâΔÕ:÷OŸ>]@†xòäIvĦýòäÉLSŸÎÎÎR(îΣˆ‹|¾ì-ôg,ÅØ’8Vïœ>FC×™ÙrCNCh_|+rI{èxµ‡pö9ùûö_®–¨ö²Ÿˆû\‹;ÌÓrîrÞÑÁ†Qy%úÅjX"rUÆ|¹á?uhÄW·_yòÔ(×_ËlzÝ'¶#pr¾Z”ÿªç4FíG½]9©¬ŠÅˆžê UÞfb¾µ[tg¼C0é#›6ÛáÈÙOÞçø^…ÅÝ–aâîÙÄr¾ZTë^8;€¸#îo!t<ýÕ2R{7æý0œ9ŸÁafJÜ×××wêÜ©s§Î²&î»»»ˆû˜ÅÝkè 3Ò±ŠikhrêܘĴ}¬êZŽ;ãUE–çU{Ígù|/­ÚWMx;êH×É»J5vì}­Œˆ»¹ýEUëR.»•$ºõªªj(ªo£«¨…rÕ™ÉÇ*M CUY~‘W&^ŎʳI[•™6ä­Ú–šÏëª [1"Ó{;æl´áÌØmõŠ^šÄý7ÛÓCÞ˜ÃñÖjcäCGƯ¹ÒÕDêðC5WrÞd+“©%Õ¢›³Ù¨[ £Ï ¯‚š™ @ÔL5Ûâ~yy‰¸WÜ}A÷Føs³û?y’cÕ6<ÒR>Ò°Òn/ãI7*_róWôöDý]-çu«öpbo¸¨`”Áöý&+ÓrŸí¶TûôðØUÞëTUïк¯ÕÃ(ƒ‰ÓÏþó£ŽL掘s¯ ­DJ§¤†æ½ªv!œ™hBU})¼k€©«Ñ¯/DÅ]LæÕéçó~yµ˜øìQ×Mº¶?^Wîí˜/yz£þnèC0zêíuxÇä·q]62UØþ±Æ¥3áHãÏQÍÊöŽ{Ǩëî«~QÍ‹#æÂ × Õé›|„¹ê¨M7üýL¨åϤ¸Ï3S¬–éOѪK‰:Ê©ÇVíþžÄoÊåÕÖŸsŸ TËP-“^q???GÜ©sÏ^ûtÄÝ­ñ× ´«!I¬±qjEжéH¤ "ÒX%¨µÈçÛÖ«x¦ÞÙ·§gu½:%ÛvP.šú ½õ¶µF^ÉD $¨€ŠÕ¨äuáxU7þB½UëâM-–s÷StªÎ²^-C;À(Å=VÓ©†¤MMãU˜¨šhDI´Ö¢S½ÊE´j"w+àzN×/u>Õh­Ë [Ä4¡LÚˆ­Ÿ‰×¨è%y§^Þ¿2ˆ¢}¡k±¼í–óEûˆ`.ªeh-@µ ÐÎqh/î~ý‰2ªá*šÄê‹víC¬ µi”«eÕdÅ8PaµÚðÛäÄqޤ‚(ÞV'Ô¢&ZÏ“P7¢–—u-ŠÙaSý¢4ö8Z_”Ðd>¡¶G­â=§í¡ÝºÛV'¹ÄwÄ ƒs÷ûp¾5Jq›µ8ÕmÛ‡ØÚ ·}ˆ¬rÈ»n|X,–ƒŠ qTEÄÝ­)²5õ MPœº]1Ò¨Ú®:M}’šÜ$¿”Ôð^Óm׆§hß¿u÷ÐÙºÛVÇ/™¬×¹#îTË@Å}n{…´G P02q·ïÙZŽFìU¦øËJn}‚­dhSãá¼*•7Õ2~­‹i âWã ñúR»Ú·“l7}¿±…¸O’Z­6Ÿ§ååå¥TöwïÞ¡P0Bçnß?²õ*Ñê‘øËJ¡ú¿’!¡¦ÂV<Û)jI¨¥‹_3ÌëKíÞô±Ûñ«Mzzck¶ô=Sâ>Ï#1½|ùyªe€7TÎÏÏߟ\3¥abÈ!Ä÷ާ.î/rBþ}µ¡þ.ç*Rêo›ËÛM9/6êïk•9ëo—s½‰Â«Î»¡¯ ámHo¢û´WÚq¡×µw€ì’qóæÍÔÅÝôºÔßeQ2*©î•\åõRúók2e­"WÙÙ.˜…JWÖ6d²æ+­Å¯ÔгE¥ÅµŠ… qDÜ¥vû™«»?Î$¯Iê«ÞÖ’ù¯í!îˆûø¬)䨫eöJžR÷6 _”û¼œô–mÂýAs µpîˆûœ‹;‸O^ܳ/1⎸DÙßßÿ"S­e{ Š¸\Ó’¦i÷ÁšB"îqÿ§¿ù"õüÝßý]gusÀoþæoòâЫ¸û{ÿòó“Rʧ>t÷_œŸŸ\_g{úâɺ@Ü÷›¹ÂçµÂC={¯ôùÞJDgo*¹bÒ¨Ù¯>?Ù”ÿÞÜÞ¼›S dš‡Ûwln77VôB•&X¥V¸3~tÅÏÄÏ9ÈqŸKqŸÛŽÃwŸ¸K5ĽV¸÷¯îÖÔ‡2Ížâ;FÊïoø½½©® VÜe†'›r-“³œ‘×» ›‰›³—fRâî]e 5¯ÿªùfEJÌI½$ÿŠR=´ŠüªYÙ»¾Þ%“̬µQ—Yl‚šIp]ßn^×*›qïÂÜvù‹¸Õ2#wGÖÍ_O ƒ4u)þ¹JÓwùív¡ ¾’«ÔÕÝF°ºúV­²aªKGɦAÜ»@SHÄjÄ=#¿~ýú—¿üåþþþÖÖ"Ë{6‹{]×™([­ªJ‚:“’ù*R‹¢?ú˵%ß+‰]ñ’3^»YÙnJŸ.ÌŒqîrF­n«eü[S}ëÔÃĪuë¥[·ãÕóNl…ϵªÌAÜçˆÇ3 î»’`U RRÚª3iú_µ(ªÖD¥”353Ø™®dWU1OÜ7 z¡©«ñ«e\M7õ3^•½©£×ÃDz)M]¿ÎDUãÔ½ê ]á#ÿ–æQÜ×××çöÌDÙq§Z&³â¾»»;ÀZtFÇa€¸#î©w)Óˆ;∻a:ùå/ɪ}ˆ»ßýzóEÍ yÑ\Û ÆÖУ,ÕåW;ÛwŽ95¨…L©F2òÇÖPqìy‰ý^Ñõ8þŠkÂôön÷P‰×ô˜"Wð3©¿²ê¹-?ók·³x›ƒ™yå¬bÆÙÑC‚xóæXj™ÞèC²í½Ý Ù¡sk®m«”öèÌhS‘BóÒw[«Ý@ˆ;âô-3Fq—’¤_‡Ój•+™+Œ˜Ëõ–5­ƒ/t›U£Œk9Œ™·ç¯«Kµ¹Ò+G …n(ûJ=»f¨#›œyå–'6Jò !Sš}ðTÕÏ\e+„ÑS›ƒÃO_'dÎ*uO‹»¹6LjÃÿ(ìOV»íÑåPåš?lH·µpîˆ; îÓw&ªe÷yá‹Ç_N}Ê®¸7+ÍëëB¡Òî{ûU‡4Èûöû£YŸþr÷—8 ÄqŸ<ß¼=˜®§ùë_œÏ¸×Kî!äǺœ+¨™ëB¥)ÓˆR=XQ§¯—ÔÈåê›póo¨â>¬¸›:I÷ï^É><ÓµŽM]å¨kõ8šq/CgZÜqÄ=…âèØHñËÞ“0ÝøÂi^aSÊ…Â6s0ùØ4ˆ; S-ƒ¸#îˆ;⎸#îó-î4…DÜw@ÜqÄw@Üa`ÌȱFÜçyY@Üã/ÿò÷>|øÉ§ýý#îÐæð¡(qï—ÝÝ]\|=ÅéÓ§gˆ;tÒ÷?R€¸FÜIóùæ¯Yxñu£¬"Oê^Þ(/Èy¹°œzæ™ü›/?CÜÓλwïÞ¦ŒŸþô§oÓЉ¸gGÜõdÄ]OÏ´X¯ZÉ.ŠùWЏL,ЫեrCÏè…òoµ(÷´óÝÕ¤øà©O÷Þ>E1wªe¨–™Mq¯ž”næ íÎ~Õ&ÍæÍíM9#6¾2YµÕJýíÝœó÷7Äç7j¾5‰o‹;}ë²ÞÖm!¼¬ô"îˆ;⎸ϥ¸ï­¸K„¿º[+ÝT3Je¥à~a4×ôÛ2Y­pÿ¤ôpûŽZÎ-vùJ¦LÌÙ½–¸ê¯çõþØBÜÞXñ.þVäB™ÆÛVDÜ÷V¼}3;i÷ÐdµšAÜw )$Õ2ÑIøªÚÓ´·\3Æ9y{Õùö玸⎸Sçˆ; î0iwÄw@ÜqÄqÄw@Üq@Ü)Äw@ÜGËË—/`Æá@Ü£¼}û–x¦AÜwÄqÄwÄqÄqGÜaX?~ÜÒð# îˆ{vx÷îð¡4wÄ=C¡©988 (wÄ=;ܸqÛ€¸#îY£V«-..Rˆ;âž5Ž)ĽoqÿÝÒ矟”æ|’…X8ß]ý…óÃ÷_£€¸#îˆ;‸#îˆ;‸OBÜk…‡'¥Û¹B»Sý¦ÿÕÍ6iîæTë=›Uh&4}¥nÊÄ·÷úV³õÛBÜô[‚ß­¥[Ük³ŸÒÈ¢ëðíý ¸ îÈ»\©¼JŠ6¾’KnçÄÝí;F˜næVü™Âç{+ŽZm*öuü¶X1+š‚ÜäŠjnE]r£Ñk^š»¹;f­ûznno> mwÅnH®xÛß´LhßÞŠÝC»{¿‰6¤Éˆ»W2úJ”­_,ê"§Åݸ9 YJrþsE³®)@sµ¸¦WbÎ âˆ;âÖ +ÜJ5Œ*i)‘îø¦VX­>ž•óhî­ø&TÉô}£¼2‡Hnþ†Œ®Ùf-»¹ÏýFÍ]u¾)îXŸkÄÝŠ¾I©öÊß=o•ØÌ»è;ö¨ƒë“.@9£ŽÂþîÌ/@{ç俯нaê|€¸â>ßâ^+H)WjUxoE‹»dTÊ“1ìÖ¹Ÿléôl鞟ƒÍíä+U²·òÐÓ5ajW̕যwVËôµD­âÔmZ¯¯4¾¸Ë|îx™˜4þLŠœ»>L£à®¸›å¶äDÄÝ¿ nÞ­y¨N‘9Ì›9¯ÄB÷1ˆ; îˆû§ä:÷ÑOwµÀÝlÿÀ€ªˆ; îˆ;­ewÄwÄqGÜwÄqGÜ÷1Š;⎸ž- Qˆ{¦Ä‘†qÏš¸·Z-#îr†@Ä=#â¾¾¾nÄ]Έ€¸gDÜ=ztzzzyy)gD@Ü3"îˆ;‸##îˆ;‸#îˆ;‸#îˆ;⎸ îˆ;⎸Ì„¸ •ëf¥ÙîkûU‡4ˆ;ÀhOÉQÑî´Ôé ©wR¥úuAÌ’’(ɹ¤Rj‰^X/y[/Èo¯ër‘^±éÏø9 îIª*ÏsBy§Œ™ñO:¹$|J6+õÐy'ä v]¯;ùøßªtÍJÁžªæüm:^-7Û²g±ž©óeRÜuÐøKêêCI\ýÚ˜z)´:½Ž´’‰¼Pˆ;@ËìPkwïÌ ŸwÚW‰RÅÏÇ~ëÞd;ç¯/îÞE X®·eÏbkÑ [â~]ZÐÍèqÞ@Bù‚’ ¥ºwÂ*¸ ,;Úœ·0”â îî •(îò,²vÛœYîy§O2•ÀËÇù¶ çt>ÁùÛ´g®gyÅ[®Oy¹-{#î÷´¸Cæ{ŠòÄq@ÜwÄqH¸K!¾ººz÷îÝÑÑQ­V“3ò£Qgù·ÕjÉ¿§§§»»»çççö+óW.‘Ëå·2Moy¶îÞÖ4ãÈ–Ðì|ÍvËJþ¸æcä'0?z/?Á¨²•¹õ˜­û£O [™&Ùh&–­LŒ¸‹,zœ»ËÓ§OñD^¾|I!§á̈»¼º"î.ÇÇÇœZ‰H{E!Àd˜õhœ{Y__çÔJdkk‹B€ÉðüùsÄ}XÎÎÎw—7oÞpj%²»»K!ÀdØÜÜD܇eL.fWÜ‘°vR0÷a¡Z&TÛÁUà4œ%q³+î³Þk|\^^R0®®®wœ;–ç8wÄç)Æmq;»­oqîXœ;@ˆ? œ{œûŸþÙËí÷Gi˜¶þ×ÿ:¾Ì¾æŸŸO½dþr÷—S߇ï}vùË<ˆ{¦œ»÷÷'×™Ÿ†÷y(Ÿ®â>Ü»wO*ûLWí¦BÜÇÔqGÜwŒ³³³™¶í×¼¡Ú³¸7ÕÚF]Î/ç*f¡q§5½ðEN%o“U}ÇÎ×*;=¨‰ÙКËþ­â‹ÚÈĽ¥TÜû)–Û©Ô&Öö’¿]s·ÕKaziê"Wð˲0¼¸ÓãM&¹qãâ>,cê'k„âî Vý•š/á6 uÓJ!ÿßñUfGK°\²¼Ý”²²¦S*ÝÏU¼µtÊå /Ã÷{6g9S2 ³¡5ÿR±³­ÄèÕ†—ÞîŒ]W$ik¢¸ommÉUzุV,A™8…#¿’éõºMyéŠä¶S«›c÷z%¦tÇnKfâò{gáZN¼Ò u…PªÛK…ÙoOr™2´î^i§£¸ïïïÏzµl 븡·nÝš1qÓË#wsÎ{º£eW*‚Ò-©Jh|å2 ƒuõ¼ÒbàE®à ºñŒfÞW4“•ÉY ™U–eQ0*oÅÝH•Lf´O®b×ue+qúÙÏ~æ†ËË—/ŸöÆãLJ*+î¶LœÂ13GÜýãò6lÎx(™-L[Èá.xµÊ‹Z3RJªlýuUñÚuuï:êL‹ßý¾¼"ºeøz£C§I³þ®ÿdè«T{w£­æ<_֞ѓ%æÛºª*‘º uG«FÝxÒWªF¥w-jqq_VU~ÎÎv}/\rÄ]åùêÄYÅŸéѹaºw¯×ä¸sï¯X¬¸;eâNÝ»Bèuíá˜M˜}ý¨ûšî‹»[˜N!{;Ü.Xç®öçUè(ïJî*ÞLGç.o7qîý>¥DÜçKÜÇĸ¨.w“ѱNJÂÚ‡H±˜Ñj­sW±L¶lÕu¢Ççñ:w©Jczh„¸Î}:âNkZË⎸gй#îˆ; îˆ;ÎqGÜwÄ}ÎÄ=%­eZ­ÖQVø“?ù“v_ 3bm_Ê*t;<q—çïû£#&WÇfOÜSÒÎ}*GcÚɉ5á ­ŒOÜO®¯™f[ÜÇô‚_úÅ}L éäÅRf;¦K¦‹yEûãÇÈ îˆ{)é[f´Z-#îÃÔ“$bÚ_Ë¿8WûzÇ÷‰‰{®Pq>ÖkÑ%ÎÔ¬ÔÚç£_‹‰_m¸vÌd~Å}>ûsßÜÜ4â>òAÖ'Ö[iºE…,‹{³²!£³TW]¨Xq¯U F¯½­Ë2™™Ù.ÔŠa—¨”MõW¨®Cš~¶ª‘š9 ü”¹RɻԽ™\Au%2¿â>&R.î·nÝúøñãááa_ýEtEž$[[[¿úÕ¯äß±¶@;ÿòåK¹¡×¯_ïïï£\Bq·bí:w¥ÅÒw×ý™JÅÓßpz)ýR£ƒ<õü^IØd&CÝI »‰ævÓó=òJÐövçžaq·§Î؆q•¸ç””×¥{3uù­ú(“í©oUzùQú}©Ôʪ_×a—ßnø:Vü¸¸«L®›òú1ïâ>ŸÎqÄ}|â>Ô4¶ tœ;⎸âNk™Ù÷‘7AÜw@Üwœ;⎸⎸óósÄqÄ:ƒ¸#îˆ; îˆ{  ZqÄòÉ ¸ó@qÄòÁ¹#îˆ; îˆû,ˆû˜@Üw@Üwœ{¦¸qãÆÓQ€¸⎸ãÜç±w@Üwœ;âˆ;â>Oâ>Ÿƒu #î÷¹fqÄqϲ¸ÏíÙˆ; îíľe²Ð·ÌÕÕ⎸⎸Ó+$⎸⎸§^ܧ¨M€¸C–Ľ—aíÚ¦é4“7ÞÞvsÒ#7áÜwÄ÷¶¥zß^×ÝqMS­GGÊöSuGÊvSÕ3%•^¯âÍ_5ÛRU[ǹ#îˆ; îÉ»(Õ=UµƒV[¥ñf*•½JÁŠ» »V)„¼¹ú½’ À]/¹ÃgÛšœ{¼¥À¹KÜÿ¿ÿ¿]1ôÞæ q‡Ùw奺Tdù³R”åÚDGÓx3Z—…VaùqC«öFAxÒ¯Wò® òÛºcð¯ë¢ rØð3 oT̯¸§¤µÌŸþÙË÷'×™Ÿz/ÄfNÜ;L®:÷:³2}.Ä=%íÜwÄ2,î´–™)yCqGÜqGÜGIJú–é î/rBþ}µ¡þ.ç*¤SÛ\Þn¾?©¿¨9_Õ*;rН’¸0!ÏúÚžšßÙ.ŒPÜ?~ÜAw˜®¸¿?:bâêxÅ]lÔõLSêõ²ß”R«4WK³}%åRyÕ½’«Ý¯N®×DÁ÷Xz“ƒ\kY”ÌB3óJ¯+DA‹{AøW+î:Ysm»"WQ×›³ZKt÷?ÿó?·ÏW?ûì3ÄR(£wß­+ÍÕªz-½yHÇ}nß[®ÍUÊKoÅÝ\?¼k†¾Š8â®òŒ:÷½’½6¨'ç¾ÄýöíÛwšÀ¦V.÷¹÷ô;w©¶B·~ÒR[2êi?X®[W­ ±£¬º° +g”.û¶=’^^0¤+—YIv²mºU:fCò ±®–QùHÑÏyÚœç¼ZqGÜwœ{ïâ›öJ½(éø&ïâÑC•ý¼=PEÜwÄç>„¸ÓZqGÜwĽ3­V qGÜwÄpîc9Éé~qGܧ%îzàÖ­[3&îçççóy’iR»{ˆ;â>1q€••~eÄ=¥ÜÒ îˆ;â>ˆx qxxÈMµL*K_ƒ¸#îˆ{¿|üø1å§â®HÉÕ ³¿¿o¢SÎ îˆ;âÞï]/âŽsOµmOs€"îˆ{jÅÝž;oÞ¼á·N¯¸s’#îüîˆ{t/_¾¼[·ƒˆ;ÎqGÜ÷)8÷ë±5Ä@Üqîˆ;⎸OSÜs+…BÅùToF—tHBâ×îLQÙö’I³Rˆ$ƹ⎸gPÜÇÑÁŒ­*…Tþ[¨4•Ô6+%½P t¡bÅ·©Û‘_)ýmVšJÍÕLI¿j–¨”Mo2a$[7“B©äVõ’¿Pþjr‘_Ï’¸§d°@Ü÷9wí°•.[©uÅÚuîúp-ÿعn]‹½›^É}Ý‘c=/E;’ÌlQμë‡ZjžÛkL3ðï³#î)fwÄ}†Ä}kkkÄû§•WÊ©P)ÁĽ d⺒c;Sf\%««oÕŒ\(¹deÕ¯ëÆ°ËoM27[u…¨—"â®2¹nªË†ZR¯{ûØëÇÙ€¸#î3)îi ê{í‘ÝUè[„BϹ¦â̼ººâ$GÜùÝ÷¾˜ÀÕ™†ª€¸#î3)î׺ ÜËËKùwww÷Í›7ÏŸ?—bbúÅ•[­–ü+—ÈåòJpxxhšgggò«Nf¹}Û•^ÒL·ý M!qGÜgU܇'RqŸÐZÆ—Qïk¨)Kɯ¥IIûœ; îˆûüŠ{¤ÉMBkç¶IŒ}Ú©¿rÅ=mígp#îó+[Ëx¢4‰1:«Z¼È$õô¶ŸÁ¹⎸ϯ¸÷’MŸ b&Û~†Ö2€¸#î8÷ B;w@Ü÷ù÷ “Š3óì쌓qçwGÜqîYwú–AÜùÝ÷©á~ƒy  ˆ;âŽsGÜ3§M€¸#îó,î»»»ˆ;ÎqGÜ÷¬‰{†‡`Ź⎸ϯ¸¯¯¯#î8wÄqGܳ&îcj‡¸Où$?ÍXÅýôôt‡óÍ7ߤ§ §l?ÿùÏ'¼Å®mš»Š»”Ú ïó£GR-8÷aÅýëÒÛ÷'×s>ÉB«¸/~ÿÞ<cgÎÏÏ硺CWqÿòËÏ..¾ÎöôéÓ³9÷155EÜwÄqGܧɴÞPEÜwÄqGÜ3_-Ó\ÞnªÝ¨¿¯Uv:±þv9W‰,‘Ý¢¿¹¶ç%[…v9÷u:éݨËlåüÎvafŽ¿ÂWÉ䱋Òû‰פĽÏhÔE±ìUx-÷ÀÕGù܉{ãACͬ–ÁǼXºPbÉ÷QÐjµ¦/î{%_£ òÄðTØÑq¹Ä(²È¼…µÊ+%Ó%3³,¼ô¯6„™Þ;ë.ëdrÆ“9ý^•wòñ7W¥gôIëÍûù̺BÏ,ç ¿Ìxj¥s“;¯SªË‰]W¯%Ò(î}¾)Cs¼6пˆ¼Í{Þo¡UO¼¨]¤¸&$î}ˆ¬vØØž‡æ4V›Ó‚.Ï7%îF§j ûàŸ´ž¢¹VT&–›3)åŒ{9I©¸÷Yøf¡‘!›À‚_ÂõÛ¯wÄ}Øâš¸÷Y ÁåʉÀ6q8÷½’Í6´nvÅݨv±ˆ»ùªQ^¸¨.áܳC¤Î]šïd–§œ·wÄ{%»\μ:© #»V”uX/ëú•ÅFŜ꯿®>NU'âŽsÄ}¼»=0ÌâŽsÄqGÜ÷10·­ewÄq‡,‹ûܶsGÜwIJ,î¼r‚¸#îˆ;dPܧշ îˆ;⎸¨"îˆ;âw@ÜwÄp#îˆ;àÜqGÜwÄçˆ;⎸##îˆ;⎸ãÜwÄq‡ù÷óós~ ÄqGÜ!kâΪˆ;⎸CÅjÄqGÜ!ƒâÞjµø%wÄqœ; îˆ;â©w@ÜwÄp#îˆ;àÜqGÜwÄçˆ;⎸#î£Á:wÄq‡ Šûéé)¿⎸#⎸#înqúô鑿֭[üˆ;⎸CFÄ]jºÐ¼{÷ŽßqGÜwȈ¸KÏnÄqGÜwÈŽ¸«âÆüˆ;⎸C¦ÄýÑ£GµZqGÜwÈ”¸ÓÎqGÜw˜¸Ë3äââëìMŸ>=kwÈß|³™ÉCŽL½kßHÄý³Ï¾3¥Ú¹ÎÏÏ硺>9CÜwÄqGÜw@ÜwÄqGÜaDâþ,_~¦~ÎâêEãA£CJým9/ä|Q,ô.ùüƒ‹‹ÕbUÍ7Ê SwsÕ¢ð÷ªó>«/ç—z8ºŽ ué…ð¾Òe>ëâ>Ž’Tq(Ó‹¥iØpâÞßÙdŠ%¹èìêUStžBk$'âž q¯.ù'ꂌyn¨3Ö‰<¹ÄH¹È/4üsω°g2æò2Χ(–ôi¹ê-Ô‘'ôL>¿ üˆ´ñ§?+–UàÚí*±Pk‰1‰»fÏ…Úª>»u½ÿr'½;i ĈXðO§%sâÉ=·'›œÑù¯Ví©+„:-äŒ=Û´=|½–Ñ©4‹û8JÒäi"ÄF Ðyz™›Íù_u 0ûë¨þ¾k‰Ñ‹{ŸgSÞ¼H¼ /~´šõEN&©:šn$1´†9vÄ=[âî{‚©àÐ ­Ž[ÛÕ[ŽöL3AcÖ²Áäœ{Þù2Õ%»95ãŸcwÿ´þê“GJ­Zèl½á ðÏÀÀgU—ªþí‹<^ou's#Í‘3МÌ!çÞîðgDÜÇQ’&~ÌÎF ) ¿HUÈ&£c€¹¿ŽÍ¼s€ %îMæ¯ð]‘÷ë—Ír`ÃÝýïZû+îO;²µµ…æÎ@{Yûó«u21Z]²ËµwXþ)j´Iž"¿dÅÝœ·2¶ÌZ‘›MóQ®Òß9šÍ}Ëf/ã¬sf·’Ï/¹{,WsKòøŠ¶¡ºäœŠª̰ç1lÉÓ)ÿ@‹vREÇOÙÓ^ø'Û‡ŸŽ:÷Ñ—¤)H¯ Â@]¤KR¸mÈÁÙ1Àü;?ql­‘×¹÷u6¹â®±è£ŒœF î¦LÜýïZÃ{ïÎfõjïA0|Õ^¨zqZTeÜ÷,©£YqèÃOéÕq–d×[™vyv~0îª;›†?vÄÖ2´–¡µ ­e溵 îˆ;⎸#î06qÿðá'Ù›ö÷ÜAÜ3yÈ‘iÂâ~çηæ¡T»Šû<â>â0£}Ë? îSæ¥q‡‘s||ŒFÜaz¥ŸîQJ÷ÙeqqqGÜa:\^^qOmLjû¬ûz?FÜa <~üØœrq‡rxx(|( Ä&­mßÜÜDÜa„Zq7ŠY- £¼Ö&KÑ”š«¿]Uâ+5׊»º¬ªdR¦mú˜¸Ë4Ò˜‡ªeªKZmŒ:ËZqúºbÄÚÛn¸ È¿™XrÅÝn¬b÷§/çÞÄ}âþöíÛL>óùôéY»Cþæ›ÍyxêÕã ÉvÎ7oÞK›A—aíhV ¥n]ͧ¸_t® jzÖcµø°›hS¡¸#îˆûlˆûÙÙ™üûîÝ;ù÷øø8"îº1¯C1óªª(UL·b׺§™®Î¹Õ›¸ÏUkÄqGܧïܯ‡ÙS݇éþ ýÅ*Õ§XÓïVÌZûBw‹¸#îˆû4Åý™÷¨¤¸ÚùŽ,x°ck;Þoš@ùjßw”z[ö¾}ª31qïï0ªzŸÕc´¤Äñ…¦‰›i¬æTz¦BÜ›×u¥Û~‡bRæ …’íVLþ1ž½„uGÜ÷T‹»~,£åL=v—rc¿xa«Rdl3¬p{€Ð#£†VC/qqÕ4ˆ]Œê|V«Z‹Â[hC™Š?9c¯4ž¸ëÄÁ£ž²·E³–mÕ;qïz˜æŠ%uÙ6t«†[Aõƒ2›Æ‚Ðå“Ï/ØçTA[4µŠ:.÷!˜Ú–ßbâžXÇöèÝ»$§–K«Õzòä‹ÌOõW%Ä}vÄÝwëJŒ´z*­1 §<ó§£ø^KÞpc¯ˆK͇^Ó°f|ÁmÈU,.]øúeÚ§:ù˜sW× ¯­˜ÒÇÀZÜ»f¨M›s2iª‘#M÷æRrîÕ%[øjÆÙÖTÅ`d î­s/ëæ²FD¼÷ü¶Vv¹v¦«Úlºïà%½¦á%V•*¦jÅ “ú>¿` ©Ð ¼Wé"5Bö5 £ã¾¸´Ûµ{2†:÷n‡éµ2^*úGaÒè«*‰6Qüø+‚²ájS€Þ¯Ðæw@Üáz°ª}ùDu è_€™ü u®×Õñ¦½”6¦X瀸gXÜi-3¿­ewÄqŸq§ó@ÜgOÜ?|øIö¦ýýw÷Lrd­¸ !Ì»NЙ£9À¼û†¸§]Ü'IèHH =Š;ýÏt…vîˆûœŠûâââþþ>?ÆÌ‰û›7owÄqGÜqYwÛ¹ØË—/).ÄqGÜC"î³(î­VëòòÒT©qã5˜¸ÜEb‡ 9$­J6DOˆ;âÞ…7n$t- ³àܯi-3œ¸ÜE¨ÝQ‡Û½»y©Ûz¨ë Ý_ˆ÷ ÷Ð=y îˆ{vww¯®®äÌóçÏù=÷¹÷¡ú±ðôTwRdÇhW‰ô2|O‰âþt8¤-Ùw@ÜçVÜîÇÂíÆC—ŠUÕùGÆéÃ5XÅï/¤èXõazò‡s‡¬‰ûÑÑ¿â>—â>½î:†îÉqGÜ¡ OÓJ×áŒ÷Ñ‹û|·–œ{ÖÎüÙÝyÄqGÜ÷lªâÎYÔËO¼½ýÃÌOˆ;âeø.)wĨ–AÜwÄ}ü´Z-Äqœ{öÅýíÛ·³ÒÑ+gâ}ˆ;%8wÄ玸âŽsGÜqï›ËËËqd{ãÆoœ-ˆ{œžžŽ#ÛÍÍûóðÎ÷d¦~ÂÙ€¸#îˆ;̽¸›Á:wÄ2%îcz ÚQÜŸ™q Üa ’'ým¿c]6bCáÄG°4Ü”ó ÕÎÂ:Ø(—Õ¥†3JçccFÄ]^ŒŸ>}úúõkÎÄ} tw42©­R=‹U-‚Î(Ãr‰7Le~¡ÑÃX—¡1-õ(9ÂŒwãIó’Ù¢œÑãRêaÕòj”Ë|yµê$óF­¬š¡vŒ¸ÇG¹ÔC²©Á-evÏ͵'2>§—¾ÛZ‡O³âþòåKž¯ î)vî¾­V²«‡VãŠé…‘¡&ÃãÊ·ëÒñãaç^]ªúÃÑ×)õE"ÿ X”›~Vu’åíhgޏ'Œr)¹¿ÃjÆŽœéLRµÍ`i½¬Õ‹¸·Z­õõõQ‰û< …,¯…H àÜ'\-£¬«޲˜w†ô‡šô‡©\ÕÃKvëÒÓ²ª–YUßÛ(ó\q×â«ÅÝOf3¿è6Ê¥Ù¨·çÁ(—«Uw|N{Éé²VÕ2ggg÷îݲZqÀ¹EÜÇ‘`œÉÑN=ŽZi/?±jýg­5…ªˆ;@öÅÖ2sØZqȾ¸#îˆ;â5qÓ0{tæîw€ì‹û˜ú–™æs|pÄ ûâN¯ˆ;âAqŸswÄ玸#îˆ;ÎqGÜw@Üqîˆ;⎸âˆ;⎸âŽsGÜw€¹÷ùT7Äqȸ¸é UÄqGÜqŸ&TËô»Ê~ôÃ/¿ül¦§»w¿=ë‡ð;¿ó/w@Ü;Ñjµ÷¾XZZ¤/³©O››÷w@Üqîˆ;â0gâ>çŒCÜÝq¦áÂÓjÌٌ3õ Ã°!E;ˆ ^+id¾UTÂÕFd0©®#†ën”{1\]•_ð;¬\è*Äf p3ú`ïk!ãÜÓ$îáb; "˜ÏÛ‘ÿüb; "¨® V‘_Rân2”[Ñ)Ë~†ÞŒÞÏ 2nÇn5ùÛË»E5JxÑÒ6òmp9Qù¬ÚëŠ;¸ÜPûÕІö¸º¬U]j CêÄÝùºœ_ˆÿ­ñF÷ö×A=²kxøo/}løo#‹Ra½E¥†fs '™òËrÆuîú:¡7äÞ+ø#†W¿.7ô ²6™¯ÅvŒÿ-êJ åÄý* £eºnD%0-åU~ë%6ßËG ¥Jf2,?Hw™FZo·ZÆøb™­§ìÞeÆ÷rÑ1Ü&³;vîêV ýímÈìp0¾¡)æ.zY çˆûH`°ŽQ‹{§ºšÑÕÝmò*CÆ=b¸·¡¤c¬´u€ÓÓSÄ}ìâΔÑÖ2KKK C”ËeÄqgBÜ•¸_@†úžq¿ººBÜwÄq‡¬‰;Tû]åç?ýäÉLÓžVÓ(î²ß?/çþÂFTCª®2ÓiõŽéc¨ÇòUo>Ÿ/Ëipñ‹oE.éqý/ö°î>'Òá@âËåµÑö3Sâ>çÌy§˜fŠÎ=o4¤QÖMø«ZSºlÃ*—ü`>Š|ÞK&ç…$-´ºÿ•^X|ÔW”ªŸ^·¼’*Z´zª¶êW¬&6œj»j£ ¿)ªÝ~Þý轡wFî²Ê3¯Èw'OùmÑWÕ¢YhvXxQ·‹BÑ=öè>6Â/«¢.[3“/W„ÜO¹&“hiãÜw@Ü{÷†Òļ‘?W(ý¯„«Œþû»á4zuû•ï=óÎͧq6ýECJ–ë^å¼Q1³Üýh¶[-æåL>"vzŸ­×Í‹àJ“÷]°7cöÊOÙ´)èGŽ(Øùä}ŽïUDܽ2LÜ={%0[‘ëÊL#¥sGÜq@Üaô>FÜwÄq‡¬‰;Ãì!îˆûÅ}thSŽÑU>tÞÉA¡Q¶ÙòׂÈrÛ¹ÆÔ˜›GîòÄýïñ 2%î =qõÖ±ÃÓ“—ÛõX£[—5^_’I=¤çC]À»ËL¿•½ôÞ^ô{j´Av™üž¿ÌQ÷ºV–Ä]+j)(BmWäŒ~,Y­&èŽZh!z3r¢¸ë4b9ô1xTëã=eÍ«'«Eý$S=„´4ÕoêíX°Q»ö9¤}¤é§IÜïQ§ê˜Ú|·A‘>ƪn{é…Û¶ÇÛhÕy|ª Ü+‡bÕ>Sµ¢gŠÐZYw µ ÎÖ2L÷Ѹõ°1—y&´ qªY†ÝÿY7¯p&¦K,ÁH¶>ì[¢¯7›òÅN78wÄyEÜÛˆ»Ó%Ô`£]ÕĆ4Nc•jø ¡ÛÅ}ûßmLÒ¡¹‹m¶h÷ÄíÌÒ~«šúø™¨œÇ¶Ãn½}c¯d"ât-mè¢gòÂkQã·~©šç¡ÆEÁ¶ƒæ@´–AÜ£üþïßûòËϘ¦;ýÎïü‹´Š{1ÒB¦sÕä†4î7¢ý¨D±$5&éÜÜ%²'¡f*Õ‹PSŸx3•á·Þ¾L’ ¤jä6tiØ{ükŒ×›§i\ä>ÑÕ4æá*íܹ}‘VËD[Ètn¸’Ü&,îúÁx¬eˆ+£áÆ$𻨧”vO¢ÎÝoêSt;æõeqÈ­N9©L’ $Ü.(ÒÐE•I>,î&™sé’ëøÛmØë†\-ûâΪ(ð@5ÞÔ'-ígúnTu»Îï·± }Ë îwZËdFÜé…‚Š»i¼aúè¡ —þzSÉëj„r>ß‹q«•Xžž}ú‘‚‘Š{£§Þ Yy¯Uú´ù½Þ¸ ÷ÔŠûééé|ž–oÞ¼1•xRå)•¸ÛA”‚§|±ñ˜â#.¹ÍçïèˆÅÝD)ÒF%Öj%4âR´™‡ë6#Yç.—„*ôÛ´`éo ¦6 †X ;÷¾†BÜ'ÇÕÕÕœ‹; #÷`%ÛÜ%Öj%>â’+µ¶íG¼‰ÕÙ¢ÛõU5ÔZÆo]3ÔL‰µÍTœœ½ ;5Kæªáàà€ wCûP­Yúmû‘’¾h²QÿNSÈì0Ï7.0qÄ}Æœûâ÷ï½?¹fšúôä§/YÄ÷‘¸##î8w&Ä=ƒœA¶ÈޏÜåïH޹¼Ý”3b£þ¾VÙéRû"'äü« õw9Wé³ú¶VY–ÙÊMäJwCgU_ÛSó;Û…w^x;Д+ö¾âaf{°ŽQŠûž'»/r©ÅR%•|k7Ú-—¬‰‚VÒÂŽ¹h=}Q»^«Ññ-ú^âºYøj»$7ñB‹»QðWµŠ\×\$dr^Uð•Ú—i¹®¾–,« ý­èý±;oRš+M÷µj¡vq@ÜÇ_9}q÷Ýúš(eT*©ú:î;tGñ•F+iÖ’½ÝT ý‹„µó¾â×¥²q*}ýÅžÊÇh±#îsiq»ºB˜ÌõVìþ¸“\Å,ï¾â€¸O†{Îm»ô¹žêIy•ó¶~f¯d—Ë™W'um®›*µVÌ圗À(©·ÜK,¯bÇ\¶›FÜ×T‚ÒÚ¶¿•hµŒòà;ŽL{+vÖDÉÝù“Ð%¡ÝZTË î"µTûSC©žIžºë½BÙÆkö_l×X q@ÜÓ­eh-8w&ÄqŸ¾óÛ‹Û>ýè×9—÷‘9÷lÀHL€sGÜpîˆ;d¥¥¥!ÊårvÄ}ÎÕ q‡!Åζè8,¥â>çƒÌ!C6Å}à¾ewÄqO¯¸Ü+$âàŠûßÿýß‹ÔóOó7:«Û¿~øPÌ÷wGîˆ;@OâþéÓ§ÏOJ)Ÿ¿Xî,îßÿ쳓ëëÌORĉ q@Üwœ;∻™j…‡'¥›¦`ã+¹ÄÌÞ­E÷f®ÐAŽïæîØÜü…_=LH&nï!îˆ; î0q×Â}C(q×ï&Z_§y¸}GÎÖ3›òïÍíM%ýú¯Ê­V¸­¯*ÌvoŬr3·â]6üLlÎ6 âŽsGÜFïÜ@GÄÝv5£åXšú›ÆæëƤ߷¹é •‘×3ÂÏÙäÊÄÏY8[Ÿ„¸7+µÈßzIþÍ*ò[¡þ6s•æÉu}»™°ºIÖËBĽ'®®®w€ÑŠ»²êŽs¿)Vââ~[¨úéÁeõÕÞŠÔe[c21–?QÜoªÕ7o¸ÛL‚œý4ws9i+îõR\»sB.¬ï™dz­½’3æ ¨ÕU‚ QÐù¼4ˆ{gNOOw€Ñ;÷9| wî÷í, Ä];z)å9Wýý”r¡Ðêï%Ð œ;⎸âž&qWî[‘(îÚò«¯KuWÜÕ*¥ÒFÝ»3سi÷Î\^^"îˆ;Ty Š¸ îˆ{êÅ}ÎAÜaTâþÿð¹Ç?Nùôøi¡?qoV¯Ÿ MMU¯ÒÛê£o!«¦Ç¹g™[·n}üøQþ£G)^ܳADÜ7ü‡™B¸MYöÌW‘Æ-ú£]n4ZjzN/1âžS-^šzaÁo-S0«ÛÖ2ÞŒžß.‚­ø—ÐB½®®‚÷šÜäìX¿ŽÙ œû¼ðöí[ÓlëÞ½{” î‰âjžnÊ¢6Ò¸¥^ò,êö™§nÛîÉ«Q|¹Ä›1T]Mwfdj­°ïŽ.´^…P׌BÅl×Ì›Gµvpîó‚÷9ïÑ÷â¾WÒMË¥njãì6eQâmÜRW)Uc˜ºiÕnÆÔ*! ¾¸{ ;ˆ»j6ãºõpó˜èB?¥i_/3Ñ›³›0âÞÜ›Ãj™yîò÷Æ2P(@Ü;²jÄqÄqO¯¸ ⎸CöÄýÓ§O怹 {tν¹¼Ý”3b£þ¾VÙé GúÛ9!ç_m¨¿Ë¹Jñò¾­U^äJý _ûœÍÞÖ_ÔÚîaÿª¯í©ùíBk o÷šrÅÞ×BÜw8÷$qßó”÷E® ÅQª•’o­’Faå’5QЊVØ1×­kR^—…0§RêU¤è{‰7êÞê¢d¾Ò+Ö_éÍ™…¯NLÎJ©¥DÚLä·v^gÒ|±çen÷ÖH¹—ƒ7SrV©¿Ò3Ër¡?oŽeYïžÜssyXÎ|¥öeZç& A§ôN¯k7mRš+\÷µjªE⎸âÞëÕõõõ?>}úT~”[­–ü+—Èå›››v¡Ipzz*ÿÞü­o%º]+¸J­9yðÀSkÅTÒy-­´ZèË®5ÝFdÍ GF@¥¤b§Ó+}ôwÀdbôÚŠ»ZâjºëÍÃ9˜‹“Úm-èêÚ#ÅÝ\jÑcqĽb.i®sWW&sPúèìºî$W1Ë»¯…¸#O¥Îý…þÑÈК~Ø «].g^I¥ÖZ©®keôEó–{‰¥F‹5[!£5Z²c’ùéª.ëWÖìÅ`MO;¾Ž›mÙ® aµRøW OÜõ®é×òŒw¶ân%Rác>Ê}ÛqdÚÌØ£³ë®‰’[h;'¡KB»µ¨–AÜqOËÕΪ¤Š%yÛYüÉ×û¿Ø®°⎸âNkZËâ>FªÕ¿ùâñ—Óþ_oþÄqGÜq%ÿÃÿ¸9õÈÿÝï–Yq/*×ÍJ³Ý×ö«i†à;¿½¸ýþˆiêÓþîqwÄ=£â®f®¯Kõë‚(˜%%Q’3rI¥ Ô½°^ò¶Xß^×å"½bÓŸñs˜'‰ wÄ=½â.¤*Û%uõ¡¤U¾®”[Ë}½Ú°N¯þÈÄZñC9 îˆ{Ïâî5Ûuþ § ²}cѼ¹ÒÓ ƒ½½E˜uq×â_ëNñƒ%BÈÏʹTgöÞ@wlï×Ól?æÞÂPˆ;âÞ³¸»ï $‰{´œü*á…ÁàÝ@“`Çk4켜~0Ëâˆ; î)tî÷m×ëkwðÂ`ü=Gÿ=Ä÷á÷TæÅ¹âˆ{úÅݼThúžŠŠ»y¥1òn úÖ{Ѿœ›qÄw¨"îˆ;⎸#îˆ; îˆ;⎸#g?ýŸ¾yðÅ“éNÿê÷w@ÜqÄq@ÜwÄqÄwÄqÄw@ÜqÄw@ÜqÄ÷AøÙÏ~úáÃO¦;ݽû;ˆ;$pãÆ—/_nnnÚ2÷ÞÅýââëéNˆ;$sxxhz*]_g$#@ÜwÄ=CqoµZ î#÷|þAðWŸ_åÆ×zvA§y&çŠÕäw ‹‹‹ÔÉâ>.q·_›¿fa£±¬¢tÉ,W³ÅUsÈ—Ÿ•õwˆ;ôÍñññÖÖåˆûÄœ»Öng£û¡ULzïc$=âžBZ­Ö[èÓÓSDqÏŒsw\NҌ˿ÅÀ¯*õ¯. ™¸º¤ÍûB£¬.Õ¢§ìÒÂ#î©æèèèó“S×éÅŸý{Dqç*uîˆ;âˆ;⎸#îˆ; îˆ;â>&q¿™+|^+GªeÔ­ÀCGÜÍŒÝÉ`©–AÜqçj÷IŠfôÐiꪰ£Ý«ÎwÄwÄÖ2€¸⎸#â>nqÿî꘺NÿþÏþÑœ!qÿ2ÄüÁ  âˆ; îˆ; âˆ; îˆ; â€qŒ;`Ü0î€qŒ{v9::z Óc}}ýòò-Œ;tá­†r˜Ò»ËûgÊ0î€qÀ¸`Ü1î€qŒ;`Ü0îwÀ¸L‡óóóDã~vvÖjµ(À¸Æ -¬¬¬ˆ»»»” `Üã".//#®}}}bŒ;`ÜRÇÁÁuí7nÜ ‘ `ÜãR677qÿøñ#¥wÀ¸¤”V«uëÖ­­­-Š0î0vã^«Õ€Œ‡#çüüüæ·‹ÃxÅÝ ÆÆlÜåê¿[úüó““Œ„ÞÃéèè軫? Ð˜äôÃ÷_¾¶Š `Üã΄qg¸ÆãŽqg¸3aÜ0îã^+Ü̺3}MñµúËgónNÜÜÞ4ïo±ñÕçïLtÜÌ¿º-îÜ­Ùâ›–›·÷‚¯nß±‡‰qQ!ó³ªØp þv`£p7·rãw˜²qwŒ‘tÒÊÜÈ%Æ…Œ©6.ê+c€|'dÒÄ3ñ ×ií­xN=°Sþ†zÍ6°nÒ«Ülšhæq[o·åïR°Š>@õ•ñgþVÜÄñ#R™ßQKbw!ãd«nÛæ>ØäÒsìf|É<÷äà´?_x‰ °ÈO¼ç„z4æKŸG² 6çFàJÛ€4¿æF8ÆâQ‡qÀ¸S÷^{Üïº_%YÏjxÞÔ$ngš#ƽƒ+ê1ÛUþ‰Õöq¿•˜ƒ1ÄÇrîaÜÄ ÆÝßtçw} ¡Cs“u*=Œ{‚cþ¼]p†oÒÜ_ÁûA÷Â?ñv§ûXó %Døf29 ÇókbÜ0î0ÇÆÝ˜’À k¢ W|㢪­‘]¹KJɤc£…hʾ²õãÛlwà´B rT™‚q÷¾õsP•¦®ê܆'žUÄ‘‡ëàC l¥7çMeÜBN ÎðÓ•à½sÓo*ú‰;=€ÚLhcLy$£ý5#1–¸ã€qŒûlNÆ÷ŒÎ¦ëp†iÐÏË©LwŒ;`Ü™èU†Bc¸`Üã΄qg¸ÆãîsppÀhí`‘ñÐcäœýÆoþ%†öïdŒ;Œ×¸ƒäøøX:ù—¢Œ;`ÜSJ«ÕZ\\”Æ]þ•ó`ÜãžF677íã~9OÆ0î©#ÞÄ¿÷FÞwÀ¸O‚ËËËÄ×ìär 0î€qO îÛ¨Ò¯'.À¸Æ=M'€àŒ;`Ü1îwŒ;å€qŒ;`Ü1îwÀ¸cÜ0îwÀ¸Æ0îwŒ;`Ü1îwŒ;`ÜãwŒ;Æ0îwÀ¸§‹f¥P¨4Õ\½äÍ ¶zû%wÀ¸@J¯}]ÓøÇi]ÝÚm×,ïc¯¦} ÷Ñ)‚üG(ÌÉ\/ C©î§)•T‚RÅKÿÊ]’”Ix›ÂÙš«!î}D»}¨cÜ1î=]àâW(Ipò–*õJ!ø&šØ¿>%\³Ú^ïìåNxWÚÈþ$^+›á ­³ÝØeÑ5î6£`ôÎU>–ap¼¥R©Í…ãž²Z‡¸ái£RÎ7ú£w~·òŸx&Î=¿U;ëÕ(Õ¨_wÝŒ;Æ ÷ \ä •xík7_¹fu¸ÞÙ+f¤b+îø;\ì܈\jÜKlbz›aüZdE<À wuªs¡“Ù1ÚŽq·uNâx&!!³¹Xi2X*\¹i³wŒ;@¸v—’áŒ{èšÕþzç~V™½µ_ ¶·r‹íÊÖ|5Ž•ƽ߽èHÈuˆ+÷«gAâW΂ÈWÎÙøWSßÛ¾¤²Ç½íW*gko'yÊÌÞNý24‹{+¿BÞ1îÓçòòr&v•÷‘ýÔ¸ËðAB¡AïžQä-¹IŒû”‘·’OŸ>ŸcÜÛ!ÃÃTNôÈË—/yP˜%À¸…Y©OŸOŸ_]]QbÐÄ `Üçý&ã>ãN;ô 5î€YŒû¼ƒqŸŠqÀ¸s‰qŸãN;ô 5î€YŒû¸8??ǸcÜÛqvvÖjµ(4èKRhæYB^?~üH9`ܹ‰Ä¸§Ý¸SãýB;dŒãããõõuÊã>}ÎÏÏÍwŒ{»bŸ•g2ö÷÷åEŽr€Ìpvv¶µµE9`ÜS‹oÞ¼Á¸cÜ1î€qpÙÜÜ|ùò¥}ì,¯†=¢Ù Æ}jÈpœ•§?0î[ÿø“µ§™Ÿ~í×~­÷Ä·¾ó ÷hsò-|Z­Öÿõz9!Ôyºó»ßý½®PÿïÿÏ;.13TõÅÅEæõë×” Æ}šA9+uc0îúg/¿y{ðþäšiÖ§¯KSx>s~~¾øý{>“œþúçßûì—€YGz$×µ¯¬¬P&÷)׸ór*ÆãŽqg¸@;ûa;mG1î€qg¸3aÜ ½<~üXºöýý}ŠãNû¬÷拜XÞnš¯6„ب«ùZe9WÙ쪬ëf^_…µ2ÛlBî›XÛ ¾ÚÙ.Ø2I›qÿøñãË—/oܸñî݈› ÷`ÜÇ-ƒe2ÈZ„åPÆýììLç½{÷=zÄ 3Áåååææ&å€qO³råH©qß+yÞ+ð4ÚÇH÷à™årÔL’Á’ÖM§ Üô"WðD3w¬‰(½rmSh‰ž1[ ™gùIûUÜSi|[¦H¸.M¥/¨…1+rHÁ†tQlÛ ´–sºnC¹–Xzo‘t3ê¿p÷\Ï¡ªZ]·;^&/Û’×l ƒqïXç† áoUÈõ Wv:y†K&±@ÆÐTFFûþþ¾iª(9==tûX£%X$ŽÆI‡È‘[Ñ3êwTÊý±~:ö{ –r¡ŸC$2³–íšÊÔjµÍÍÍ7nЩŒã¡Æ0îGz—çÏŸc܇3î½µ¨+±)rìhå<ë/§¦*Z&ò{e/,y90î€qǸcÜgÖ¸3Ñ« ½Ê`ÜãŽq†«««Z­†qǸcÜ1îLwÀ¸`ÜS /§ºüåÿãõ÷—Wþ`õi¶§ýùf~‡ç{÷FÞÛcW.//ÿÅ·nõ²{óO2fs>ýþ£Çþà—ÈŒq¯ÕjkOŸ21™©;ǸOºƒœ+ÎÎ΄ò/;<-¤¿—Gt||L4À¬wyý-½}{r}ÍÄTjïÇ0îÔ¸cÜGŒé™nqg‡G…éÖfqq‘hŒ;ÆãžM0îóµµe{ ”óìðTÂØ‘¼^“€qg¸cÜ{…÷ùáãÇ‘ñ_ävx’GŽhVFQŒûÔŒ{³’+Tj¿êf€l;MM5bu¥©ç뢰Ýëæ0î÷0­VkVÚÚb܇ü¡Í˜/.rIjßp˜¹îåˆãGtyyI|ƽ»å•3¢´ç9f=ÓÁ¸‡k{YR׫ÔK¾ w3‘îÜ®b¬yS×v}R/‰R=y';m®´—°«IGÑõhÎî.aÜçéÚ×××1î™GêòÕÕ•™·­«å’Ôö6s;Ü•ÃÃCëÑÝ#Úßß'>ãÞ“qëvÆÝqØžå,©¨Uö*…$ãî˜o?ÛšIÙ®â<¾¹ÈÞÖý2eÜâ·;Àø}B jî1îÓäììlVšcÜGvÁsD€qŸy㮼¯r¡ª‡vÐfWZmóIÙhß|KšŽ“vjµ…ÒFpc çƒ<ý2éo.º·þ®ÚÕK¥Èž$ 1úÎ`Ü9Ïwww1îwv˜#Œ{û§ 5LǸg^NŸ³Ã`Ü1îL÷Ù`VÞøcÜù 0îL÷ù…wŒ;;Ìƽ3»»»À§]Ì`ÜãŽkĸLÙ¸ôÆ}ìPãŽqg‡9"À¸`ÜgæTǸcÜÙaŽ0î÷TC;Ææˆã€qŸóœ~Ü1îì0GwŒ{Ú9;;{óæ ÆãÎsD€qÀ¸§šãããõõuŒ;Æ=å·—Gé@^áF„wÀ¸ÆãÞ7­VKzwŒ;Æ&„ü€qŒ;ƽox9ãwÀ¸`ÜãŽq'ù ãwŒû( ÆãwÀ¸wfwwWø´‹Œû$hµZwŒ;`ÜãÞAýJoßž\_31•Ú_ 1îc‡wŒ;`ÜãŽqg¸ÏWWWµZ ãŽqŒ;`ܧoÜ›•\¡R›J>ƒoº¹]ðÚlÔûZ±¾‘¸ÅQÆ={œžž>þãŽqŒ;`ÜÓiÜkÏç*M/M©´a•ê^²zÉ|Þ®”{î%ŸÈµÐdd"­ya»i–”6 Φê5ëµf»íÛýBeÏOͳӑº‰Í.•ö0îwŒ;Æ0î€qŸšq—>Õ÷¬{%6実öÖŠ¥iŸOdI¥’aûÛqCÒ—+Gîdr2ðn7ͦ•‹.¬b]{ì~ƒ÷¹€¦2wÀ¸Æ=½Æ]™Zc¦ë_kí¬ýJÍ´1î‰ù¸Kêf›•“@ÍØUÌ·ª¾\7ŒQ3~¾ÚzP¿Þu·Íkñ•)ïfÜã;€qŸ+x9ÕåOÿìå7oÞŸ\3Íúôui,Ñ‚qŒ{º'kåÓÝŸ—S1îCwwŒ;Æ0î™0îLwjÜ1îLwŒ;`ܱ­Lw˜}ãÞ|á¿T"6êÞÂZe9WÙq“Å—´êkAÊ óµ½ö«˜ÌØD«´Ù¨ÍP½&SXޝVxQK£qßÝÝý£?ú#Œ;`Ü1îLwjÜçÆ¸G¯ô¯¥WÞòÒZÎqónʽR‚Ñ÷îrÎ{W'šþ~Œûþáþ“òOD~O#`F‡À¸÷nÜzã>v¤k___ǸnÜOB¶õÕ†S¿îÕCGê§­ßu¾R•Ö~“caÓl3WÛAu¸wWà¯èâ®ù»Ö9X%)C÷V¤m»ÝmïF%ɸ{9/çüÇ‘=Œ,Ù{»ôôÔ¸sÊ쀹ĸÆgggoÞ¼á*>„q¸QͼMÎ Àø‹¢—6î?¾ººÂ¸cÜãŽq§ôã>3ç¹t0\Å'aÜ™èUãŽqŒ;Æ0î÷áåTŒ;ÆãŽqŒ;Æã>3§:WqŒ;ÆãŽqŒ;Æãžj¨qŸÏóŠBÀ¸sÊÆã>á3š®ãÎUúckkKºFù—¢À¸sÊÆã>Ž¥îݸq£ÕjñKÆ}p¨qŸ+jµšíQÎS wNyÀ¸cÜ'Àâ⢹ôÌJÔ€qO/———\Åç«««7nXã.çûí 0îœò€qǸðó¹ciÍJ_v€qO#Ô¸Ïò‡ŽŒDHcwŒ;§<`Ü1îcåðð0>îÙÙ¿`Ü<ÏéÇ}x÷îÝóçÏMó˜ÓÓÓV«%ÅTw¹œÂÁ¸sÊÆã>®®®ä.I›qyy)wO~4Ã>®¬¬ð{Æ}ä)4+ï)rÙ €kĸsÊÆãÎ÷™ãøøxVÞá*ŽqǸSÚ€q‡5î———t)÷a‘g‘ôî\Å1î€q甌;ƱÍJ¡PivþªCšÁrî´ŽðWª—D?ë¶“3,Õ½ùzi´ycÜCðr*Æ0îœò€qǸƒcg¥Ö>Ôÿ×›sݹ÷…Ÿ¢ƒq%Öß%.‘ÿZËdâÏ.Ý_9Ø·¸Ÿï°¹v{þªÃ*vQ°KÑ]qm<Æ«8à1î”6`ÜaÆŒû üˆÒF,o`…¥JÜï:ƺqwl­7_¢×ªÇr:{÷þ¢]­y›Ì“÷6~ÈÖ¸GV‰ß'´?ä‘WèsÉ  ÆãwNyÀ¸cÜÇÍÕÕUZÛ¸[Oªl¬vè%×Ïz¸v6îkMB¯®ÚÁ¯­v>]',q³ñ}²Þh©Xm9Î%¼w××Ý2ïmüÛwwk&ßÐ7‘í¶ÂãfV^á*ŽqǸSÚ€q‡5îüˆC1òJìqíàZ¸cÜ]¨qǸÆS0î÷qsxx8+a@ê| E`¹ºº2ƒòpǸÆS0î÷ñqvvv¤¹ÖOûͼÜmû•qöÒ™˜¯.//¯õ ñ¯ä̵îÒZÎË׺»Év_ÉM˜¯LƒG™}è›QU{ÓóLŸõò\2dL?þœ«8Æ0îœò€qǸÏ5½÷*2ÆÝºp s=ÔŽ¼|æ½ç.™wŒ;`Ü9åãŽqŸGž>}š\ãÞ{¯2î*½wá’¦}>ô<ƒqOäòòòðð«8Æ0îœò€qǸÏgggán9úéU¦k1úcQùúõÐô<ÓGÏ3\2x9ãwNyÀ¸cÜç‡õõõÛ¸H²u=Ùíy†KfºƒÄ¸ÆS0î÷9áÍ›7ggg”Ã,ùŠÀB;Æ0îœò€qǸϕ¶˜®lã\Å1î!?§<`Ü1îé¥íË©€qO?Ô¸cÜãÎ)wŒû\…€qŸUZ­Ö¬ŒdÆUãŽq§´ã÷!¡Æã>ÃÈØ]__ç*ŽqŒ;§<`Ü1î÷TsvvöæÍ®âwÀ¸sÊÆã>PãŽqŸíó|ww—«8Æ0îœò€qǸÏ———Æ}VáåTŒ;`Ü9åãŽqŸ¨qǸÏü©>'WñwïÞýÎ÷îýÁêÓ9Ÿ(S2fÔ¸_^^þÆoÞÈüo´¼òHN™?ÌßüÍC×éîþõs«øûñññ·¿ýÏ¿üò³lO?øÁw¾øâ{Ù>Æ|þ{¿ÿûÙ¹‹Ã¸Ïi»\ýëÒÛ÷'×LL2§”wyy^üþ=~ÄlLÓƒaHã.-ô|_3ÍúôéÓ³¥¥EŒ;`Ü™0îw&Œ;Æ ãŽq§Æ}ÊÆ½ù"'<6êÞÂZe9WÙq“Å—´êk&eO«¨­¯í ©ûn&Ááô“­¿Ïñ©ï8…ò©¯ÉýË–E„‹Æ}b^ml‘¿WšäošžèÊœq[„„ƒ¤½Rõ¨Kú—{(¦ûGǸej<È;?y±ê/Ì?h¨«Eoæë‹êR4YÂä¤Ç¸cÜSŬ¼^=^ã½äÈ @é•·¼´–s®XnJ{Éq/fþubÙ¬%ÛUäÌFi-¼ÊÎvA'S[ñ®[N¶¯6tþµsy»™¸Ýh&áÃÙ©ÕwjN2áçÝÿò¬×µ‰CžtÑý M—aä¦ÂÛ7u‰\§å½;¹–nçUþÒ~E~ˆøvU²^o-0|™Ì&пið‹ÇrP¡®×z±‰a9ÚuÅ7¿_MGteʸOF#Shõ.õ®'iþÑ1îã2îÕöm··ðYÙ˜z9JæLÖÍW/ÜôwŒ;5îÛî—/_ Á7ß|óßýùÿ’¬˜a‡xu±ñܧw °WšPm¢}¹àÅgüü#×uá‰gk®[IT&Ar&QsZøª7rÁ¹Ð_u°SIå Ü¼ZNeè܇$]e£æpž*YBA]»1²ã>…Ègü¾±\OŸœÛ aŸ`ªÒ]™2îcÐý€«ß~õ¾ô$Í?:Æ}Æ],”ο.ÓH–ªá:xe×ËÏ.Úù{Œ;Æ}êÕíûûûsr°›Ê„t_UþÙ:$¯"'RÁc/n…Ÿ¼öødÍ5 ›qw.~~Q4[?s[÷ßn<“ÐᨅÞÅ/H±é1ãn¯Öê@:÷ÄýI¨¦JúVeÔʇ¯²Þ~.çü꽄£/™÷7n¦Ã«3ò]Ïçø¼Ž¿{"8?ý^|£jܧ]Ùj*3æ ~£ö…Ÿ )Ýõ$Í?:Æ}"Æ];ò¸qW]¥&U³®Z˨f6Úè»K0î÷rvv¶µµ…qâÁ1ÓXƒ±u±O׸¼|ù2ÝÍš§ù¡5³]súrê hcZ~tŒ;Æã> ÇÇÇëëëw&z•Á¸3aÜ™0îwŒ;Æ=Õ\]]ÍÏøaw&Œ;Æ ãŽqǸcÜg•z9ã΄qÇ«áÕ‚ã΄q‡¹àôôô-¼}ûÍ7ßP3jÜ[­Ö»wï2ÿýÅ_üÅöövæswww˜X"†÷««+. ™A^h0îÔ¸ÃÌsxx(„¦K“y&%Æ}NX\\|üø1åÃÄŒ;Æ}hµZœpyyyãÆ iÜåßYx ã>ŸÈò1*¤À`À¸`ܳ5îsÅãÇíT_aÜSK­VsC9>>¦Læó`À¸ÆWWWòI9̉éa¨¾Â¸§S”Ìs!Ëââ"çû`À¸Æ§§§ÏŸ?§2Ïññ±¹ì=õ1—Cª¯0îiC§ŒLé?L ®¬¬È›››”ÌbÊ0Á £‚`À¸Æ}Þ;bpë¨ÜǨ»Â¸§6P#¥M¬ÎWWWv^ž/nÆ0îsÊåå%ŒÌÝ 80îsTÚ"Æ0î€qŸSx9ãwŒ;`Ü1î÷ÙÀ} wÀ¸cÜãŽqÀ¸§jÜ1î€qǸÆã€qÀ¸c%1îwÀ¸cÜ0wŒ;`Ü1î€qǸ`Üg€V«uvvF9`ÜãŽqŒ;ÆãžjŽŽŽÖ××)Œ;`Ü1î€qǸ`ÜSÍÙÙÙ›7o(Œ;`Ü1î€qǸ`ÜÓ~žsiĸÆãwŒ;Æ=íðr*Æ0îwÀ¸cÜ0î3sªSwÀ¸cÜãŽqÀ¸§jÜ1î€qǸÆã€qÀ¸c%1îwÀ¸cÜ0wŒ;`Ü1î€qǸ`ÜgƒËËK ãwŒ;`Ü1î÷TC;Æ0îwÀ¸cÜ0î3Àåååþþ>å€qŒ;Æ0îwŒ{ª9;;ÛÚÚ¢0î€qǸÆã€qO5ÇÇÇëëë”Æ0îwÀ¸cÜ0î©æêêêèèˆrÀ¸ÆãwŒ;Æ=Õðr*Æ0îwÀ¸cÜ0îw¬$ÆãwŒ;Æ}PãŽqŒ;Æ0îwŒ{JiµZ‰íÚ¯®®Ž‰Œ;`Ü1î€qǸ`ÜÓB­V1=zDÉ`ÜãŽqŒ;Æãž.¶¶¶"Æýòò’bÁ¸ÆãwŒ;Æ=uÈ3ܺv4ãwŒ;`Ü1î÷”rvvf\ûææ&¥qŒ;Æ0îwŒ{zÙÝÝ]\\lµZÆ0îwÀ¸cܲ`Ü¥d˜)~ô£Ýï¯üŸþÓ¤Ü2ƒ¼)ͪq¿ººúö·‹Ÿ8,-}w˜Xº¼¼¼qã7(F‚ã÷è{{û‡_3ÍÄôéÓ³¥¥Å~åo¾ÙÜÝý¥—Iž­ã¨¬M‰q——çÏ>û¿r6¦!Ÿ€ Æ0îwŒ;Æã΄qg¸Ì©qVÎûÊ«ÞÂÆƒ|þAÃM_ÒvZ-)ƒÌ‹Õñ‹Kh'W‹r«ù…|ô‰ßB¹1oÆ}¬?±šªE‘/?Ýo×y¢[Ÿ­À¸ÏLLV—&6) ài÷±‰»J«·IìÄIûË\?ª%V.L™paÜÒaÜ£2$Uc©ê-_*æÅtSZrÅÔ—¼™“‰Ã™7«Fd£R—µ›óWÞE·Q^p?:)õ~:ú®ÓËYi_D@e>îU&C-jf<€gãåÔ ^›Ò(\w€Y3îLô*ÄqO‰Wc¢W¦™ Œ;Æã΄qǸ3aÜ™0îw&Œ;Ư†Wø3aÜFkÜŽŽž<ù‚i†¦¿ø‹ÿ[¿¿òßüÍÿ1%óã?˜‡Ã¬ÕjY5î­Vë§?ýcÎñlLß|³9L,]]]ýñ?Í|)­®æþð?'0îóÅÇ…ò/E1»Æ`ÞXYYY__§0îsD«Õºqã†4îò¯œ§@0îéçõëצÓôÝÝ]Jã0/¬¯¯ÛqC¨¾Â¸¤óÐrvvF™`ܲÏþþ¾#—P,w€ÔbZã}ÎÏÏEr9…ƒqH'îCBËÖÖ%€qȸqN§Ç1ž;cÜÒÉåå¥}Gž/ò¬1óWÊã0']cÜf ׸Æã=Œ;Æ0î÷Ù¸À¸`Üã€qǸ`Üã€qŒ;ÀdùøñãSèÆãÇë·~k˜=z$ÿo€qÀ¸ÏÍJ¡Pi³z©®fê¥x6w9çççCöstt„qŒ;Æ=;\ÏÕíÇzIhÇmDR6CžÞKí¯äÏŸ]qŒ;ÆãÞ?Ú]Î[ø5ä"ìΛ®§×s![¾ÐÄ”*¡ÚúxÝ=Æ0îwŒ{nÝùàÔ”Ó]ò–…«Õ…R)ºÈ®,ð½½õêñ wŒ;`Ü0î÷Ô ¥”ÔPãwŒ;Æ}À¸Ã9===‚L 7Æã€qǸC6‘^í³Ï¾sqñ5S¦!ÅãwŒ;`Üã΄qÀ¸`ÜgŠŒ;`Ü™0îwŒ{ziµZ74rfȬ·¶¶(R©qV΋|ù™±€Õ¢ÅU5ßxÏ?h f%íº ™¨Í«ýdÒaI|y_»¸ ±T æÊÞVLøjU•¥s¤ò‚-gŒ;ÆãžFÖ××Mr†Ò€Ô÷ê’çÔc­Ýª²­ÆwúV;ÉŽK£¯ÓH“êy\iOE~!šÒb›m<“À4ËÜ–ªñÍÅs3ûVVy$˜xaè`ýMx»í'0·. ß¾_´ÙUw+*½oñÕW yw7Ú÷„£0™ø£…l·½óÁ¸`Ü0î#`ww×uò#eé2îÑÊcßÂ:uÏžã´)£^?–IÌj»žÕ³¡2Ñ7ÕöÆÝ߇èŽÅÓwNݹµ¿åðc•ë^þ7Á¸Û»‹n5îmŽB-É/D7ÚѸ?Ž7oÞ`Üã®8880SüèGÿºß_ù?ý§ÿH¹e†zë³³³xþr!b )2î~¯‡5‹ÊG.óΨ'Ž¥¶®ZµQUÎa3ª¿•–Ô÷‘L"ƽÏÄ_b3ŒïXèbÕ«=/.ÙV+~…z$çÀ¸ûû©“XŸ=ÞОt¸‡Q›síx¬©Lø(Â/äñ4•Œ;dǸ¿}ûv{û‡¼:3+Ó§OÏ––ûý•¿ùfsw÷G”^&y¶ÊsvT’qïÞ=y1ÛßßÿÕ¯~%/lræñãÇmI;C®Žnµ^>3˜ãÞÃdLd79¡)U;3ª£â¥Œ;ÆãŽqǸŒ·šîž[zm×p;V¾^¥J¥ Œ+oª¹RÉû¤¿¬‡fB`Æ)»½Ê`ÜãÞÁ¸·{"ÙÛ»ó Ój1H9¡Ì{ê`È)þ¸Ó¼î¢Íûþ1îãü5íØà×të>ûaHÍÏ—ã^w«ÝC>ÓŸC›_0þóÍv{WŒOïæÆµÿ¯ÐÂ0î€qθwç¢Cw¹nÇ®áîr=OXç!3ç}ãÞf®Ü^Pkt2ynu¬2Xò® Ò-Wr‹‹ØN†ºôj÷b¾Ê3ŸïIbϸÕ©qk¨„Ê3–½gPÉlÇñ|ÂÝ«éç«Æ–³Wã€qH£q¸¥Ä×ãl†‘Éé‚w¸£›½—S³ðkŽìçø`Ü&nÜ™èU† ã€qÀ¸3aÜ™fѸ·Z­ÃÃC´0îw&Œ;Æ=ÕÆ]^…———È1`ÜFoÜe4?yòE&§ÿøA&ëç?Ýï¯ü7ódõWžÃIž³é4îïÞ½3]묬¬ Ç0$òöïÆúå—Ÿ1e`ºqã70î£1îYåõë×7nܸºº¢(&`ÜÏÎÎÜn1ß¼yC©Â000aÜã>/|üøÑ¸NT€É÷{÷îEžÇ“À¸3aÜ1î€qÏ­VëÆÖ=¼{÷Ž2«qßÚÚ’'Ýææ¦ÉG~\\\¼uë–<)[˜”q÷ÇWŽŒ©ÜnؾîÓj1>êsl¬åVwòé:°]÷­´Ï-thzôºüB>r?0ºÆã>UÖ××#BuzzJ±ŒÏ¸[^¾|Iy¤{ÔŽKÛjG\^*æ7|-fô}ƒ›7sáñ’£õÃEû>ðî"ìÖ#H;c,UÛm%´ŠsJWNYöˆïŒ+ÔY ù·-¥È~V‡Wã€qOfߨÍâââ£Gì<%€q‡Ìw; rdÐ4;x¶5¯îÌ¡¯ÚÖÍëjìà– æeß_®:ƒF÷¸ÅøVÚ¯¢nâT…zhXë6B‡½¾³*e~!ºQ'«éïǸM•ÝÝ]Œ;`ÜSG«Õ²ýй¯ÇÉkñ€q‡l÷‹[­*m¯ú9R-mm®ó•rÌ~Kã˜Ãí¹ÿ¶‰eJ{ó Ò'÷ø£Õÿ±­t^%¹Æ=ž[ܸ{ûŸÏû7!îVʱÎ~;Æ}D_ÞaSw˜ãþõ jævòJL¤L0î÷.Р ãw&z•À¸ÏŒîSsȽ{÷ OFÒ Æ0îLwŒ{ßPã>ÏÆ{¶iqŒ;Æã€qǸÃÑjµÞ½{÷2¯œ`Ü»@;Æ0î÷ÙÀv wÀ¸`ÜS 5î÷ÞãFÅÊÊÊÖÖA€qïƒËËËýý}ÊãÞ™Quƒ€q³³3jþ0îwÀ¸§ãããõõuÊãŽqŒ{ª¹ºº:::¢0îwÀ¸§^NŸcÜã£äàà`só>CëMe:?ÿï(„Ó‡?yòä NRŒû™¡wŒ;Æãw&&Œ;Æ=ÅÌMû³r^xW½…ùüƒ†›,¾¤í´Z RŽ-sw•>Vo³u¹wUïc£¼ ÄRu·ÚÄjQ{~ÁƒÏB¹1¼-VÅ›/?sV‹BŒe[ã2îççç»»»ŒR €qœ«««Z­–qãu±ÒejϪ–/óŽávSV—¼¸ïófN&IæAÎr]ÿ6 ’yxCÚy»»Ü<(Ûfëå²ÉaµX|PÎÆ=”[|ݰ‡öÜ¿·?ʲÛû››õÙÒaž[µ4÷ñÌãEàÝ_îŰÛRÉz¾êǸnnnº7gggÆ}pNOOŸ?žqã.ÍYÈú.PÙeϼzþÏ:BkïBVØqxnÊ!3/.µ­›ïPãîÜEø›K¼IpöG.©.I“Ý(/•Ï\ãÊ­µÅÊÖÇÝ­ZeAç­wÍtàõÍÄ=w¼¨Û=…ðÊÓÎŒx[!ßß¿qôèÿ²²²"Ú ¿ÚÝÝÓã×ý×Ì>7nÜ8>>æÊ÷ù5î/_¾Ì¸q·µP­,œzn][6|+u똥_ô+}ÿ œñ™‡svg;ãnïÔž¨u•·öï” nÂÆ]~,.äUJǸGr«Æ½C»-vfÚ+º|ÞɼÑasñ''KÅ|¨ḬÛOûå奴é=r-WïoŽƒ§OŸ2bCr-•rŒûœ"ÆááaÖûÀjf'óTï§ÓÐ¥·Ì«ÅÛß÷½­É´q—¦ùõë×SlãŽqǸ`Ügºƒdbš‡^e0îwŒ{¸ººÂ¸31aÜã€qO5Ô¸31aÜã€qH/÷îÝ›îë’€qŒ;ƽf¨Æ0î€qǸcÜã>¿´Z-Æ…Á¸Æ0î÷´#¯åëëë”Æ0î€qÀ¸§š³³³7oÞPwÀ¸Æãžj¤u{ûö-å€qŒ;`Ü0—S1î€qŒ;Æ}6À½aÜãwŒ{Ú¡ÆãwÀ¸`Ü0î€qŒ;Æ}PãŽq7———G0m=z´»»K9L—ããcŒ;Æ}X_E!`ÜÇÇÒÒâ§OÏ..¾fbšóisóþ¶ã÷¹†wŒ;Ɖ ã€qŸ.//÷÷÷)Œ;Ɖ ã€qO5ggg[[[”Æ=­ÆýY9/òeoõjQˆâªšo<Èç4Ë3Xwœ™'d¢6W¬öµ‡í—Ä—÷µÛÉ›XÈ›P»ºÏ/U‡ñ©Á&VUÑ:Þ(/ØbÍT]¡Ã ŠzôÛ¸`ܧÅñññóçÏ)Œ{J»4dž•´†l¡ÜЦÐó‚¾EKrÌÒ‹ë4Ò8êµ´Ê’ê#È<œ³Ì-žR妰Í6’IÙO öÓOÏ$’›Ù7µ®Ct'ý ƒ#u6áíyh£Õò’ZX]Ê—WËùðÎ$¬ëÜŠ4Ìžx¥Ü ؽºhcÜŽ(œyš0yåï'³ù`[Þ¡õvÓ…qÀ¸««+:‰Ã¸§×¸G+†]ïèÕ{Î̦ŒÚñX&m+ÅûϼCÕ¸?ãGÏ ¶ÍĹshgÜý}ˆî˜›F&îÂNÚж]-hËþÌ3îñÜœG—lÜíÍFÇ÷6Gä-‰ÿ m&S¼®ƒͶ0î÷”ÀË©÷Tw¿rÔÚ*e¹–ŠygaÄÚÆÓ{‹¤U-7„ÓZf¨ÌC9{ÍBTæaS¨,ämý´›IÜC'dâî³ãM“›ÊèÄ*ó%ÛF¥ZlW+½[ð®oÜã¹Å˧‡›.µq»¯/OÌ<úƒú·X‰¡¾•z[4•À¸`ÜGÛÄyîžÖQ÷žgz~úqÿ"£ÎãžRèÇã÷Y2îÂ,ÐýÚþ§`y;ç}«çÊ67ÿ g{ µÛz|­ ¥›§³V÷^–OÈßÝáj{;è}égèîXüÛ`ŸªE¹Ñ  DOŘømä'•¹¿Kî¾ÅK¯SAµû!üß1¾b$Ï®¿QPD ÅÜ©œÛíaâ.%ÚëFRÆËª¯b 6äÏuŽmŒû¬pzz*¯”Æ0î3Uãž`G<ë)’ ·MãºJg¹7ÛÙÑ´Ûz|­È]uüðâùÇlpò.9;¸RëÞâßú+VËyõQºw5ëºØ¤bŒHâþ˜uËí­s;‹Ù¡ Ú‡…šÍç»—pçß(±ä{/çø¶;–vÆ=‡žK¯ÃýÞÅη´÷ÙãòòòððrÀ¸Æ}¦»3XAÜHé/㵫jÝb1âRmFq—Óá¶!²Vh¿ýïŠEÏÍ%Ýlˆ=­ß¦²ý"²#¡½›¹è·‘zÞð#€.ÅèHò×zÝg炊µûÃÅwÌþâÎOßá7êѸ·+ç‹dçžp,m{80îöHÃ7}¡ß©ClcÜg^NŸÿò¼øþÿÚÞþ!ÓœOþK^Ní׸c\¬kIðÈìüp³8÷ôruuE!`ÜÇjÜé’‰‰î SaÜãN;`Ü1îLL÷QwÕò:eÕ­¤w·ãº}Tñú‡3Zá ©ÍÔŸ1 ˜:=Ÿ £­£FØ+ŽÞÄè~&Œ;Æ}¬Ó3GgWÛŽißÇ(÷«Å å83¯.9תÖ®îîdûIy£¼ ÄRu˜ÒéªnX¹`KÈg¡ÜÍÏš/‡âǹ¸v[÷TwßÜäËe÷EHõ¦_¾‡†é7êjc¢6J~Öí’Ýü½4z»=å»ÝÇŽÚONÛl/ý¦iòW¡&ÔŽ4²‘°#LØt4Ÿ>Ê¿³ Žn«_ßÝþ7íyOÜnaÚ´DÿŽ¡=H.F•ªQm4’Ž4ñMÓ^6y—£ËÏ„q§Æ0îS1îQÇ,­¤6¦jù’¯³«Ñ”Ö1»^Ü7‚yOg4F’y³\׿ HÈüëØž¨mi«ms³«û[79Ä·è%Xªê­”˾×/>(ç=ãÎ9é ÂÚsÿÞn¯c72Cë³ug þO/wOšûxæñ_!Á»;¾Ü)±a·¥’õx£…qŸF{è}Áä×ûÜ·ò„ë[_Æìîò"=™Äûžé¡gŽav»w7Ù¡{“ęȻ”íz ìPIݳÄzVéø2ìíúûÃéϹ'ÿ¦]¶Ú’{PIŘ~íêæÛFäH#}òô¾‰¾~&Œû,ÒjµÎÎÎ(ŒûlwéÀB¶Ï·zÊþU;kûœzn­ƒÏ¢îßM9dæÅ¥êæu½upKKïV-Û=Ž™¯.I“Ý(/•Ϭqo›³PÊÙÇÝ­ZkAç­wÍtàõM¶qÏßívO¼¢¶3#ÞVÈ÷mú£?úÞÊÊÊÓ!X\\œKãn«¬#}{Ç:½ö—¸-ZÚ÷\6Lʵ1y¡Þ»{7î}ïv7;éö"ºw€2îánáÛ÷¥‘pï´10´½–Bÿ‰‘"êÖå`¿i7ןЙg‡bŒþŽá+ZÔ¡2r—ç­Pu¼Óã&úù™0î³Zã¾¾¾N9`Üg¼©LÈAj] 7 »ºÀzºÉÒú5»ÆäyÎoøÌÃ9»¶RmÈ:Ñö{bkˆÛ÷øáÄ»üª¸÷êìõFí=‰›s´X:Ô¸Û=lg¦½cÉçý’øN¶Ý\ü¡ÊR1j3ì¶f°Æ=Kôùrj¼¾zÖº ÉXG(Óìh'5ìdú7Ÿ§iÝÞ¾}K9`Ügܸܨfv2ŸÕòqºô–yµ8pûû¾·5smÜçØ¸Æ0î÷y3îLL÷™l*“æºUÛaH½… ÒaÈøûuqÞlì¸ó;ÌGg)ìÓfŠõ~t}–C? Œ0î³ÓT†—S1îw&&Œ{*{ݰ Ü×J_}ѸŽ3Ô5GBoz ¹¸è³Ã|~À~]ÚwÌ”‰Ó•Œ[(á¶ÓѲê>RlpøS?öþûä1ã×úó#$)D{Ù½h'Eí;ù±ï3”Ëy×âGš¤7‹fEz•É ¼œŠqǸ31aÜSjÜ#xtí[£¯¾Vúê‹&¡ªØyuÕôûÑKo!ñ]êzPƒõëÒË´¡ÖÿÐæeÖø>'þÔ}€>yúŠÄž‚ºí^B'EíÞv’&åÖ©¶¾íVx9•wÀ¸wFnå4­V ñéǸÇ:ñèÜ·Fß}­ôÜMWãÞco!ñ]êå úï×%éþ'ž¸qw=x¸cœ6E—ÜYÊÔ}€>yúŠUcï)¨ÛîÅ;)jÛ;§ÝípÊøOÓK–UŒ;Æ`LÆè9%å=ÏL®l·4ÞÍcÜ©qŒ;Æ€^e0îCpuuE!`ÜÒgÜW?Ý—;µôè­—’±f4ò¹ˆ}Êtõw/}ïŒêÆWÈSÿuÚæ3þøSãw€AŒ{Ô¾øívã]yD^Äë³—’Á3uTâð3—4¼Vå²Ó9ºR¼çœYéi§so‰}ï$”|ÏÅ$õ¯’XÈÑn)û-ä^úáéÙp|hneØS€ tø÷Tsyy¹¿¿O9`ÜÒeÜ_°k$õ6Ó¹Ä^J†Ï\z¡vuó~—)Ú™«&$=íŒÊ¸÷ÔQL»þUb…)áFbõxwÔ¾žû0‡Ö½ {°ãžrŽŸ?N9`ÜRfÜÓÑò{v3§—›+äñìhR®½ôºƒqO)WWWGGG”Æ`V;ðrêœÀË©óösÛñ_VVV¬q¯Õj¤Õ¸÷÷ˆ¿ß®IúhÄ<8£îSe°ft3š½õš]í9x΀qǸôXÑ.bðÔRhÜ=»§ûÄð<_¼_—®½¬$õãÍ9¹¤?úí0ÄMè5\ïp¼O˜‹výƒôÓ?L»îq:”Fû`z>Ò¤l×O¾\.Šè0 ÝûÌé§—À¸Sã³ÎÙÙYĵ¿yó†b€´÷H7ŒÊ¶uìA¥‡^V¢ýÄôÑG¼š^: éúÖf9¶·ƒuQ’üšiR÷8‰;Ù®¿÷’>Ž4ž8ž*´zbùwü5Eß=Æ`†ÙÝݵ:øèÑ# ÒXãê‘£M*=.‰ÛñxÎɦ6ÖãG†t3îz•I굦¿þa’ºÇ‰ïdb?$nnýi$q'ãnkÚížvù5ûëå0îÔ¸C6X__7Æýòò’Ò€4÷tuBÿ/ã/XÊãŽqï ½ÊÌ'­VëÆ̰qŒû\1á~Üå}·¾}K€½úÆ0î÷ž¾|ùrb›;??_üþ½÷'×LLLfzòÓ—<úŒ;`Ü1îݹ¼¼ÜßßǸ31aÜ&lÜóùü—Jþàþàÿø1î©cÂ/§¦Û¸7_äü¶ uoa­²œ«ì¸ÉâKÚNõµ åØ2—«±¶ç-ßÙ.Qz5L9„ö¡¾&w8WXŽ6î(¼¨¦À—·›îÂWñ†$#ÙÆ`&Á¸‡¸ººÂ¸Ç³4¬Úþªå¥µœc¸Ý”{¥/îÛÍe³–L<’̃œåºþm€Ÿù‹m³V}m£ò"wíãýLâ› {hÏý{û ,»½°¹YŸ-và¹å®JsÏ<^> ÞÝñåÎá»-•¬Ç[ Œ;Æ} Æ=°}!séJe—=ìYIk.­SÔ„¾ŠØÐá3ß(µ­›73{%i²w¶K/jM׸»7/ö¢¶XÙú¸»U«t>Ñêp×L^ßì@ÜsÇ˧ݣ¯ì̈·òýwŒ;̶q7ÛP 6œzn]ñöŽÁu««¥õôë•ôüåð™‡svÍ«7Ó|±QXVÙ:ÆÝÞ0¨ÑÆ=ºÃjÜíQ´3ÓÞñ.çü§‘Ìk6ÜQZË…šÄ »-jÜ0îƒ÷¡ÕÌsæNC—Þ2µ1pûû¾·EwŒ{¦hµZgggw&&Œ;Æ=ÕPãÎÄ„qÀ¸ÏÒI¿}ûãÎÄ„qÀ¸cÜZ­ÖÿoŸÿdí)ÓÔ§›7+ÿo ”ÃÔ§ÂÚÓããc´ãÞ…£££õõuÊa¹wïž¼m£ã>LøåTÀ¸Hþâ/þâ ¤˜ÿüŸÿ3Æ=uLøåTÀ¸H–––>}út©äÇÒ»cÜ0îwŒ;ƽ¨qǸ`Üã>\]]QwŒ;`Ü©qŒ;@OÆ].üö÷þåç'%¦!§Å/–¥÷ƺ}ÿ³Ï~q~~r}Í4ëÓOžô ÷”ryy¹¿¿O9`Ü0îwŒ;ÆãžjNOO_¾|I9`Ü0îwŒ;ÆãžjŽŸ?N9`ÜfÀ¸× 7s…‡îŒš¾º-îÜ­éù½±ñU7”OŸSëŽ6Æ ã>Ï\]]Qw€ŒwK‚R>ܾ£,¾É'ÈM&X¹ºÐK"un÷7üºû&ÿz ü”Iû|CÜÞÓKìž·Û“vûìæ“1ãÞ¬ä •Zâ|ðë¶›íª©¹]ð–nÔ;n"4Õ7’—Ç'/ÿ„Ì1î÷ñÁË©w€Y6îŽkïZã¯Õ6K”ݺdï[íüwŒ;Æ0îL¼œÊ„qÏ8Ô¸cÜ0îwŒ;Æã>Ы Æ UÆýæíoýðý×LCNßYùÝq÷Z¥0©FÛ½töÒO[”¶½ÊÄø›îºÊøÚ ]8÷ì@?îsÅÇå­š™_YY¹¼¼4óµZ€4wHû^)Ò’[õ¯âùæx,¡Î[Ú¤ úlQ·¢ÇÎ^lb½z`܃ “6´q÷Òä*õí‚óþ¨ç›Më%{νJpß’ÔoL­—”Ár…𠬾q·E,¦ÚO݃ Æ=óœmmmQsUÑ.bÈû7J0îЫqOêxq¯¤}s§þXüw@{é³%±«–ØŠ®?öv Vcí¥‰¿ç?Šf¼;e ëûéž2Þ5Û§¤ûò«=ºxaöðôãž.//÷÷÷)‡ùáüü<âÚß¾}K±Æú©q¯o˜NʃNTTç-ž³lÛ‹ÓyK‡>[â]µtîì%Ø“°qï°‰!Œ»nšRÚ°5Üñ …±tLéV«;=ðô¡£‹t72î¡›Œ{†áåÔ9DÞªY×þøñc 0îÐww[‘´Öp.ö4á&éÓê¥Î/`ܳVéN!ÌëëëÆ¸óëÆèU†^e0îÔ¸CziµZ7nÜ888 (ãwŒ;Ƹ¼¼üߺõ«O™¦>=Ì?¡Ò0}ç·éÕ0î€qg¸cÜSWã~~~¾øý{ïO®™˜˜Ìôä§/yôwÀ¸3aÜ1iŒ;Æã.?¸?÷oþô|L³>}ëÛßþå/‰q§Æ}LƽùÂï¾UlÔ½…µÊr®²ã&‹/i;Õׂ”cÍ\M¯6ÄòvsdÆ®ížøÛícWC‡¿¶×מDs ²êýHëkª“ÛÂr´Çù‹Ú𥪠!ò½Úˆ÷n?’maÜ0î³Æ=½Õí“ìÆ»»qº@iàJ¯¼å¥µœc¸Ý”{¥/îÛ¯åœ7ÔÁÎH2r–ëú>ØO,ýŸ4Ä;ÛßFY;ÅÈG•fÇ–ͱ’î&œ=±)ÅFåEì ä·nžj>¾çÎáïÔê;¾1îƒL¹QZ Ö ¦³N¶ÑUÚWκØýòñÊÊÛ=eÙ#7î¡…î‹To·…èo— ÞÝñåáBj[ºÞŒ;ÆãŽq9fäÔÓÓÓkÝÓÈ‘æêêÊ|%ç#_ÉùQ.”ó2œ—‰ã_™æ7———æ+³­ãããÃÃÃß^ü~'£‡H0XÊËznϳVÖlí…†" }±eÃg¾QêP7ñ|Ê}Z 1ý®íóçƒUw>|7òbÏ_î$xµáŽÌ3^,Ñÿîaœ"JÜšcÜ#«´ÿ]”õ»[•­\1¡:Ü-ØÀëG·»]‰ÜÅŸ!x?ºñ¶z|ö‚qŒ;`Ü1î)­àïÖT&äÛ^m„,¯®ˆ {©Àð¹Õ·ÒŠùõ©ÆZžrÈÌÃ9»f.é®`m£àzbײ{®.¸g°9·Ùy›¿Z˜lÜuƒ–’œ^%‹{øªb;¨_ìCãÙÆ=¾ jâ5îöÀÛ™io?—ÛfÂwx¼#‹+Ô$fØmQã€qÀ¸cÜçÆ¸ßø;õ™3 ‘ºï¶{û¥^m·ãÞmÜ0îwŒ;Ɖ‰^e0î€qŒ;Æããáø7×_¾Ù~4ÏÓÿüׇ¿ûýÏ0î³fÜ›•B¡ÒTsõ’73Øêí—`Ü™˜0îwH“qÿæíÁœ þ_ÿâã>»Æ]þczæÐž»îwOQªûiJ%• T©Ú|å.IÊ$¼Mál͵úî}D»}¨èÐ[­ÖÿoŸÿdí)ÓÔ§öÏÿyþß(‡©O…µ§¦ƒ&Œ;`Ü1î÷×¸Ç ·õÖgí|£?zN:¸ÿÄ3±È¯|ïmg½Ú~¹®ÿ¹Ó>@æ¸wïÞ$ÍÀ¸cÜ;u‘Üï°3^â®c vÇ°ç± û¸ãža㮼x0§Œ´ëécm»YNÏ$Tßns±f\Z÷R©à'ì°€qÀ¸Ã${|¾ëÂðØ‚¡MtX°ãpõ5¿5Â‹ÈøƒÑ1»ÿ‡qŸMã€qŒ;Æã>|{»±ãÆ½Ãø$=ã˜8þ ;ša·áÿ0îwŒ;`Ü!»5î]½´[°wãÞu¸@ó1>þ`|ÀÄnÃÿaÜ1îwÀ¸/§òr*Æã€qŒ;Æã€qŒ;`Ü1îwŒ;Æ0î€qǸcÜ0îwèø‡ø>ÌJØcÜ0îwŒ;ÆãwÀ¸`Ü0îwŒ;Æ0î€qǸ`ÜãwŒ;Æ:óþŸÿ{¡ðˆé?þÇÿ'Æãл»»­VKο~ýúêêJÎÉy 0î0>~ö³Ÿîîþèââëyž>}zv÷îï`Ü1î½²¾¾.b\^^R2€qŒ;Æã"Z­Ö7\×~pp@±Æ0îwŒ;@êøøñ£uí›››`Ü!]ƽñ ŸÐè<_]f>qáųr^äËÏt†«E±Pnô¼EŒ;Æ U¼~ýZºöÅÅEÓÞãé2îî£áŒ»œ)®vÜJàæå‘_ÈGs“ –ª¡¬ô’ÈGŒ;Æ`¬¬¬S€q‡™¬qï\YÞµ=’À~”¾Ü³ãázzÿ^¢XMúˆqǸÃ`ý‹ï}çwKŸ31 ?ÝzzïÅŸý{N+Œ;̘q÷œ·_eïµ™iW¯¿T U´K¾Tô}yµªû|ĸcÜa(ãþÝÕ|~Rbb~º÷ö)Æã¼œJwŒ;`Ü™0îwÀ¸cÜ1îwŒ»;Õ 7s…‡jþ«ÛÞL?S°zû%]¦Í»9ÿÉÚÆW£ÈÖ=ñeä|{o"^9´“_Ý–ÎݹíwþÎÝÆãwŒ;ƲlÜ}j¬áÞJÈìª4+·U‚•»ÛwÚ|å.IÊ$ìÔ=³uÌÒ®Üï7[ù•·H®ëÈø2·¥§‡µ¯Ö"‡#Sjí»úÍíMµ¢_˜æc8q¬¸¼Ì•eÜ*È|¼NJ÷7„W‡#Í}ä`㇩’…ï[âK0îwög›¿÷{ß)îÎóôùç¿û{¿wãŽq‡žkÜãæÕzJ×FÖ7¦¾Ëôì£IËD™Ô¸”ÉB¶Þñ»½eÛ©ú||™GsŽWŠ»Æ=VtÖ.û™H·íXsoÇD|Ӫ̕¬y̸G~8O•,~˜NV!ßßf Æã0·`Ü!eÆÝ3ˆñº^Çk*ógM°©ŽùÅH&‰5î'!*=bPÞk¶_ݶíCL=qÈ=)s7gUT™ÛJ}5îÊ‹;NýæÆŠÿào%¹ÅNìWðÊ?¨•w/Û¹ðž¸ùD–Pã€qŒ;Ì€qŸ•©ï¦ó©É| “_ß?ÎCø`Ü0îwÀ¸3Ñ« Æ0îwŒ;¦“ ã€qŒ;`Ü™0î€qÀ¸cÜaÞ`T\^^rNŒœ³³3ä ÍœŸŸcÜã€qŒ;`Ü0î€qÀ¸Æ0îwÀ¸Æãwøÿ²‰‰°B¤=IEND®B`‚hppc-0.7.2/hppc/src/main/javadoc/resources/logo.png000066400000000000000000000057601300364116400222140ustar00rootroot00000000000000‰PNG  IHDRR#ˆ0ʨ cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅF pHYs  šœ vIDAThÞÝX{\“õ'=z¼qÊ2Ëò.IŠQ~ù('Qϱ¼¥’œN)–SÍ¥d’á% è –š°4ä>‘;ã>6váÎØÆÆÆ6Øön{ßwŒßy쥹¡Ñ±?Âç}žÏó>ïo¿ïs^'ô{Pvv¶··wll,!äôðGtww;ýBŸ|ò‰í£+W¯½ñúÆÀ½ï=‚°Y,–“ …‡‡SòZV½Ÿ×+È"OŒ Þ·ÿÃG 6Ðøñã‘§gåDìÿ'0Ææ2Ÿµk5Øo¿ý¶ðèQ£&Où 0QQ‘ðhóë½àùò¢&ë‘‚íïïoëç÷?P"6Å~ò$(TÕ0ÕZÝ#•ÛVÌ£„=jô¨§§=eµBddä£VÉwíÚEaÓ´"¤ôY¹Ôi(²«í#v@@…êÅù³)Iò¹+T¹œîé¹èŒüÿ½}Ç[~úAÞOߌó'«$""ðé§Ÿ°Õ¹|ùòȆ½ÆgÓðhì˜1VÞÍÍm$ÁæòZ2³ón¥çrù-¦¾^kö¬Ax-)/#å BRb”TâB\jè,&D%&q¹YZ9 «FHžõ]Œvrrò€ý㌞ÞÏ=7Õí…çW{¹ýu…›ë‚ç§<õDп¶ ÔŒuˆlF²È¢B¤¨FªšžJ¤Z´&ëû/–¼ìÑoA7oÞ,**ú£ç6‹Å{fêô×¼æÓÏôá%ñjAH„õÕ#Ä'Uù²…Ì;‰§ì×'ûã)ûŒšQ^ KpQ±A U½#%îøô³GÌ*òÕ™§Çœ² bjì734ÊÛŠnºB^ Óqy¡‰à›LFÔe’”é¡}f•IÉ5·Ðñ›‡ÌX+ÙQLŠJÁ:?$„͘9gÄl`W/§Œuvê($Pµ@•Ñ…W«û…Œ¯ô*Ju¬ûŽL;Bf7\x“”1Œ ²ô+œö’²2£0w¦&DLŸ9ýái¶ U…§Õt[Ž<}ž õ¼"i§.|:¿CCé9âÆ!RZnî*7‹ŠH¼ž´-¹$=Š$ÚŒ]ÅàgÚ·ÃŒmN§P((Þd2Ý]WŒÆ®®.J %ìééÑh4À€²L&#x¥RI©‘$)•JéëëƒW´Z­õ4 •J¥V«±X,‰d``Àl6Soýö‹ ^J*ˆV#&‡Ì—ZÄÕÝØ‘Ç5!ã±½Nxe¼Î,&~اë“hE¸²ÌˆÕµ,’õYt†¸Hj¹`·?}~º=掎f'„\.W$Áu CI TÔÚÚ*‹Üø––ÜÜÜÜØØú¯ººš‚äííM! `TB¡N£ŒRYYI=­¯¯9u<£r>Ÿ?;Ÿ^¼xÅ\#jf“wD¨ƒ¼° ™ˆ}<Àëø´$ÅçñÚ‹ ME¯$“æáÝEf-¿²Ç(-%1BbZÒ1GÌ@wîÜÙºu«î æ§xÀSQQ ÜŒÇãuwwC À;;;£ôþLà+À@½âããC…˜©­­ xÄáp¨§` 8Šú 8á4°õ,ØÐÐPSS3ûïë6}“Ѫù¨ÉP‡š {V_‘ D²æþJ¹¡ÖD R¸*yŽJFï•Ð5]tRÃ3æŸ6õ‰Á¬·®6sæÜ!ƒ¹¬¬lïÞ½vB ÃÀ«ýýýàíÚÚZ&“ 1 †¨««¨à‚`¿$™ÖÛ¯]»–‚ ‘àÁvT.ªªª*0ûg‚XkRÁßÔÔ¤×ë!ÐaÏš3³Á˜Ë7HÌMÄçîXˆ3žÖŽä,½Ñ\®¯N40¾–áU Y–Jž­ThúDDéy²2Ñh€Û<Ü]ÚÒûÁ t”ƒàï?•á™Ô½©ü¤²Çq*È©„„Ô#___*iáW.—SÊà[0DTE€˜‚ì8“Š* ÀLwa âçæNU!6»¯¼W£?<|Anlᘠ¸ºL¡©ÞœÔe`¶«Ò$Ú"•©ÑÐA'~:‚§‡êÕ,½æÑî·üJʪ~ìû…\nfffaaát6lØ¿àOPKOO§?˜`^ÊÊÊ¢ül2ÉP›ÜE2q¬@ØœâöÒ¢û]ý7Á†N¶{÷nð[TTD#¼Hå¡Ù60[Z²d Ô9ÇÐ8räÈаoý˜±Èw‘ Ëú+dºzãñÙÚ&ѯhZ3D¨³‰Ú´ ‰ EgôÇfhO"7ËÚ;T™°ŸúFF}ùð°SSSçÏŸúÐ~ A:;;S£Å0a¯ZµŠšUí $<:qâ„í[ƒÃéÜs“8—§ñ{…tcø,íá‰úЩøYoüêì9sì—¶Í›7ÃÈ5|Ø«W¯¦z²#Á\”eïÀ÷À®eÔ:uâ UU ~·†eLÚ‰ü 4;0ûp4< ?>Ï´sÍ%ídžqç¸N¹v…öð°³³³ýýýã³¼¼ÜQÙÏÏÏ1·–-[F­ °°°-[¶Ü³xžŠ<õ¤Ëdjã &£¿ª‰º ]íEìN”¾0ZËK‘8MHÀ2æ‹QI?j^îëúææ·ü7Ä}ÕN¸mÛ6ˆö!a;ƒ léҥà +èííí÷|fù dÜ”?gÈnAž³£ÊR^‡êYˆÇB\¶¥ •¶þ5ñ·gº>õ7ß7~õ?JKK‡: *vBWWWXH•gÍšÓµðìÙ³àÉáÀ†Æ;ûJi)éÎΓֿ¿>CzSŒx*Ô¤A 0ÌhWXu½?í ß:ÁyBìéøáüÀþU5Z[ $ãÆƒÚ>dØ´i“­æS(‡Ô:mK;vì¸~ýºÐÝÝ’¡?!ž9qÆÝ}É‚—]¼6-[à½~תÕÛ<Ý–º,\¸ðØÑO‘e¸½:'\èÒ¥K_Û Uà¡l5cbb`>% ¦ÈÄÄDH»a3y÷ÝwÁÛùt:v•øøxh]C6PØ!S`ó…þš°Ã$›””ô+Œ{d=Ùi¹çcâÎ}y>–.É~ëÈ4'''###݆ÒÒÒh4,žvÊPÀ`x>zô(ƒÁ FKÇqÒ’ú >uê ç.\x𠼃­Aʇuiÿ/l÷0$pNIEND®B`‚hppc-0.7.2/hppc/src/main/javadoc/resources/overview.css000066400000000000000000000025741300364116400231260ustar00rootroot00000000000000.header ul li, .footer ul li { list-style: disc; font-size: 1em; } table.nice a, table.nice a:link, table.nice a:visited { border: none; } img { border: 0; margin-top: .5em; } table.nice { margin: 1em auto; border-collapse: collapse; } caption { color: #9ba9b4; font-size: .94em; letter-spacing: .1em; margin: 1em 0 0 0; padding: 0; caption-side: top; text-align: center; } table.nice tr.odd td { background: #f0f0f5; } table.nice tr.odd .column1 { background: #f0f0f5; font-weight: bold; } table.nice tr .column1 { background: #f9fcfe; font-weight: bold; } table.nice td { color: #526678; border: 1px solid #cfe4f8; padding: .3em 1em; text-align: center; } table.nice th { border: 1px solid #cfe4f8; font-weight: normal; color: #526678; text-align: left; padding: .3em 1em; } table.nice thead th { background: #e8e8f0; text-align: center; font: bold 1.2em/ 2em Arial, Helvetica, sans-serif; color: #66a3d3 } table.nice tfoot th { text-align: center; background: #f4f9fe; } table.nice tfoot th strong { font: bold 1.2em Arial, Helvetica, sans-serif; margin: .5em .5em .5em 0; color: #66a3d3; } table.nice tfoot th em { color: #f03b58; font-weight: bold; font-size: 1.1em; font-style: normal; } table.nice thead th.empty { border-top: none; border-left: none; background: white; } .red { color: red; } .nobr { white-space: nowrap; }hppc-0.7.2/hppc/src/main/javadoc/resources/tweaks.css000066400000000000000000000005011300364116400225420ustar00rootroot00000000000000 a.logo { float: right; padding-left: 10px; position: relative; width: 82px; height: 35px; background: url('logo.png'); background-repeat: no-repeat; background-position: right top; } /* Page background color */ body { font-family: Trebuchet MS, Arial; background-color: white; font-size: 10pt; } hppc-0.7.2/hppc/src/main/templates/000077500000000000000000000000001300364116400171135ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/000077500000000000000000000000001300364116400176715ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/000077500000000000000000000000001300364116400223515ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/000077500000000000000000000000001300364116400233035ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/AbstractKTypeCollection.java000066400000000000000000000055141300364116400307070ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Arrays; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; /** * Common superclass for collections. */ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @SuppressWarnings("unchecked") /*! #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ abstract class AbstractKTypeCollection implements /*! #if ($templateonly) !*/ Intrinsics.EqualityFunction, /*! #end !*/ KTypeCollection { /** * Default implementation uses a predicate for removal. */ @Override public int removeAll(final KTypeLookupContainer c) { // We know c holds sub-types of KType and we're not modifying c, so go unchecked. return this.removeAll(new KTypePredicate() { public boolean apply(KType k) { return c.contains(k); } }); } /** * Default implementation uses a predicate for retaining. */ @Override public int retainAll(final KTypeLookupContainer c) { // We know c holds sub-types of KType and we're not modifying c, so go unchecked. return this.removeAll(new KTypePredicate() { public boolean apply(KType k) { return !c.contains(k); } }); } /** * Default implementation redirects to {@link #removeAll(KTypePredicate)} and * negates the predicate. */ @Override public int retainAll(final KTypePredicate predicate) { return removeAll(new KTypePredicate() { public boolean apply(KType value) { return !predicate.apply(value); }; }); } /** * Default implementation of copying to an array. */ @Override /*!#if ($TemplateOptions.KTypePrimitive) public KType [] toArray() #else !*/ public Object[] toArray() /*! #end !*/ { KType[] array = Intrinsics. newArray(size()); int i = 0; for (KTypeCursor c : this) { array[i++] = c.value; } return array; } /*!#if ($TemplateOptions.KTypeGeneric) !*/ public T [] toArray(Class componentClass) { final int size = size(); final T[] array = (T[]) java.lang.reflect.Array.newInstance(componentClass, size); int i = 0; for (KTypeCursor c : this) { array[i++] = (T) c.value; } return array; } /*! #end !*/ /** * Convert the contents of this container to a human-friendly string. */ @Override public String toString() { return Arrays.toString(this.toArray()); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ /*! #if ($templateonly) !*/ @Override public /*! #else protected #end !*/ boolean equals(Object v1, Object v2) { return (v1 == v2) || (v1 != null && v1.equals(v2)); } /*! #end !*/ } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeArrayDeque.java000066400000000000000000000570401300364116400271730ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.*; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.KTypeProcedure; import static com.carrotsearch.hppc.Containers.*; /** * An array-backed {@link KTypeDeque}. */ /*! #if ($TemplateOptions.KTypeGeneric) @SuppressWarnings("unchecked") #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeArrayDeque extends AbstractKTypeCollection implements KTypeDeque, Preallocable, Cloneable { /** * Internal array for storing elements of the deque. */ public /*! #if ($TemplateOptions.KTypePrimitive) KType [] #else !*/ Object [] /*! #end !*/ buffer = KTypeArrayList.EMPTY_ARRAY; /** * The index of the element at the head of the deque or an arbitrary number * equal to tail if the deque is empty. */ public int head; /** * The index at which the next element would be added to the tail of the * deque. */ public int tail; /** * Buffer resizing strategy. */ protected final ArraySizingStrategy resizer; /** * New instance with sane defaults. */ public KTypeArrayDeque() { this(DEFAULT_EXPECTED_ELEMENTS); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). */ public KTypeArrayDeque(int expectedElements) { this(expectedElements, new BoundedProportionalArraySizingStrategy()); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). * * @param resizer * Underlying buffer sizing strategy. */ public KTypeArrayDeque(int expectedElements, ArraySizingStrategy resizer) { assert resizer != null; this.resizer = resizer; ensureCapacity(expectedElements); } /** * Creates a new deque from elements of another container, appending elements at * the end of the deque in the iteration order. */ public KTypeArrayDeque(KTypeContainer container) { this(container.size()); addLast(container); } /** * {@inheritDoc} */ @Override public void addFirst(KType e1) { int h = oneLeft(head, buffer.length); if (h == tail) { ensureBufferSpace(1); h = oneLeft(head, buffer.length); } buffer[head = h] = e1; } /** * Vararg-signature method for adding elements at the front of this deque. * *

This method is handy, but costly if used in tight loops (anonymous * array passing)

* * @param elements The elements to add. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public final void addFirst(KType... elements) { ensureBufferSpace(elements.length); for (KType k : elements) { addFirst(k); } } /** * Inserts all elements from the given container to the front of this deque. * * @param container The container to iterate over. * * @return Returns the number of elements actually added as a result of this * call. */ public int addFirst(KTypeContainer container) { int size = container.size(); ensureBufferSpace(size); for (KTypeCursor cursor : container) { addFirst(cursor.value); } return size; } /** * Inserts all elements from the given iterable to the front of this deque. * * @param iterable The iterable to iterate over. * * @return Returns the number of elements actually added as a result of this * call. */ public int addFirst(Iterable> iterable) { int size = 0; for (KTypeCursor cursor : iterable) { addFirst(cursor.value); size++; } return size; } /** * {@inheritDoc} */ @Override public void addLast(KType e1) { int t = oneRight(tail, buffer.length); if (head == t) { ensureBufferSpace(1); t = oneRight(tail, buffer.length); } buffer[tail] = e1; tail = t; } /** * Vararg-signature method for adding elements at the end of this deque. * *

* This method is handy, but costly if used in tight loops (anonymous array * passing) *

* * @param elements The elements to iterate over. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public final void addLast(KType... elements) { ensureBufferSpace(1); for (KType k : elements) { addLast(k); } } /** * Inserts all elements from the given container to the end of this deque. * * @param container The container to iterate over. * * @return Returns the number of elements actually added as a result of this * call. */ public int addLast(KTypeContainer container) { int size = container.size(); ensureBufferSpace(size); for (KTypeCursor cursor : container) { addLast(cursor.value); } return size; } /** * Inserts all elements from the given iterable to the end of this deque. * * @param iterable The iterable to iterate over. * * @return Returns the number of elements actually added as a result of this * call. */ public int addLast(Iterable> iterable) { int size = 0; for (KTypeCursor cursor : iterable) { addLast(cursor.value); size++; } return size; } /** * {@inheritDoc} */ @Override public KType removeFirst() { assert size() > 0 : "The deque is empty."; final KType result = Intrinsics. cast(buffer[head]); buffer[head] = Intrinsics.empty(); head = oneRight(head, buffer.length); return result; } /** * {@inheritDoc} */ @Override public KType removeLast() { assert size() > 0 : "The deque is empty."; tail = oneLeft(tail, buffer.length); final KType result = Intrinsics. cast(buffer[tail]); buffer[tail] = Intrinsics.empty(); return result; } /** * {@inheritDoc} */ @Override public KType getFirst() { assert size() > 0 : "The deque is empty."; return Intrinsics. cast(buffer[head]); } /** * {@inheritDoc} */ @Override public KType getLast() { assert size() > 0 : "The deque is empty."; return Intrinsics. cast(buffer[oneLeft(tail, buffer.length)]); } /** * {@inheritDoc} */ @Override public int removeFirst(KType e1) { final int index = bufferIndexOf(e1); if (index >= 0) removeAtBufferIndex(index); return index; } /** * Return the index of the first (counting from head) element equal to * e1. The index points to the {@link #buffer} array. * * @param e1 * The element to look for. * @return Returns the index of the first element equal to e1 or * -1 if not found. */ public int bufferIndexOf(KType e1) { final int last = tail; final int bufLen = buffer.length; for (int i = head; i != last; i = oneRight(i, bufLen)) { if (Intrinsics.equals(this, e1, buffer[i])) { return i; } } return -1; } /** * {@inheritDoc} */ @Override public int removeLast(KType e1) { final int index = lastBufferIndexOf(e1); if (index >= 0) { removeAtBufferIndex(index); } return index; } /** * Return the index of the last (counting from tail) element equal to * e1. The index points to the {@link #buffer} array. * * @param e1 * The element to look for. * @return Returns the index of the first element equal to e1 or * -1 if not found. */ public int lastBufferIndexOf(KType e1) { final int bufLen = buffer.length; final int last = oneLeft(head, bufLen); for (int i = oneLeft(tail, bufLen); i != last; i = oneLeft(i, bufLen)) { if (Intrinsics.equals(this, e1, buffer[i])) return i; } return -1; } /** * {@inheritDoc} */ @Override public int removeAll(KType e1) { int removed = 0; final int last = tail; final int bufLen = buffer.length; int from, to; for (from = to = head; from != last; from = oneRight(from, bufLen)) { if (Intrinsics.equals(this, e1, buffer[from])) { buffer[from] = Intrinsics.empty(); removed++; continue; } if (to != from) { buffer[to] = buffer[from]; buffer[from] = Intrinsics.empty(); } to = oneRight(to, bufLen); } tail = to; return removed; } /** * Removes the element at index in the internal {#link * {@link #buffer} array, returning its value. * * @param index * Index of the element to remove. The index must be located between * {@link #head} and {@link #tail} in modulo {@link #buffer} * arithmetic. */ public void removeAtBufferIndex(int index) { assert (head <= tail ? index >= head && index < tail : index >= head || index < tail) : "Index out of range (head=" + head + ", tail=" + tail + ", index=" + index + ")."; // Cache fields in locals (hopefully moved to registers). final KType [] buffer = Intrinsics. cast(this.buffer); final int bufLen = buffer.length; final int lastIndex = bufLen - 1; final int head = this.head; final int tail = this.tail; final int leftChunk = Math.abs(index - head) % bufLen; final int rightChunk = Math.abs(tail - index) % bufLen; if (leftChunk < rightChunk) { if (index >= head) { System.arraycopy(buffer, head, buffer, head + 1, leftChunk); } else { System.arraycopy(buffer, 0, buffer, 1, index); buffer[0] = buffer[lastIndex]; System.arraycopy(buffer, head, buffer, head + 1, lastIndex - head); } buffer[head] = Intrinsics.empty(); this.head = oneRight(head, bufLen); } else { if (index < tail) { System.arraycopy(buffer, index + 1, buffer, index, rightChunk); } else { System.arraycopy(buffer, index + 1, buffer, index, lastIndex - index); buffer[lastIndex] = buffer[0]; System.arraycopy(buffer, 1, buffer, 0, tail); } buffer[tail] = Intrinsics.empty(); this.tail = oneLeft(tail, bufLen); } } /** * {@inheritDoc} */ @Override public boolean isEmpty() { return size() == 0; } /** * {@inheritDoc} */ @Override public int size() { if (head <= tail) return tail - head; else return (tail - head + buffer.length); } /** * {@inheritDoc} * *

* The internal array buffers are not released as a result of this call. *

* * @see #release() */ @Override public void clear() { if (head < tail) { Arrays.fill(buffer, head, tail, Intrinsics.empty()); } else { Arrays.fill(buffer, 0, tail, Intrinsics.empty()); Arrays.fill(buffer, head, buffer.length, Intrinsics.empty()); } this.head = tail = 0; } /** * Release internal buffers of this deque and reallocate with the default * buffer. */ public void release() { this.head = tail = 0; buffer = KTypeArrayList.EMPTY_ARRAY; ensureBufferSpace(0); } /** * Ensure this container can hold at least the given number of elements * without resizing its buffers. * * @param expectedElements * The total number of elements, inclusive. */ @Override public void ensureCapacity(int expectedElements) { ensureBufferSpace(expectedElements - size()); } /** * Ensures the internal buffer has enough free slots to store * expectedAdditions. Increases internal buffer size if needed. */ protected void ensureBufferSpace(int expectedAdditions) { final int bufferLen = buffer.length; final int elementsCount = size(); if (elementsCount + expectedAdditions >= bufferLen) { final int emptySlot = 1; // deque invariant: always an empty slot. final int newSize = resizer.grow(bufferLen, elementsCount + emptySlot, expectedAdditions); assert newSize >= (elementsCount + expectedAdditions + emptySlot) : "Resizer failed to" + " return sensible new size: " + newSize + " <= " + (elementsCount + expectedAdditions); try { final KType[] newBuffer = Intrinsics. newArray(newSize); if (bufferLen > 0) { toArray(newBuffer); tail = elementsCount; head = 0; } this.buffer = newBuffer; } catch (OutOfMemoryError e) { throw new BufferAllocationException( "Not enough memory to allocate new buffers: %,d -> %,d", e, bufferLen, newSize); } } } /** * {@inheritDoc} */ @Override /*! #if ($TemplateOptions.KTypePrimitive) public KType [] toArray() #else !*/ public Object [] toArray() /*! #end !*/ { final int size = size(); return toArray(Intrinsics. newArray(size)); } /** * Copies elements of this deque to an array. The content of the * target array is filled from index 0 (head of the queue) to * index size() - 1 (tail of the queue). * * @param target * The target array must be large enough to hold all elements. * @return Returns the target argument for chaining. */ public KType[] toArray(KType[] target) { assert target.length >= size() : "Target array must be >= " + size(); if (head < tail) { // The contents is not wrapped around. Just copy. System.arraycopy(buffer, head, target, 0, size()); } else if (head > tail) { // The contents is split. Merge elements from the following indexes: // [head...buffer.length - 1][0, tail - 1] final int rightCount = buffer.length - head; System.arraycopy(buffer, head, target, 0, rightCount); System.arraycopy(buffer, 0, target, rightCount, tail); } return target; } /** * Clone this object. The returned clone will reuse the same hash function and * array resizing strategy. */ @Override public KTypeArrayDeque clone() { try { /* #if ($templateOnly) */ @SuppressWarnings("unchecked") /* #end */ KTypeArrayDeque cloned = (KTypeArrayDeque) super.clone(); cloned.buffer = buffer.clone(); return cloned; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } /** * Move one index to the left, wrapping around buffer. */ protected static int oneLeft(int index, int modulus) { if (index >= 1) { return index - 1; } return modulus - 1; } /** * Move one index to the right, wrapping around buffer. */ protected static int oneRight(int index, int modulus) { if (index + 1 == modulus) { return 0; } return index + 1; } /** * An iterator implementation for {@link ObjectArrayDeque#iterator}. */ private final class ValueIterator extends AbstractIterator> { private final KTypeCursor cursor; private int remaining; public ValueIterator() { cursor = new KTypeCursor(); cursor.index = oneLeft(head, buffer.length); this.remaining = size(); } @Override protected KTypeCursor fetch() { if (remaining == 0) { return done(); } remaining--; cursor.value = Intrinsics. cast(buffer[cursor.index = oneRight(cursor.index, buffer.length)]); return cursor; } } /** * An iterator implementation for * {@link ObjectArrayDeque#descendingIterator()}. */ private final class DescendingValueIterator extends AbstractIterator> { private final KTypeCursor cursor; private int remaining; public DescendingValueIterator() { cursor = new KTypeCursor(); cursor.index = tail; this.remaining = size(); } @Override protected KTypeCursor fetch() { if (remaining == 0) return done(); remaining--; cursor.value = Intrinsics. cast(buffer[cursor.index = oneLeft(cursor.index, buffer.length)]); return cursor; } } /** * Returns a cursor over the values of this deque (in head to tail order). The * iterator is implemented as a cursor and it returns the same cursor * instance on every call to {@link Iterator#next()} (to avoid boxing of * primitive types). To read the current value (or index in the deque's * buffer) use the cursor's public fields. An example is shown below. * *
   * for (IntValueCursor c : intDeque) {
   *   System.out.println("buffer index=" + c.index + " value=" + c.value);
   * }
   * 
*/ public Iterator> iterator() { return new ValueIterator(); } /** * Returns a cursor over the values of this deque (in tail to head order). The * iterator is implemented as a cursor and it returns the same cursor * instance on every call to {@link Iterator#next()} (to avoid boxing of * primitive types). To read the current value (or index in the deque's * buffer) use the cursor's public fields. An example is shown below. * *
   * for (Iterator<IntCursor> i = intDeque.descendingIterator(); i.hasNext();) {
   *   final IntCursor c = i.next();
   *   System.out.println("buffer index=" + c.index + " value=" + c.value);
   * }
   * 
*/ public Iterator> descendingIterator() { return new DescendingValueIterator(); } /** * {@inheritDoc} */ @Override public > T forEach(T procedure) { forEach(procedure, head, tail); return procedure; } /** * Applies procedure to a slice of the deque, * fromIndex, inclusive, to toIndex, exclusive. */ private void forEach(KTypeProcedure procedure, int fromIndex, final int toIndex) { final KType[] buffer = Intrinsics. cast(this.buffer); for (int i = fromIndex; i != toIndex; i = oneRight(i, buffer.length)) { procedure.apply(buffer[i]); } } /** * {@inheritDoc} */ @Override public > T forEach(T predicate) { int fromIndex = head; int toIndex = tail; final KType[] buffer = Intrinsics. cast(this.buffer); for (int i = fromIndex; i != toIndex; i = oneRight(i, buffer.length)) { if (!predicate.apply(buffer[i])) { break; } } return predicate; } /** * Applies procedure to all elements of this deque, tail to head. */ @Override public > T descendingForEach(T procedure) { descendingForEach(procedure, head, tail); return procedure; } /** * Applies procedure to a slice of the deque, * toIndex, exclusive, down to fromIndex, inclusive. */ private void descendingForEach(KTypeProcedure procedure, int fromIndex, final int toIndex) { if (fromIndex == toIndex) return; final KType[] buffer = Intrinsics. cast(this.buffer); int i = toIndex; do { i = oneLeft(i, buffer.length); procedure.apply(buffer[i]); } while (i != fromIndex); } /** * {@inheritDoc} */ @Override public > T descendingForEach(T predicate) { descendingForEach(predicate, head, tail); return predicate; } /** * Applies predicate to a slice of the deque, * toIndex, exclusive, down to fromIndex, inclusive * or until the predicate returns false. */ private void descendingForEach(KTypePredicate predicate, int fromIndex, final int toIndex) { if (fromIndex == toIndex) return; final KType[] buffer = Intrinsics. cast(this.buffer); int i = toIndex; do { i = oneLeft(i, buffer.length); if (!predicate.apply(buffer[i])) { break; } } while (i != fromIndex); } /** * {@inheritDoc} */ @Override public int removeAll(KTypePredicate predicate) { final KType[] buffer = Intrinsics. cast(this.buffer); final int last = tail; final int bufLen = buffer.length; int removed = 0; int from, to; from = to = head; try { for (from = to = head; from != last; from = oneRight(from, bufLen)) { if (predicate.apply(buffer[from])) { buffer[from] = Intrinsics.empty(); removed++; continue; } if (to != from) { buffer[to] = buffer[from]; buffer[from] = Intrinsics.empty(); } to = oneRight(to, bufLen); } } finally { // Keep the deque in consistent state even if the predicate throws an exception. for (; from != last; from = oneRight(from, bufLen)) { if (to != from) { buffer[to] = buffer[from]; buffer[from] = Intrinsics.empty(); } to = oneRight(to, bufLen); } tail = to; } return removed; } /** * {@inheritDoc} */ @Override public boolean contains(KType e) { int fromIndex = head; int toIndex = tail; final KType[] buffer = Intrinsics. cast(this.buffer); for (int i = fromIndex; i != toIndex; i = oneRight(i, buffer.length)) { if (Intrinsics.equals(this, e, buffer[i])) { return true; } } return false; } /** * {@inheritDoc} */ @Override public int hashCode() { int h = 1; int fromIndex = head; int toIndex = tail; final KType[] buffer = Intrinsics. cast(this.buffer); for (int i = fromIndex; i != toIndex; i = oneRight(i, buffer.length)) { h = 31 * h + BitMixer.mix(this.buffer[i]); } return h; } /** * Returns true only if the other object is an instance of * the same class and with the same elements. #if ($TemplateOptions.KTypeGeneric) * Equality comparison is performed with this object's {@link #equals(Object, Object)} * method. #end */ @Override public boolean equals(Object obj) { return obj != null && getClass() == obj.getClass() && equalElements(getClass().cast(obj)); } /** * Compare order-aligned elements against another {@link KTypeDeque}. #if ($TemplateOptions.KTypeGeneric) * Equality comparison is performed with this object's {@link #equals(Object, Object)} * method. #end */ protected boolean equalElements(KTypeArrayDeque other) { int max = size(); if (other.size() != max) { return false; } Iterator> i1 = this.iterator(); Iterator> i2 = other.iterator(); while (i1.hasNext() && i2.hasNext()) { if (!Intrinsics.equals(this, i1.next().value, i2.next().value)) { return false; } } return !i1.hasNext() && !i2.hasNext(); } /** * Create a new deque by pushing a variable number of arguments to the end of it. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public static KTypeArrayDeque from(KType... elements) { final KTypeArrayDeque coll = new KTypeArrayDeque(elements.length); coll.addLast(elements); return coll; } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeArrayList.java000066400000000000000000000412051300364116400270370ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.*; import com.carrotsearch.hppc.cursors.*; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.*; import static com.carrotsearch.hppc.Containers.*; /** * An array-backed list of KTypes. */ /*! #if ($TemplateOptions.KTypeGeneric) @SuppressWarnings("unchecked") #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeArrayList extends AbstractKTypeCollection implements KTypeIndexedContainer, Preallocable, Cloneable { /** * An immutable empty buffer (array). */ public final static /*! #if ($TemplateOptions.KTypePrimitive) KType [] #else !*/ Object [] /*! #end !*/ EMPTY_ARRAY = /*! #if ($TemplateOptions.KTypePrimitive) new KType [0]; #else !*/ new Object [0]; /*! #end !*/; /** * Internal array for storing the list. The array may be larger than the current size * ({@link #size()}). */ public /*! #if ($TemplateOptions.KTypePrimitive) KType [] #else !*/ Object [] /*! #end !*/ buffer = EMPTY_ARRAY; /** * Current number of elements stored in {@link #buffer}. */ public int elementsCount; /** * Buffer resizing strategy. */ protected final ArraySizingStrategy resizer; /** * New instance with sane defaults. */ public KTypeArrayList() { this(DEFAULT_EXPECTED_ELEMENTS); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). */ public KTypeArrayList(int expectedElements) { this(expectedElements, new BoundedProportionalArraySizingStrategy()); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). * * @param resizer * Underlying buffer sizing strategy. */ public KTypeArrayList(int expectedElements, ArraySizingStrategy resizer) { assert resizer != null; this.resizer = resizer; ensureCapacity(expectedElements); } /** * Creates a new list from the elements of another container in its * iteration order. */ public KTypeArrayList(KTypeContainer container) { this(container.size()); addAll(container); } /** * {@inheritDoc} */ @Override public void add(KType e1) { ensureBufferSpace(1); buffer[elementsCount++] = e1; } /** * Appends two elements at the end of the list. To add more than two elements, * use add (vararg-version) or access the buffer directly (tight * loop). */ public void add(KType e1, KType e2) { ensureBufferSpace(2); buffer[elementsCount++] = e1; buffer[elementsCount++] = e2; } /** * Add all elements from a range of given array to the list. */ public void add(KType[] elements, int start, int length) { assert length >= 0 : "Length must be >= 0"; ensureBufferSpace(length); System.arraycopy(elements, start, buffer, elementsCount, length); elementsCount += length; } /** * Vararg-signature method for adding elements at the end of the list. *

* This method is handy, but costly if used in tight loops (anonymous array * passing) *

*/ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public final void add(KType... elements) { add(elements, 0, elements.length); } /** * Adds all elements from another container. */ public int addAll(KTypeContainer container) { final int size = container.size(); ensureBufferSpace(size); for (KTypeCursor cursor : container) { add(cursor.value); } return size; } /** * Adds all elements from another iterable. */ public int addAll(Iterable> iterable) { int size = 0; for (KTypeCursor cursor : iterable) { add(cursor.value); size++; } return size; } /** * {@inheritDoc} */ @Override public void insert(int index, KType e1) { assert (index >= 0 && index <= size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + "]."; ensureBufferSpace(1); System.arraycopy(buffer, index, buffer, index + 1, elementsCount - index); buffer[index] = e1; elementsCount++; } /** * {@inheritDoc} */ @Override public KType get(int index) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ")."; return Intrinsics. cast(buffer[index]); } /** * {@inheritDoc} */ @Override public KType set(int index, KType e1) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ")."; final KType v = Intrinsics. cast(buffer[index]); buffer[index] = e1; return v; } /** * {@inheritDoc} */ @Override public KType remove(int index) { assert (index >= 0 && index < size()) : "Index " + index + " out of bounds [" + 0 + ", " + size() + ")."; final KType v = Intrinsics. cast(buffer[index]); if (index + 1 < elementsCount) { System.arraycopy(buffer, index + 1, buffer, index, elementsCount - index - 1); } elementsCount--; buffer[elementsCount] = Intrinsics.empty(); return v; } /** * {@inheritDoc} */ @Override public void removeRange(int fromIndex, int toIndex) { assert (fromIndex >= 0 && fromIndex <= size()) : "Index " + fromIndex + " out of bounds [" + 0 + ", " + size() + ")."; assert (toIndex >= 0 && toIndex <= size()) : "Index " + toIndex + " out of bounds [" + 0 + ", " + size() + "]."; assert fromIndex <= toIndex : "fromIndex must be <= toIndex: " + fromIndex + ", " + toIndex; System.arraycopy(buffer, toIndex, buffer, fromIndex, elementsCount - toIndex); final int count = toIndex - fromIndex; elementsCount -= count; Arrays.fill(buffer, elementsCount, elementsCount + count, Intrinsics.empty()); } /** * {@inheritDoc} */ @Override public int removeFirst(KType e1) { final int index = indexOf(e1); if (index >= 0) remove(index); return index; } /** * {@inheritDoc} */ @Override public int removeLast(KType e1) { final int index = lastIndexOf(e1); if (index >= 0) remove(index); return index; } /** * {@inheritDoc} */ @Override public int removeAll(KType e1) { int to = 0; for (int from = 0; from < elementsCount; from++) { if (Intrinsics.equals(this, e1, buffer[from])) { buffer[from] = Intrinsics.empty(); continue; } if (to != from) { buffer[to] = buffer[from]; buffer[from] = Intrinsics.empty(); } to++; } final int deleted = elementsCount - to; this.elementsCount = to; return deleted; } /** * {@inheritDoc} */ @Override public boolean contains(KType e1) { return indexOf(e1) >= 0; } /** * {@inheritDoc} */ @Override public int indexOf(KType e1) { for (int i = 0; i < elementsCount; i++) { if (Intrinsics.equals(this, e1, buffer[i])) { return i; } } return -1; } /** * {@inheritDoc} */ @Override public int lastIndexOf(KType e1) { for (int i = elementsCount - 1; i >= 0; i--) { if (Intrinsics.equals(this, e1, buffer[i])) { return i; } } return -1; } /** * {@inheritDoc} */ @Override public boolean isEmpty() { return elementsCount == 0; } /** * Ensure this container can hold at least the given number of elements * without resizing its buffers. * * @param expectedElements * The total number of elements, inclusive. */ @Override public void ensureCapacity(int expectedElements) { final int bufferLen = (buffer == null ? 0 : buffer.length); if (expectedElements > bufferLen) { ensureBufferSpace(expectedElements - size()); } } /** * Ensures the internal buffer has enough free slots to store * expectedAdditions. Increases internal buffer size if needed. */ protected void ensureBufferSpace(int expectedAdditions) { final int bufferLen = (buffer == null ? 0 : buffer.length); if (elementsCount + expectedAdditions > bufferLen) { final int newSize = resizer.grow(bufferLen, elementsCount, expectedAdditions); assert newSize >= elementsCount + expectedAdditions : "Resizer failed to" + " return sensible new size: " + newSize + " <= " + (elementsCount + expectedAdditions); this.buffer = Arrays.copyOf(buffer, newSize); } } /** * Truncate or expand the list to the new size. If the list is truncated, the * buffer will not be reallocated (use {@link #trimToSize()} if you need a * truncated buffer), but the truncated values will be reset to the default * value (zero). If the list is expanded, the elements beyond the current size * are initialized with JVM-defaults (zero or null values). */ public void resize(int newSize) { if (newSize <= buffer.length) { if (newSize < elementsCount) { Arrays.fill(buffer, newSize, elementsCount, Intrinsics.empty()); } else { Arrays.fill(buffer, elementsCount, newSize, Intrinsics.empty()); } } else { ensureCapacity(newSize); } this.elementsCount = newSize; } /** * {@inheritDoc} */ @Override public int size() { return elementsCount; } /** * Trim the internal buffer to the current size. */ public void trimToSize() { if (size() != this.buffer.length) { this.buffer = Intrinsics. cast(toArray()); } } /** * Sets the number of stored elements to zero. Releases and initializes the * internal storage array to default values. To clear the list without * cleaning the buffer, simply set the {@link #elementsCount} field to zero. */ @Override public void clear() { Arrays.fill(buffer, 0, elementsCount, Intrinsics.empty()); this.elementsCount = 0; } /** * Sets the number of stored elements to zero and releases the internal * storage array. */ @Override public void release() { this.buffer = Intrinsics. cast(EMPTY_ARRAY); this.elementsCount = 0; } /** * {@inheritDoc} * *

The returned array is sized to match exactly * the number of elements of the stack.

*/ @Override /*! #if ($TemplateOptions.KTypePrimitive) public KType [] toArray() #else !*/ public Object [] toArray() /*! #end !*/ { return Arrays.copyOf(buffer, elementsCount); } /** * Clone this object. The returned clone will reuse the same hash function and * array resizing strategy. */ @Override public KTypeArrayList clone() { try { /* #if ($templateOnly) */ @SuppressWarnings("unchecked") /* #end */ final KTypeArrayList cloned = (KTypeArrayList) super.clone(); cloned.buffer = buffer.clone(); return cloned; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } /** * {@inheritDoc} */ @Override public int hashCode() { int h = 1, max = elementsCount; for (int i = 0; i < max; i++) { h = 31 * h + BitMixer.mix(this.buffer[i]); } return h; } /** * Returns true only if the other object is an instance of * the same class and with the same elements. #if ($TemplateOptions.KTypeGeneric) * Equality comparison is performed with this object's {@link #equals(Object, Object)} * method. #end */ @Override public boolean equals(Object obj) { return obj != null && getClass() == obj.getClass() && equalElements(getClass().cast(obj)); } /** * Compare index-aligned elements against another * {@link KTypeIndexedContainer}. #if ($TemplateOptions.KTypeGeneric) * Equality comparison is performed with this object's {@link #equals(Object, Object)} * method. #end */ protected boolean equalElements(KTypeArrayList other) { int max = size(); if (other.size() != max) { return false; } for (int i = 0; i < max; i++) { if (!Intrinsics.equals(this, get(i), other.get(i))) { return false; } } return true; } /** * An iterator implementation for {@link KTypeArrayList#iterator}. */ final static class ValueIterator extends AbstractIterator> { private final KTypeCursor cursor; private final KType[] buffer; private final int size; public ValueIterator(KType[] buffer, int size) { this.cursor = new KTypeCursor(); this.cursor.index = -1; this.size = size; this.buffer = buffer; } @Override protected KTypeCursor fetch() { if (cursor.index + 1 == size) return done(); cursor.value = buffer[++cursor.index]; return cursor; } } /** * {@inheritDoc} */ @Override public Iterator> iterator() { return new ValueIterator(Intrinsics. cast(buffer), size()); } /** * {@inheritDoc} */ @Override public > T forEach(T procedure) { return forEach(procedure, 0, size()); } /** * Applies procedure to a slice of the list, * fromIndex, inclusive, to toIndex, exclusive. */ public > T forEach(T procedure, int fromIndex, final int toIndex) { assert (fromIndex >= 0 && fromIndex <= size()) : "Index " + fromIndex + " out of bounds [" + 0 + ", " + size() + ")."; assert (toIndex >= 0 && toIndex <= size()) : "Index " + toIndex + " out of bounds [" + 0 + ", " + size() + "]."; assert fromIndex <= toIndex : "fromIndex must be <= toIndex: " + fromIndex + ", " + toIndex; final KType [] buffer = Intrinsics. cast(this.buffer); for (int i = fromIndex; i < toIndex; i++) { procedure.apply(buffer[i]); } return procedure; } /** * {@inheritDoc} */ @Override public int removeAll(KTypePredicate predicate) { final KType[] buffer = Intrinsics. cast(this.buffer); final int elementsCount = this.elementsCount; int to = 0; int from = 0; try { for (; from < elementsCount; from++) { if (predicate.apply(buffer[from])) { buffer[from] = Intrinsics.empty(); continue; } if (to != from) { buffer[to] = buffer[from]; buffer[from] = Intrinsics.empty(); } to++; } } finally { // Keep the list in a consistent state, even if the predicate throws an exception. for (; from < elementsCount; from++) { if (to != from) { buffer[to] = buffer[from]; buffer[from] = Intrinsics.empty(); } to++; } this.elementsCount = to; } return elementsCount - to; } /** * {@inheritDoc} */ @Override public > T forEach(T predicate) { return forEach(predicate, 0, size()); } /** * Applies predicate to a slice of the list, * fromIndex, inclusive, to toIndex, exclusive, or * until predicate returns false. */ public > T forEach(T predicate, int fromIndex, final int toIndex) { assert (fromIndex >= 0 && fromIndex <= size()) : "Index " + fromIndex + " out of bounds [" + 0 + ", " + size() + ")."; assert (toIndex >= 0 && toIndex <= size()) : "Index " + toIndex + " out of bounds [" + 0 + ", " + size() + "]."; assert fromIndex <= toIndex : "fromIndex must be <= toIndex: " + fromIndex + ", " + toIndex; final KType[] buffer = Intrinsics. cast(this.buffer); for (int i = fromIndex; i < toIndex; i++) { if (!predicate.apply(buffer[i])) break; } return predicate; } /** * Create a list from a variable number of arguments or an array of KType. * The elements are copied from the argument to the internal buffer. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public static KTypeArrayList from(KType... elements) { final KTypeArrayList list = new KTypeArrayList(elements.length); list.add(elements); return list; } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeBufferVisualizer.java000066400000000000000000000021511300364116400304110ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * Reused buffer visualization routines. * * @see KTypeSet#visualizeKeyDistribution(int) * @see KTypeVTypeMap#visualizeKeyDistribution(int) */ class KTypeBufferVisualizer { static String visualizeKeyDistribution( /*! #if ($TemplateOptions.KTypeGeneric) !*/ Object [] /*! #else KType [] #end !*/ buffer, int max, int characters) { final StringBuilder b = new StringBuilder(); final char [] chars = ".123456789X".toCharArray(); for (int i = 1, start = -1; i <= characters; i++) { int end = (int) ((long) i * max / characters); if (start + 1 <= end) { int taken = 0; int slots = 0; for (int slot = start + 1; slot <= end; slot++, slots++) { if (!Intrinsics. isEmpty(buffer[slot])) { taken++; } } b.append(chars[Math.min(chars.length - 1, taken * chars.length / slots)]); start = end; } } while (b.length() < characters) { b.append(' '); } return b.toString(); } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeCollection.java000066400000000000000000000040761300364116400272250ustar00rootroot00000000000000package com.carrotsearch.hppc; import com.carrotsearch.hppc.predicates.KTypePredicate; /** * A collection allows basic, efficient operations on sets of elements * (difference and intersection). */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeCollection extends KTypeContainer { /** * Removes all occurrences of e from this collection. * * @param e * Element to be removed from this collection, if present. * @return The number of removed elements as a result of this call. */ public int removeAll(KType e); /** * Removes all elements in this collection that are present in c. * * @return Returns the number of removed elements. */ public int removeAll(KTypeLookupContainer c); /** * Removes all elements in this collection for which the given predicate * returns true. * * @return Returns the number of removed elements. */ public int removeAll(KTypePredicate predicate); /** * Keeps all elements in this collection that are present in c. * Runs in time proportional to the number of elements in this collection. * Equivalent of sets intersection. * * @return Returns the number of removed elements. */ public int retainAll(KTypeLookupContainer c); /** * Keeps all elements in this collection for which the given predicate returns * true. * * @return Returns the number of removed elements. */ public int retainAll(KTypePredicate predicate); /** * Removes all elements from this collection. * * @see #release() */ public void clear(); /** * Removes all elements from the collection and additionally releases any * internal buffers. Typically, if the object is to be reused, a simple * {@link #clear()} should be a better alternative since it'll avoid * reallocation. * * @see #clear() */ public void release(); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeContainer.java000066400000000000000000000070161300364116400270510ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Iterator; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.KTypeProcedure; /** * A generic container holding KTypes. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeContainer extends Iterable> { /** * Returns an iterator to a cursor traversing the collection. The order of * traversal is not defined. More than one cursor may be active at a time. The * behavior of iterators is undefined if structural changes are made to the * underlying collection. * *

* The iterator is implemented as a cursor and it returns the same cursor * instance on every call to {@link Iterator#next()} (to avoid boxing of * primitive types). To read the current list's value (or index in the list) * use the cursor's public fields. An example is shown below. *

* *
   * for (KTypeCursor<KType> c : container) {
   *   System.out.println("index=" + c.index + " value=" + c.value);
   * }
   * 
*/ public Iterator> iterator(); /** * Lookup a given element in the container. This operation has no speed * guarantees (may be linear with respect to the size of this container). * * @return Returns true if this container has an element equal to * e. */ public boolean contains(KType e); /** * Return the current number of elements in this container. The time for * calculating the container's size may take O(n) time, although * implementing classes should try to maintain the current size and return in * constant time. */ public int size(); /** * Shortcut for size() == 0. */ public boolean isEmpty(); /** * Copies all elements of this container to an array. * * The returned array is always a copy, regardless of the storage used by the * container. */ /*! #if ($TemplateOptions.KTypePrimitive) public KType [] toArray(); #else !*/ public Object[] toArray(); /*! #end !*/ /* #if ($TemplateOptions.KTypeGeneric) */ /** * Copies all elements of this container to a dynamically created array of the * given component type. * * @throws ArrayStoreException Thrown if this container's elements are not * assignable to the array's component type. */ public T[] toArray(Class componentClass); /* #end */ /** * Applies a procedure to all container elements. Returns the * argument (any subclass of {@link KTypeProcedure}. This lets the caller to * call methods of the argument by chaining the call (even if the argument is * an anonymous type) to retrieve computed values, for example (IntContainer): * *
   * int count = container.forEach(new IntProcedure() {
   *   int count; // this is a field declaration in an anonymous class.
   * 
   *   public void apply(int value) {
   *     count++;
   *   }
   * }).count;
   * 
*/ public > T forEach(T procedure); /** * Applies a predicate to container elements as long, as the * predicate returns true. The iteration is interrupted * otherwise. */ public > T forEach(T predicate); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeDeque.java000066400000000000000000000045331300364116400261730ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Deque; import java.util.Iterator; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.KTypeProcedure; /** * A linear collection that supports element insertion and removal at both ends. * * @see Deque */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeDeque extends KTypeCollection { /** * Removes the first element that equals e. * * @return The deleted element's index or -1 if the element * was not found. */ public int removeFirst(KType e); /** * Removes the last element that equals e. * * @return The deleted element's index or -1 if the element * was not found. */ public int removeLast(KType e); /** * Inserts the specified element at the front of this deque. */ public void addFirst(KType e); /** * Inserts the specified element at the end of this deque. */ public void addLast(KType e); /** * Retrieves and removes the first element of this deque. * * @return the head (first) element of this deque. */ public KType removeFirst(); /** * Retrieves and removes the last element of this deque. * * @return the tail of this deque. */ public KType removeLast(); /** * Retrieves the first element of this deque but does not remove it. * * @return the head of this deque. */ public KType getFirst(); /** * Retrieves the last element of this deque but does not remove it. * * @return the head of this deque. */ public KType getLast(); /** * @return An iterator over elements in this deque in tail-to-head order. */ public Iterator> descendingIterator(); /** * Applies a procedure to all elements in tail-to-head order. */ public > T descendingForEach(T procedure); /** * Applies a predicate to container elements as long, as the * predicate returns true. The iteration is interrupted * otherwise. */ public > T descendingForEach(T predicate); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeHashSet.java000066400000000000000000000554301300364116400264710ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.*; import com.carrotsearch.hppc.cursors.*; import com.carrotsearch.hppc.predicates.*; import com.carrotsearch.hppc.procedures.*; import static com.carrotsearch.hppc.HashContainers.*; import static com.carrotsearch.hppc.Containers.*; /** * A hash set of KTypes, implemented using using open addressing * with linear probing for collision resolution. * *

* Note: read about * * important differences between hash and scatter sets. *

* * @see KTypeScatterSet * @see HPPC interfaces diagram */ /*! #if ($TemplateOptions.KTypeGeneric) @SuppressWarnings("unchecked") #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeHashSet extends AbstractKTypeCollection implements /*! #if ($templateonly) !*/ Intrinsics.KeyHasher, /*! #end !*/ KTypeLookupContainer, KTypeSet, Preallocable, Cloneable { /** The hash array holding keys. */ public /*! #if ($TemplateOptions.KTypeGeneric) !*/ Object [] /*! #else KType [] #end !*/ keys; /** * The number of stored keys (assigned key slots), excluding the special * "empty" key, if any. * * @see #size() * @see #hasEmptyKey */ protected int assigned; /** * Mask for slot scans in {@link #keys}. */ protected int mask; /** * We perturb hash values with a container-unique * seed to avoid problems with nearly-sorted-by-hash * values on iterations. * * @see #hashKey * @see "http://issues.carrot2.org/browse/HPPC-80" * @see "http://issues.carrot2.org/browse/HPPC-103" */ protected int keyMixer; /** * Expand (rehash) {@link #keys} when {@link #assigned} hits this value. */ protected int resizeAt; /** * Special treatment for the "empty slot" key marker. */ protected boolean hasEmptyKey; /** * The load factor for {@link #keys}. */ protected double loadFactor; /** * Per-instance hash order mixing strategy. * @see #keyMixer */ protected HashOrderMixingStrategy orderMixer; /** * New instance with sane defaults. * * @see #KTypeHashSet(int, double, HashOrderMixingStrategy) */ public KTypeHashSet() { this(DEFAULT_EXPECTED_ELEMENTS, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. * * @see #KTypeHashSet(int, double, HashOrderMixingStrategy) */ public KTypeHashSet(int expectedElements) { this(expectedElements, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. * * @see #KTypeHashSet(int, double, HashOrderMixingStrategy) */ public KTypeHashSet(int expectedElements, double loadFactor) { this(expectedElements, loadFactor, HashOrderMixing.defaultStrategy()); } /** * New instance with the provided defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause a rehash (inclusive). * @param loadFactor * The load factor for internal buffers. Insane load factors (zero, full capacity) * are rejected by {@link #verifyLoadFactor(double)}. * @param orderMixer * Hash key order mixing strategy. See {@link HashOrderMixing} for predefined * implementations. Use constant mixers only if you understand the potential * consequences. */ public KTypeHashSet(int expectedElements, double loadFactor, HashOrderMixingStrategy orderMixer) { this.orderMixer = orderMixer; this.loadFactor = verifyLoadFactor(loadFactor); ensureCapacity(expectedElements); } /** * New instance copying elements from another {@link KTypeContainer}. */ public KTypeHashSet(KTypeContainer container) { this(container.size()); addAll(container); } /** * {@inheritDoc} */ @Override public boolean add(KType key) { if (Intrinsics.isEmpty(key)) { assert Intrinsics.isEmpty(keys[mask + 1]); boolean added = !hasEmptyKey; hasEmptyKey = true; return added; } else { final KType [] keys = Intrinsics. cast(this.keys); final int mask = this.mask; int slot = hashKey(key) & mask; KType existing; while (!Intrinsics.isEmpty(existing = keys[slot])) { if (Intrinsics.equals(this, key, existing)) { return false; } slot = (slot + 1) & mask; } if (assigned == resizeAt) { allocateThenInsertThenRehash(slot, key); } else { keys[slot] = key; } assigned++; return true; } } /** * Adds all elements from the given list (vararg) to this set. * * @return Returns the number of elements actually added as a result of this * call (not previously present in the set). */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public final int addAll(KType... elements) { ensureCapacity(elements.length); int count = 0; for (KType e : elements) { if (add(e)) { count++; } } return count; } /** * Adds all elements from the given {@link KTypeContainer} to this set. * * @return Returns the number of elements actually added as a result of this * call (not previously present in the set). */ public int addAll(KTypeContainer container) { ensureCapacity(container.size()); return addAll((Iterable>) container); } /** * Adds all elements from the given iterable to this set. * * @return Returns the number of elements actually added as a result of this * call (not previously present in the set). */ public int addAll(Iterable> iterable) { int count = 0; for (KTypeCursor cursor : iterable) { if (add(cursor.value)) { count++; } } return count; } /** * {@inheritDoc} */ @Override /*! #if ($TemplateOptions.KTypePrimitive) public KType [] toArray() { #else !*/ public Object[] toArray() { /*! #end !*/ final KType[] cloned = Intrinsics. newArray(size()); int j = 0; if (hasEmptyKey) { cloned[j++] = Intrinsics.empty(); } final KType[] keys = Intrinsics. cast(this.keys); for (int slot = 0, max = mask; slot <= max; slot++) { KType existing; if (!Intrinsics.isEmpty(existing = keys[slot])) { cloned[j++] = existing; } } return cloned; } /** * An alias for the (preferred) {@link #removeAll}. */ public boolean remove(KType key) { if (Intrinsics.isEmpty(key)) { boolean hadEmptyKey = hasEmptyKey; hasEmptyKey = false; return hadEmptyKey; } else { final KType [] keys = Intrinsics. cast(this.keys); final int mask = this.mask; int slot = hashKey(key) & mask; KType existing; while (!Intrinsics.isEmpty(existing = keys[slot])) { if (Intrinsics.equals(this, key, existing)) { shiftConflictingKeys(slot); return true; } slot = (slot + 1) & mask; } return false; } } /** * {@inheritDoc} */ @Override public int removeAll(KType key) { return remove(key) ? 1 : 0; } /** * {@inheritDoc} */ @Override public int removeAll(KTypePredicate predicate) { int before = size(); if (hasEmptyKey) { if (predicate.apply(Intrinsics. empty())) { hasEmptyKey = false; } } final KType[] keys = Intrinsics. cast(this.keys); for (int slot = 0, max = this.mask; slot <= max;) { KType existing; if (!Intrinsics.isEmpty(existing = keys[slot])) { if (predicate.apply(existing)) { shiftConflictingKeys(slot); continue; // Repeat the check for the same slot i (shifted). } } slot++; } return before - size(); } /** * {@inheritDoc} */ @Override public boolean contains(KType key) { if (Intrinsics.isEmpty(key)) { return hasEmptyKey; } else { final KType [] keys = Intrinsics. cast(this.keys); final int mask = this.mask; int slot = hashKey(key) & mask; KType existing; while (!Intrinsics.isEmpty(existing = keys[slot])) { if (Intrinsics.equals(this, key, existing)) { return true; } slot = (slot + 1) & mask; } return false; } } /** * {@inheritDoc} */ @Override public void clear() { assigned = 0; hasEmptyKey = false; Arrays.fill(keys, Intrinsics. empty()); } /** * {@inheritDoc} */ @Override public void release() { assigned = 0; hasEmptyKey = false; keys = null; ensureCapacity(Containers.DEFAULT_EXPECTED_ELEMENTS); } /** * {@inheritDoc} */ @Override public boolean isEmpty() { return size() == 0; } /** * Ensure this container can hold at least the * given number of elements without resizing its buffers. * * @param expectedElements The total number of elements, inclusive. */ @Override public void ensureCapacity(int expectedElements) { if (expectedElements > resizeAt || keys == null) { final KType[] prevKeys = Intrinsics. cast(this.keys); allocateBuffers(minBufferSize(expectedElements, loadFactor)); if (prevKeys != null && !isEmpty()) { rehash(prevKeys); } } } /** * {@inheritDoc} */ @Override public int size() { return assigned + (hasEmptyKey ? 1 : 0); } /** * {@inheritDoc} */ @Override public int hashCode() { int h = hasEmptyKey ? 0xDEADBEEF : 0; final KType[] keys = Intrinsics. cast(this.keys); for (int slot = mask; slot >= 0; slot--) { KType existing; if (!Intrinsics.isEmpty(existing = keys[slot])) { h += BitMixer.mix(existing); } } return h; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { return obj != null && getClass() == obj.getClass() && sameKeys(getClass().cast(obj)); } /** * Return true if all keys of some other container exist in this container. #if ($TemplateOptions.KTypeGeneric) * Equality comparison is performed with this object's {@link #equals(Object, Object)} * method. #end */ private boolean sameKeys(KTypeSet other) { if (other.size() != size()) { return false; } for (KTypeCursor c : other) { if (!contains(Intrinsics. cast(c.value))) { return false; } } return true; } /** * {@inheritDoc} */ @Override public KTypeHashSet clone() { try { /* #if ($templateOnly) */ @SuppressWarnings("unchecked") /* #end */ KTypeHashSet cloned = (KTypeHashSet) super.clone(); cloned.keys = keys.clone(); cloned.hasEmptyKey = cloned.hasEmptyKey; cloned.orderMixer = orderMixer.clone(); return cloned; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } /** * {@inheritDoc} */ @Override public Iterator> iterator() { return new EntryIterator(); } /** * An iterator implementation for {@link #iterator}. */ protected final class EntryIterator extends AbstractIterator> { private final KTypeCursor cursor; private final int max = mask + 1; private int slot = -1; public EntryIterator() { cursor = new KTypeCursor(); } @Override protected KTypeCursor fetch() { if (slot < max) { KType existing; for (slot++; slot < max; slot++) { if (!Intrinsics.isEmpty(existing = Intrinsics. cast(keys[slot]))) { cursor.index = slot; cursor.value = existing; return cursor; } } } if (slot == max && hasEmptyKey) { cursor.index = slot; cursor.value = Intrinsics.empty(); slot++; return cursor; } return done(); } } /** * {@inheritDoc} */ @Override public > T forEach(T procedure) { if (hasEmptyKey) { procedure.apply(Intrinsics. empty()); } final KType[] keys = Intrinsics. cast(this.keys); for (int slot = 0, max = this.mask; slot <= max; slot++) { KType existing; if (!Intrinsics.isEmpty(existing = keys[slot])) { procedure.apply(existing); } } return procedure; } /** * {@inheritDoc} */ @Override public > T forEach(T predicate) { if (hasEmptyKey) { if (!predicate.apply(Intrinsics. empty())) { return predicate; } } final KType[] keys = Intrinsics. cast(this.keys); for (int slot = 0, max = this.mask; slot <= max; slot++) { KType existing; if (!Intrinsics.isEmpty(existing = keys[slot])) { if (!predicate.apply(existing)) { break; } } } return predicate; } /** * Create a set from a variable number of arguments or an array of * KType. The elements are copied from the argument to the * internal buffer. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public static KTypeHashSet from(KType... elements) { final KTypeHashSet set = new KTypeHashSet(elements.length); set.addAll(elements); return set; } /** * Returns a hash code for the given key. * * The default implementation mixes the hash of the key with {@link #keyMixer} * to differentiate hash order of keys between hash containers. Helps * alleviate problems resulting from linear conflict resolution in open * addressing. * * The output from this function should evenly distribute keys across the * entire integer range. */ /*! #if ($templateonly) !*/ @Override public /*! #else protected #end !*/ int hashKey(KType key) { assert !Intrinsics.isEmpty(key); // Handled as a special case (empty slot marker). return BitMixer.mix(key, this.keyMixer); } /** * Returns a logical "index" of a given key that can be used to speed up * follow-up logic in certain scenarios (conditional logic). * * The semantics of "indexes" are not strictly defined. Indexes may * (and typically won't be) contiguous. * * The index is valid only between modifications (it will not be affected * by read-only operations). * * @see #indexExists * @see #indexGet * @see #indexInsert * @see #indexReplace * * @param key * The key to locate in the set. * @return A non-negative value of the logical "index" of the key in the set * or a negative value if the key did not exist. */ public int indexOf(KType key) { final int mask = this.mask; if (Intrinsics. isEmpty(key)) { return hasEmptyKey ? mask + 1 : ~(mask + 1); } else { final KType[] keys = Intrinsics. cast(this.keys); int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { return slot; } slot = (slot + 1) & mask; } return ~slot; } } /** * @see #indexOf * * @param index The index of a given key, as returned from {@link #indexOf}. * @return Returns true if the index corresponds to an existing key * or false otherwise. This is equivalent to checking whether the index is * a positive value (existing keys) or a negative value (non-existing keys). */ public boolean indexExists(int index) { assert index < 0 || (index >= 0 && index <= mask) || (index == mask + 1 && hasEmptyKey); return index >= 0; } /** * Returns the exact value of the existing key. This method makes sense for sets * of objects which define custom key-equality relationship. * * @see #indexOf * * @param index The index of an existing key. * @return Returns the equivalent key currently stored in the set. * @throws AssertionError If assertions are enabled and the index does * not correspond to an existing key. */ public KType indexGet(int index) { assert index >= 0 : "The index must point at an existing key."; assert index <= mask || (index == mask + 1 && hasEmptyKey); return Intrinsics. cast(keys[index]); } /** * Replaces the existing equivalent key with the given one and returns any previous value * stored for that key. * * @see #indexOf * * @param index The index of an existing key. * @param equivalentKey The key to put in the set as a replacement. Must be equivalent to * the key currently stored at the provided index. * @return Returns the previous key stored in the set. * @throws AssertionError If assertions are enabled and the index does * not correspond to an existing key. */ public KType indexReplace(int index, KType equivalentKey) { assert index >= 0 : "The index must point at an existing key."; assert index <= mask || (index == mask + 1 && hasEmptyKey); assert Intrinsics.equals(this, keys[index], equivalentKey); KType previousValue = Intrinsics. cast(keys[index]); keys[index] = equivalentKey; return previousValue; } /** * Inserts a key for an index that is not present in the set. This method * may help in avoiding double recalculation of the key's hash. * * @see #indexOf * * @param index The index of a previously non-existing key, as returned from * {@link #indexOf}. * @throws AssertionError If assertions are enabled and the index does * not correspond to an existing key. */ public void indexInsert(int index, KType key) { assert index < 0 : "The index must not point at an existing key."; index = ~index; if (Intrinsics.isEmpty(key)) { assert index == mask + 1; assert Intrinsics.isEmpty(keys[index]); hasEmptyKey = true; } else { assert Intrinsics.isEmpty(keys[index]); if (assigned == resizeAt) { allocateThenInsertThenRehash(index, key); } else { keys[index] = key; } assigned++; } } @Override public String visualizeKeyDistribution(int characters) { return KTypeBufferVisualizer.visualizeKeyDistribution(keys, mask, characters); } /** * Validate load factor range and return it. Override and suppress if you need * insane load factors. */ protected double verifyLoadFactor(double loadFactor) { checkLoadFactor(loadFactor, MIN_LOAD_FACTOR, MAX_LOAD_FACTOR); return loadFactor; } /** * Rehash from old buffers to new buffers. */ protected void rehash(KType[] fromKeys) { assert HashContainers.checkPowerOfTwo(fromKeys.length - 1); // Rehash all stored keys into the new buffers. final KType[] keys = Intrinsics. cast(this.keys); final int mask = this.mask; KType existing; for (int i = fromKeys.length - 1; --i >= 0;) { if (!Intrinsics.isEmpty(existing = fromKeys[i])) { int slot = hashKey(existing) & mask; while (!Intrinsics.isEmpty(keys[slot])) { slot = (slot + 1) & mask; } keys[slot] = existing; } } } /** * Allocate new internal buffers. This method attempts to allocate * and assign internal buffers atomically (either allocations succeed or not). */ protected void allocateBuffers(int arraySize) { assert Integer.bitCount(arraySize) == 1; // Compute new hash mixer candidate before expanding. final int newKeyMixer = this.orderMixer.newKeyMixer(arraySize); // Ensure no change is done if we hit an OOM. KType[] prevKeys = Intrinsics. cast(this.keys); try { int emptyElementSlot = 1; this.keys = Intrinsics. newArray(arraySize + emptyElementSlot); } catch (OutOfMemoryError e) { this.keys = prevKeys; throw new BufferAllocationException( "Not enough memory to allocate buffers for rehashing: %,d -> %,d", e, this.keys == null ? 0 : size(), arraySize); } this.resizeAt = expandAtCount(arraySize, loadFactor); this.keyMixer = newKeyMixer; this.mask = arraySize - 1; } /** * This method is invoked when there is a new key to be inserted into * the buffer but there is not enough empty slots to do so. * * New buffers are allocated. If this succeeds, we know we can proceed * with rehashing so we assign the pending element to the previous buffer * (possibly violating the invariant of having at least one empty slot) * and rehash all keys, substituting new buffers at the end. */ protected void allocateThenInsertThenRehash(int slot, KType pendingKey) { assert assigned == resizeAt && Intrinsics.isEmpty(Intrinsics. cast(keys[slot])) && !Intrinsics.isEmpty(pendingKey); // Try to allocate new buffers first. If we OOM, we leave in a consistent state. final KType[] prevKeys = Intrinsics. cast(this.keys); allocateBuffers(nextBufferSize(mask + 1, size(), loadFactor)); assert this.keys.length > prevKeys.length; // We have succeeded at allocating new data so insert the pending key/value at // the free slot in the old arrays before rehashing. prevKeys[slot] = pendingKey; // Rehash old keys, including the pending key. rehash(prevKeys); } /** * Shift all the slot-conflicting keys allocated to (and including) slot. */ protected void shiftConflictingKeys(int gapSlot) { final KType[] keys = Intrinsics. cast(this.keys); final int mask = this.mask; // Perform shifts of conflicting keys to fill in the gap. int distance = 0; while (true) { final int slot = (gapSlot + (++distance)) & mask; final KType existing = keys[slot]; if (Intrinsics.isEmpty(existing)) { break; } final int idealSlot = hashKey(existing); final int shift = (slot - idealSlot) & mask; if (shift >= distance) { // Entry at this position was originally at or before the gap slot. // Move the conflict-shifted entry to the gap's position and repeat the procedure // for any entries to the right of the current position, treating it // as the new gap. keys[gapSlot] = existing; gapSlot = slot; distance = 0; } } // Mark the last found gap slot without a conflict as empty. keys[gapSlot] = Intrinsics.empty(); assigned--; } }hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeIndexedContainer.java000066400000000000000000000044661300364116400303600ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.RandomAccess; /** * An indexed container provides random access to elements based on an * index. Indexes are zero-based. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeIndexedContainer extends KTypeCollection, RandomAccess { /** * Removes the first element that equals e1, returning its * deleted position or -1 if the element was not found. */ public int removeFirst(KType e1); /** * Removes the last element that equals e1, returning its deleted * position or -1 if the element was not found. */ public int removeLast(KType e1); /** * Returns the index of the first occurrence of the specified element in this * list, or -1 if this list does not contain the element. */ public int indexOf(KType e1); /** * Returns the index of the last occurrence of the specified element in this * list, or -1 if this list does not contain the element. */ public int lastIndexOf(KType e1); /** * Adds an element to the end of this container (the last index is incremented * by one). */ public void add(KType e1); /** * Inserts the specified element at the specified position in this list. * * @param index * The index at which the element should be inserted, shifting any * existing and subsequent elements to the right. */ public void insert(int index, KType e1); /** * Replaces the element at the specified position in this list with the * specified element. * * @return Returns the previous value in the list. */ public KType set(int index, KType e1); /** * @return Returns the element at index index from the list. */ public KType get(int index); /** * Removes the element at the specified position in this container and returns * it. * * @see #removeFirst * @see #removeLast * @see #removeAll */ public KType remove(int index); /** * Removes from this container all of the elements with indexes between * fromIndex, inclusive, and toIndex, exclusive. */ public void removeRange(int fromIndex, int toIndex); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeLookupContainer.java000066400000000000000000000006151300364116400302410ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * Marker interface for containers that can check if they contain a given object * in at least time O(log n) and ideally in amortized constant time * O(1). */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeLookupContainer extends KTypeContainer { public boolean contains(KType e); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeScatterSet.java000066400000000000000000000034311300364116400272050ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.Containers.*; import static com.carrotsearch.hppc.HashContainers.*; /** * Same as {@link KTypeHashSet} but does not implement per-instance key mixing * strategy and uses a simpler (faster) bit distribution function. * *

* Note: read about important differences between hash and * scatter sets. *

* * @see KTypeHashSet * @see HPPC interfaces diagram */ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeScatterSet extends KTypeHashSet { /** * New instance with sane defaults. */ public KTypeScatterSet() { this(DEFAULT_EXPECTED_ELEMENTS, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. */ public KTypeScatterSet(int expectedElements) { this(expectedElements, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. */ @SuppressWarnings("deprecation") public KTypeScatterSet(int expectedElements, double loadFactor) { super(expectedElements, loadFactor, HashOrderMixing.none()); } /*! #if ($templateonly) !*/ @Override public /*! #else protected #end !*/ int hashKey(KType key) { return BitMixer.mixPhi(key); } /** * Create a set from a variable number of arguments or an array of * KType. The elements are copied from the argument to the * internal buffer. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public static KTypeScatterSet from(KType... elements) { final KTypeScatterSet set = new KTypeScatterSet(elements.length); set.addAll(elements); return set; } }hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeSet.java000066400000000000000000000020361300364116400256570ustar00rootroot00000000000000package com.carrotsearch.hppc; /** * A set of KTypes. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeSet extends KTypeCollection { /** * Adds k to the set. * * @return Returns true if this element was not part of the set * before. Returns false if an equal element is part of * the set, and replaces the existing equal element with the * argument (if keys are object types). */ public boolean add(KType k); /** * Visually depict the distribution of keys. * * @param characters * The number of characters to "squeeze" the entire buffer into. * @return Returns a sequence of characters where '.' depicts an empty * fragment of the internal buffer and 'X' depicts full or nearly full * capacity within the buffer's range and anything between 1 and 9 is between. */ public String visualizeKeyDistribution(int characters); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeStack.java000066400000000000000000000113271300364116400261740ustar00rootroot00000000000000package com.carrotsearch.hppc; /* #if ($TemplateOptions.KTypeGeneric) */ import java.util.Arrays; /* #end */ import com.carrotsearch.hppc.cursors.KTypeCursor; /** * A subclass of {@link KTypeArrayList} adding stack-related utility methods. * The top of the stack is at the {@link #size()} - 1 element. */ /*! #if ($TemplateOptions.KTypeGeneric) @SuppressWarnings("unchecked") #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeStack extends KTypeArrayList { /** * New instance with sane defaults. */ public KTypeStack() { super(); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). */ public KTypeStack(int expectedElements) { super(expectedElements); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). * @param resizer * Underlying buffer sizing strategy. */ public KTypeStack(int expectedElements, ArraySizingStrategy resizer) { super(expectedElements, resizer); } /** * Create a stack by pushing all elements of another container to it. */ public KTypeStack(KTypeContainer container) { super(container); } /** * Adds one KType to the stack. */ public void push(KType e1) { ensureBufferSpace(1); buffer[elementsCount++] = e1; } /** * Adds two KTypes to the stack. */ public void push(KType e1, KType e2) { ensureBufferSpace(2); buffer[elementsCount++] = e1; buffer[elementsCount++] = e2; } /** * Adds three KTypes to the stack. */ public void push(KType e1, KType e2, KType e3) { ensureBufferSpace(3); buffer[elementsCount++] = e1; buffer[elementsCount++] = e2; buffer[elementsCount++] = e3; } /** * Adds four KTypes to the stack. */ public void push(KType e1, KType e2, KType e3, KType e4) { ensureBufferSpace(4); buffer[elementsCount++] = e1; buffer[elementsCount++] = e2; buffer[elementsCount++] = e3; buffer[elementsCount++] = e4; } /** * Add a range of array elements to the stack. */ public void push(KType[] elements, int start, int len) { assert start >= 0 && len >= 0; ensureBufferSpace(len); System.arraycopy(elements, start, buffer, elementsCount, len); elementsCount += len; } /** * Vararg-signature method for pushing elements at the top of the stack. *

* This method is handy, but costly if used in tight loops (anonymous array * passing) *

*/ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public final void push(KType... elements) { push(elements, 0, elements.length); } /** * Pushes all elements from another container to the top of the stack. */ public int pushAll(KTypeContainer container) { return addAll(container); } /** * Pushes all elements from another iterable to the top of the stack. */ public int pushAll(Iterable> iterable) { return addAll(iterable); } /** * Discard an arbitrary number of elements from the top of the stack. */ public void discard(int count) { assert elementsCount >= count; elementsCount -= count; /* #if ($TemplateOptions.KTypeGeneric) */ Arrays.fill(buffer, elementsCount, elementsCount + count, null); /* #end */ } /** * Discard the top element from the stack. */ public void discard() { assert elementsCount > 0; elementsCount--; /* #if ($TemplateOptions.KTypeGeneric) */ buffer[elementsCount] = null; /* #end */ } /** * Remove the top element from the stack and return it. */ public KType pop() { assert elementsCount > 0; final KType v = Intrinsics. cast(buffer[--elementsCount]); /* #if ($TemplateOptions.KTypeGeneric) */ buffer[elementsCount] = null; /* #end */ return v; } /** * Peek at the top element on the stack. */ public KType peek() { assert elementsCount > 0; return Intrinsics. cast(buffer[elementsCount - 1]); } /** * Create a stack by pushing a variable number of arguments to it. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public static KTypeStack from(KType... elements) { final KTypeStack stack = new KTypeStack(elements.length); stack.push(elements); return stack; } /** * {@inheritDoc} */ @Override public KTypeStack clone() { return (KTypeStack) super.clone(); } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeVTypeAssociativeContainer.java000066400000000000000000000101621300364116400322300ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Iterator; import com.carrotsearch.hppc.cursors.*; import com.carrotsearch.hppc.predicates.*; import com.carrotsearch.hppc.procedures.*; /** * An associative container from keys to (one or * possibly more) values. * * @see KTypeContainer */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeVTypeAssociativeContainer extends Iterable> { /** * Returns a cursor over the entries (key-value pairs) in this map. The * iterator is implemented as a cursor and it returns the same cursor * instance on every call to {@link Iterator#next()}. To read the current * key and value use the cursor's public fields. An example is shown below. * *
   * for (IntShortCursor c : intShortMap) {
   *   System.out.println("index=" + c.index + " key=" + c.key + " value=" + c.value);
   * }
* *

* The index field inside the cursor gives the internal index * inside the container's implementation. The interpretation of this index * depends on to the container. */ @Override public Iterator> iterator(); /** * Returns true if this container has an association to a value * for the given key. */ public boolean containsKey(KType key); /** * @return Returns the current size (number of assigned keys) in the * container. */ public int size(); /** * @return Return true if this hash map contains no assigned * keys. */ public boolean isEmpty(); /** * Removes all keys (and associated values) present in a given container. An * alias to: * *

   * keys().removeAll(container)
   * 
* * but with no additional overhead. * * @return Returns the number of elements actually removed as a result of this * call. */ public int removeAll(KTypeContainer container); /** * Removes all keys (and associated values) for which the predicate returns * true. * * @return Returns the number of elements actually removed as a result of this * call. */ public int removeAll(KTypePredicate predicate); /** * Removes all keys (and associated values) for which the predicate returns * true. * * @return Returns the number of elements actually removed as a result of this * call. */ public int removeAll(KTypeVTypePredicate predicate); /** * Applies a given procedure to all keys-value pairs in this container. * Returns the argument (any subclass of {@link KTypeVTypeProcedure}. This * lets the caller to call methods of the argument by chaining the call (even * if the argument is an anonymous type) to retrieve computed values, for * example. */ public > T forEach(T procedure); /** * Applies a given predicate to all keys-value pairs in this container. * Returns the argument (any subclass of {@link KTypeVTypePredicate}. This * lets the caller to call methods of the argument by chaining the call (even * if the argument is an anonymous type) to retrieve computed values, for * example. * * The iteration is continued as long as the predicate returns * true. */ public > T forEach(T predicate); /** * Returns a collection of keys of this container. The returned collection is * a view over the key set and any modifications (if allowed) introduced to * the collection will propagate to the associative container immediately. */ public KTypeCollection keys(); /** * Returns a container view of all values present in this container. The * returned collection is a view over the key set and any modifications (if * allowed) introduced to the collection will propagate to the associative * container immediately. */ public KTypeContainer values(); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeVTypeHashMap.java000066400000000000000000001036351300364116400274440ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.*; import com.carrotsearch.hppc.cursors.*; import com.carrotsearch.hppc.predicates.*; import com.carrotsearch.hppc.procedures.*; import static com.carrotsearch.hppc.HashContainers.*; import static com.carrotsearch.hppc.Containers.*; /** * A hash map of KType to VType, implemented using open * addressing with linear probing for collision resolution. * *

Note: read about important differences * between hash and scatter sets.

* * @see KTypeVTypeScatterMap * @see HPPC interfaces diagram */ /*! #if ($TemplateOptions.anyGeneric) @SuppressWarnings("unchecked") #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeVTypeHashMap implements /*! #if ($templateonly) !*/ Intrinsics.EqualityFunction, /*! #end !*/ /*! #if ($templateonly) !*/ Intrinsics.KeyHasher, /*! #end !*/ KTypeVTypeMap, Preallocable, Cloneable { /** * The array holding keys. */ public /*! #if ($TemplateOptions.KTypeGeneric) !*/ Object [] /*! #else KType [] #end !*/ keys; /** * The array holding values. */ public /*! #if ($TemplateOptions.VTypeGeneric) !*/ Object [] /*! #else VType [] #end !*/ values; /** * We perturb hash values with a container-unique * seed to avoid problems with nearly-sorted-by-hash * values on iterations. * * @see #hashKey * @see "http://issues.carrot2.org/browse/HPPC-80" * @see "http://issues.carrot2.org/browse/HPPC-103" */ protected int keyMixer; /** * The number of stored keys (assigned key slots), excluding the special * "empty" key, if any (use {@link #size()} instead). * * @see #size() */ protected int assigned; /** * Mask for slot scans in {@link #keys}. */ protected int mask; /** * Expand (rehash) {@link #keys} when {@link #assigned} hits this value. */ protected int resizeAt; /** * Special treatment for the "empty slot" key marker. */ protected boolean hasEmptyKey; /** * The load factor for {@link #keys}. */ protected double loadFactor; /** * Per-instance hash order mixing strategy. * @see #keyMixer */ protected HashOrderMixingStrategy orderMixer; /** * New instance with sane defaults. */ public KTypeVTypeHashMap() { this(DEFAULT_EXPECTED_ELEMENTS); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). */ public KTypeVTypeHashMap(int expectedElements) { this(expectedElements, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). * @param loadFactor * The load factor for internal buffers. Insane load factors (zero, full capacity) * are rejected by {@link #verifyLoadFactor(double)}. */ public KTypeVTypeHashMap(int expectedElements, double loadFactor) { this(expectedElements, loadFactor, HashOrderMixing.defaultStrategy()); } /** * New instance with the provided defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause a rehash (inclusive). * @param loadFactor * The load factor for internal buffers. Insane load factors (zero, full capacity) * are rejected by {@link #verifyLoadFactor(double)}. * @param orderMixer * Hash key order mixing strategy. See {@link HashOrderMixing} for predefined * implementations. Use constant mixers only if you understand the potential * consequences. */ public KTypeVTypeHashMap(int expectedElements, double loadFactor, HashOrderMixingStrategy orderMixer) { this.orderMixer = orderMixer; this.loadFactor = verifyLoadFactor(loadFactor); ensureCapacity(expectedElements); } /** * Create a hash map from all key-value pairs of another container. */ public KTypeVTypeHashMap(KTypeVTypeAssociativeContainer container) { this(container.size()); putAll(container); } /** * {@inheritDoc} */ @Override public VType put(KType key, VType value) { assert assigned < mask + 1; final int mask = this.mask; if (Intrinsics. isEmpty(key)) { hasEmptyKey = true; VType previousValue = Intrinsics. cast(values[mask + 1]); values[mask + 1] = value; return previousValue; } else { final KType[] keys = Intrinsics. cast(this.keys); int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { final VType previousValue = Intrinsics. cast(values[slot]); values[slot] = value; return previousValue; } slot = (slot + 1) & mask; } if (assigned == resizeAt) { allocateThenInsertThenRehash(slot, key, value); } else { keys[slot] = key; values[slot] = value; } assigned++; return Intrinsics. empty(); } } /** * {@inheritDoc} */ @Override public int putAll(KTypeVTypeAssociativeContainer container) { final int count = size(); for (KTypeVTypeCursor c : container) { put(c.key, c.value); } return size() - count; } /** * Puts all key/value pairs from a given iterable into this map. */ @Override public int putAll(Iterable> iterable){ final int count = size(); for (KTypeVTypeCursor c : iterable) { put(c.key, c.value); } return size() - count; } /** * Trove-inspired API method. An equivalent * of the following code: *
   * if (!map.containsKey(key)) map.put(value);
   * 
* * @param key The key of the value to check. * @param value The value to put if key does not exist. * @return true if key did not exist and value * was placed in the map. */ public boolean putIfAbsent(KType key, VType value) { if (!containsKey(key)) { put(key, value); return true; } else { return false; } } /*! #if ($TemplateOptions.VTypePrimitive) !*/ /** * If key exists, putValue is inserted into the map, * otherwise any existing value is incremented by additionValue. * * @param key * The key of the value to adjust. * @param putValue * The value to put if key does not exist. * @param incrementValue * The value to add to the existing value if key exists. * @return Returns the current value associated with key (after * changes). */ @Override public VType putOrAdd(KType key, VType putValue, VType incrementValue) { assert assigned < mask + 1; if (containsKey(key)) { putValue = get(key); putValue = (VType) (Intrinsics. add(putValue, incrementValue)); } put(key, putValue); return putValue; } /*! #end !*/ /*! #if ($TemplateOptions.VTypePrimitive) !*/ /** * Adds incrementValue to any existing value for the given key * or inserts incrementValue if key did not previously exist. * * @param key The key of the value to adjust. * @param incrementValue The value to put or add to the existing value if key exists. * @return Returns the current value associated with key (after changes). */ @Override public VType addTo(KType key, VType incrementValue) { return putOrAdd(key, incrementValue, incrementValue); } /*! #end !*/ /** * {@inheritDoc} */ @Override public VType remove(KType key) { final int mask = this.mask; if (Intrinsics. isEmpty(key)) { hasEmptyKey = false; VType previousValue = Intrinsics. cast(values[mask + 1]); values[mask + 1] = Intrinsics. empty(); return previousValue; } else { final KType[] keys = Intrinsics. cast(this.keys); int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { final VType previousValue = Intrinsics. cast(values[slot]); shiftConflictingKeys(slot); return previousValue; } slot = (slot + 1) & mask; } return Intrinsics. empty(); } } /** * {@inheritDoc} */ @Override public int removeAll(KTypeContainer other) { final int before = size(); // Try to iterate over the smaller set of values or // over the container that isn't implementing // efficient contains() lookup. if (other.size() >= size() && other instanceof KTypeLookupContainer) { if (hasEmptyKey) { if (other.contains(Intrinsics. empty())) { hasEmptyKey = false; values[mask + 1] = Intrinsics. empty(); } } final KType[] keys = Intrinsics. cast(this.keys); for (int slot = 0, max = this.mask; slot <= max;) { KType existing; if (!Intrinsics. isEmpty(existing = keys[slot]) && other.contains(existing)) { // Shift, do not increment slot. shiftConflictingKeys(slot); } else { slot++; } } } else { for (KTypeCursor c : other) { this.remove(Intrinsics. cast(c.value)); } } return before - size(); } /** * {@inheritDoc} */ @Override public int removeAll(KTypeVTypePredicate predicate) { final int before = size(); final int mask = this.mask; if (hasEmptyKey) { if (predicate.apply(Intrinsics. empty(), Intrinsics. cast(values[mask + 1]))) { hasEmptyKey = false; values[mask + 1] = Intrinsics. empty(); } } final KType[] keys = Intrinsics. cast(this.keys); final VType[] values = Intrinsics. cast(this.values); for (int slot = 0; slot <= mask;) { KType existing; if (!Intrinsics. isEmpty(existing = keys[slot]) && predicate.apply(existing, values[slot])) { // Shift, do not increment slot. shiftConflictingKeys(slot); } else { slot++; } } return before - size(); } /** * {@inheritDoc} */ @Override public int removeAll(KTypePredicate predicate) { final int before = size(); if (hasEmptyKey) { if (predicate.apply(Intrinsics. empty())) { hasEmptyKey = false; values[mask + 1] = Intrinsics. empty(); } } final KType[] keys = Intrinsics. cast(this.keys); for (int slot = 0, max = this.mask; slot <= max;) { KType existing; if (!Intrinsics. isEmpty(existing = keys[slot]) && predicate.apply(existing)) { // Shift, do not increment slot. shiftConflictingKeys(slot); } else { slot++; } } return before - size(); } /** * {@inheritDoc} */ @Override public VType get(KType key) { if (Intrinsics. isEmpty(key)) { return hasEmptyKey ? Intrinsics. cast(values[mask + 1]) : Intrinsics. empty(); } else { final KType[] keys = Intrinsics. cast(this.keys); final int mask = this.mask; int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { return Intrinsics. cast(values[slot]); } slot = (slot + 1) & mask; } return Intrinsics. empty(); } } /** * {@inheritDoc} */ @Override public VType getOrDefault(KType key, VType defaultValue) { if (Intrinsics. isEmpty(key)) { return hasEmptyKey ? Intrinsics. cast(values[mask + 1]) : defaultValue; } else { final KType[] keys = Intrinsics. cast(this.keys); final int mask = this.mask; int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { return Intrinsics. cast(values[slot]); } slot = (slot + 1) & mask; } return defaultValue; } } /** * {@inheritDoc} */ @Override public boolean containsKey(KType key) { if (Intrinsics. isEmpty(key)) { return hasEmptyKey; } else { final KType[] keys = Intrinsics. cast(this.keys); final int mask = this.mask; int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { return true; } slot = (slot + 1) & mask; } return false; } } /** * {@inheritDoc} */ @Override public int indexOf(KType key) { final int mask = this.mask; if (Intrinsics. isEmpty(key)) { return hasEmptyKey ? mask + 1 : ~(mask + 1); } else { final KType[] keys = Intrinsics. cast(this.keys); int slot = hashKey(key) & mask; KType existing; while (!Intrinsics. isEmpty(existing = keys[slot])) { if (Intrinsics. equals(this, key, existing)) { return slot; } slot = (slot + 1) & mask; } return ~slot; } } /** * {@inheritDoc} */ @Override public boolean indexExists(int index) { assert index < 0 || (index >= 0 && index <= mask) || (index == mask + 1 && hasEmptyKey); return index >= 0; } /** * {@inheritDoc} */ @Override public VType indexGet(int index) { assert index >= 0 : "The index must point at an existing key."; assert index <= mask || (index == mask + 1 && hasEmptyKey); return Intrinsics. cast(values[index]); } /** * {@inheritDoc} */ @Override public VType indexReplace(int index, VType newValue) { assert index >= 0 : "The index must point at an existing key."; assert index <= mask || (index == mask + 1 && hasEmptyKey); VType previousValue = Intrinsics. cast(values[index]); values[index] = newValue; return previousValue; } /** * {@inheritDoc} */ @Override public void indexInsert(int index, KType key, VType value) { assert index < 0 : "The index must not point at an existing key."; index = ~index; if (Intrinsics. isEmpty(key)) { assert index == mask + 1; values[index] = value; hasEmptyKey = true; } else { assert Intrinsics. isEmpty(keys[index]); if (assigned == resizeAt) { allocateThenInsertThenRehash(index, key, value); } else { keys[index] = key; values[index] = value; } assigned++; } } /** * {@inheritDoc} */ @Override public void clear() { assigned = 0; hasEmptyKey = false; Arrays.fill(keys, Intrinsics. empty()); /* #if ($TemplateOptions.VTypeGeneric) */ Arrays.fill(values, Intrinsics. empty()); /* #end */ } /** * {@inheritDoc} */ @Override public void release() { assigned = 0; hasEmptyKey = false; keys = null; values = null; ensureCapacity(Containers.DEFAULT_EXPECTED_ELEMENTS); } /** * {@inheritDoc} */ @Override public int size() { return assigned + (hasEmptyKey ? 1 : 0); } /** * {@inheritDoc} */ public boolean isEmpty() { return size() == 0; } /** * {@inheritDoc} */ @Override public int hashCode() { int h = hasEmptyKey ? 0xDEADBEEF : 0; for (KTypeVTypeCursor c : this) { h += BitMixer.mix(c.key) + BitMixer.mix(c.value); } return h; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { return obj != null && getClass() == obj.getClass() && equalElements(getClass().cast(obj)); } /** * Return true if all keys of some other container exist in this container. #if ($TemplateOptions.KTypeGeneric) * Equality comparison is performed with this object's {@link #equals(Object, Object)} * method. #end #if ($TemplateOptions.VTypeGeneric) * Values are compared using {@link Objects#equals(Object)} method. #end */ protected boolean equalElements(KTypeVTypeHashMap other) { if (other.size() != size()) { return false; } for (KTypeVTypeCursor c : other) { KType key = Intrinsics. cast(c.key); if (!containsKey(key) || !Intrinsics. equals(c.value, get(key))) { return false; } } return true; } /** * Ensure this container can hold at least the * given number of keys (entries) without resizing its buffers. * * @param expectedElements The total number of keys, inclusive. */ @Override public void ensureCapacity(int expectedElements) { if (expectedElements > resizeAt || keys == null) { final KType[] prevKeys = Intrinsics. cast(this.keys); final VType[] prevValues = Intrinsics. cast(this.values); allocateBuffers(minBufferSize(expectedElements, loadFactor)); if (prevKeys != null && !isEmpty()) { rehash(prevKeys, prevValues); } } } /** * An iterator implementation for {@link #iterator}. */ private final class EntryIterator extends AbstractIterator> { private final KTypeVTypeCursor cursor; private final int max = mask + 1; private int slot = -1; public EntryIterator() { cursor = new KTypeVTypeCursor(); } @Override protected KTypeVTypeCursor fetch() { if (slot < max) { KType existing; for (slot++; slot < max; slot++) { if (!Intrinsics. isEmpty(existing = Intrinsics. cast(keys[slot]))) { cursor.index = slot; cursor.key = existing; cursor.value = Intrinsics. cast(values[slot]); return cursor; } } } if (slot == max && hasEmptyKey) { cursor.index = slot; cursor.key = Intrinsics. empty(); cursor.value = Intrinsics. cast(values[max]); slot++; return cursor; } return done(); } } /** * {@inheritDoc} */ @Override public Iterator> iterator() { return new EntryIterator(); } /** * {@inheritDoc} */ @Override public > T forEach(T procedure) { final KType[] keys = Intrinsics. cast(this.keys); final VType[] values = Intrinsics. cast(this.values); if (hasEmptyKey) { procedure.apply(Intrinsics. empty(), Intrinsics. cast(values[mask + 1])); } for (int slot = 0, max = this.mask; slot <= max; slot++) { if (!Intrinsics. isEmpty(keys[slot])) { procedure.apply(keys[slot], values[slot]); } } return procedure; } /** * {@inheritDoc} */ @Override public > T forEach(T predicate) { final KType[] keys = Intrinsics. cast(this.keys); final VType[] values = Intrinsics. cast(this.values); if (hasEmptyKey) { if (!predicate.apply(Intrinsics. empty(), Intrinsics. cast(values[mask + 1]))) { return predicate; } } for (int slot = 0, max = this.mask; slot <= max; slot++) { if (!Intrinsics. isEmpty(keys[slot])) { if (!predicate.apply(keys[slot], values[slot])) { break; } } } return predicate; } /** * Returns a specialized view of the keys of this associated container. The * view additionally implements {@link ObjectLookupContainer}. */ public KeysContainer keys() { return new KeysContainer(); } /** * A view of the keys inside this hash map. */ public final class KeysContainer extends AbstractKTypeCollection implements KTypeLookupContainer { private final KTypeVTypeHashMap owner = KTypeVTypeHashMap.this; @Override public boolean contains(KType e) { return owner.containsKey(e); } @Override public > T forEach(final T procedure) { owner.forEach(new KTypeVTypeProcedure() { @Override public void apply(KType key, VType value) { procedure.apply(key); } }); return procedure; } @Override public > T forEach(final T predicate) { owner.forEach(new KTypeVTypePredicate() { @Override public boolean apply(KType key, VType value) { return predicate.apply(key); } }); return predicate; } @Override public boolean isEmpty() { return owner.isEmpty(); } @Override public Iterator> iterator() { return new KeysIterator(); } @Override public int size() { return owner.size(); } @Override public void clear() { owner.clear(); } @Override public void release() { owner.release(); } @Override public int removeAll(KTypePredicate predicate) { return owner.removeAll(predicate); } @Override public int removeAll(final KType e) { final boolean hasKey = owner.containsKey(e); if (hasKey) { owner.remove(e); return 1; } else { return 0; } } }; /** * An iterator over the set of assigned keys. */ private final class KeysIterator extends AbstractIterator> { private final KTypeCursor cursor; private final int max = mask + 1; private int slot = -1; public KeysIterator() { cursor = new KTypeCursor(); } @Override protected KTypeCursor fetch() { if (slot < max) { KType existing; for (slot++; slot < max; slot++) { if (!Intrinsics. isEmpty(existing = Intrinsics. cast(keys[slot]))) { cursor.index = slot; cursor.value = existing; return cursor; } } } if (slot == max && hasEmptyKey) { cursor.index = slot; cursor.value = Intrinsics. empty(); slot++; return cursor; } return done(); } } /** * @return Returns a container with all values stored in this map. */ @Override public KTypeCollection values() { return new ValuesContainer(); } /** * A view over the set of values of this map. */ private final class ValuesContainer extends AbstractKTypeCollection { private final KTypeVTypeHashMap owner = KTypeVTypeHashMap.this; @Override public int size() { return owner.size(); } @Override public boolean isEmpty() { return owner.isEmpty(); } @Override public boolean contains(VType value) { for (KTypeVTypeCursor c : owner) { if (Intrinsics. equals(value, c.value)) { return true; } } return false; } @Override public > T forEach(T procedure) { for (KTypeVTypeCursor c : owner) { procedure.apply(c.value); } return procedure; } @Override public > T forEach(T predicate) { for (KTypeVTypeCursor c : owner) { if (!predicate.apply(c.value)) { break; } } return predicate; } @Override public Iterator> iterator() { return new ValuesIterator(); } @Override public int removeAll(final VType e) { return owner.removeAll(new KTypeVTypePredicate() { @Override public boolean apply(KType key, VType value) { return Intrinsics. equals(e, value); } }); } @Override public int removeAll(final KTypePredicate predicate) { return owner.removeAll(new KTypeVTypePredicate() { @Override public boolean apply(KType key, VType value) { return predicate.apply(value); } }); } @Override public void clear() { owner.clear(); } @Override public void release() { owner.release(); } } /** * An iterator over the set of assigned values. */ private final class ValuesIterator extends AbstractIterator> { private final KTypeCursor cursor; private final int max = mask + 1; private int slot = -1; public ValuesIterator() { cursor = new KTypeCursor(); } @Override protected KTypeCursor fetch() { if (slot < max) { for (slot++; slot < max; slot++) { if (!Intrinsics. isEmpty(Intrinsics. cast(keys[slot]))) { cursor.index = slot; cursor.value = Intrinsics. cast(values[slot]); return cursor; } } } if (slot == max && hasEmptyKey) { cursor.index = slot; cursor.value = Intrinsics. cast(values[max]); slot++; return cursor; } return done(); } } /** * {@inheritDoc} */ @Override public KTypeVTypeHashMap clone() { try { /* #if ($templateOnly) */ @SuppressWarnings("unchecked") /* #end */ KTypeVTypeHashMap cloned = (KTypeVTypeHashMap) super.clone(); cloned.keys = keys.clone(); cloned.values = values.clone(); cloned.hasEmptyKey = cloned.hasEmptyKey; cloned.orderMixer = orderMixer.clone(); return cloned; } catch (CloneNotSupportedException e) { throw new RuntimeException(e); } } /** * Convert the contents of this map to a human-friendly string. */ @Override public String toString() { final StringBuilder buffer = new StringBuilder(); buffer.append("["); boolean first = true; for (KTypeVTypeCursor cursor : this) { if (!first) { buffer.append(", "); } buffer.append(cursor.key); buffer.append("=>"); buffer.append(cursor.value); first = false; } buffer.append("]"); return buffer.toString(); } @Override public String visualizeKeyDistribution(int characters) { return KTypeBufferVisualizer.visualizeKeyDistribution(keys, mask, characters); } /** * Creates a hash map from two index-aligned arrays of key-value pairs. */ public static KTypeVTypeHashMap from(KType[] keys, VType[] values) { if (keys.length != values.length) { throw new IllegalArgumentException("Arrays of keys and values must have an identical length."); } KTypeVTypeHashMap map = new KTypeVTypeHashMap<>(keys.length); for (int i = 0; i < keys.length; i++) { map.put(keys[i], values[i]); } return map; } /** * Returns a hash code for the given key. * *

The default implementation mixes the hash of the key with {@link #keyMixer} * to differentiate hash order of keys between hash containers. Helps * alleviate problems resulting from linear conflict resolution in open * addressing.

* *

The output from this function should evenly distribute keys across the * entire integer range.

*/ /*! #if ($templateonly) !*/ @Override public /*! #else protected #end !*/ int hashKey(KType key) { assert !Intrinsics. isEmpty(key); // Handled as a special case (empty slot marker). return BitMixer.mix(key, this.keyMixer); } /** * Validate load factor range and return it. Override and suppress if you need * insane load factors. */ protected double verifyLoadFactor(double loadFactor) { checkLoadFactor(loadFactor, MIN_LOAD_FACTOR, MAX_LOAD_FACTOR); return loadFactor; } /** * Rehash from old buffers to new buffers. */ protected void rehash(KType[] fromKeys, VType[] fromValues) { assert fromKeys.length == fromValues.length && HashContainers.checkPowerOfTwo(fromKeys.length - 1); // Rehash all stored key/value pairs into the new buffers. final KType[] keys = Intrinsics. cast(this.keys); final VType[] values = Intrinsics. cast(this.values); final int mask = this.mask; KType existing; // Copy the zero element's slot, then rehash everything else. int from = fromKeys.length - 1; keys[keys.length - 1] = fromKeys[from]; values[values.length - 1] = fromValues[from]; while (--from >= 0) { if (!Intrinsics. isEmpty(existing = fromKeys[from])) { int slot = hashKey(existing) & mask; while (!Intrinsics. isEmpty(keys[slot])) { slot = (slot + 1) & mask; } keys[slot] = existing; values[slot] = fromValues[from]; } } } /** * Allocate new internal buffers. This method attempts to allocate * and assign internal buffers atomically (either allocations succeed or not). */ protected void allocateBuffers(int arraySize) { assert Integer.bitCount(arraySize) == 1; // Compute new hash mixer candidate before expanding. final int newKeyMixer = this.orderMixer.newKeyMixer(arraySize); // Ensure no change is done if we hit an OOM. KType[] prevKeys = Intrinsics. cast(this.keys); VType[] prevValues = Intrinsics. cast(this.values); try { int emptyElementSlot = 1; this.keys = Intrinsics. newArray(arraySize + emptyElementSlot); this.values = Intrinsics. newArray(arraySize + emptyElementSlot); } catch (OutOfMemoryError e) { this.keys = prevKeys; this.values = prevValues; throw new BufferAllocationException( "Not enough memory to allocate buffers for rehashing: %,d -> %,d", e, this.mask + 1, arraySize); } this.resizeAt = expandAtCount(arraySize, loadFactor); this.keyMixer = newKeyMixer; this.mask = arraySize - 1; } /** * This method is invoked when there is a new key/ value pair to be inserted into * the buffers but there is not enough empty slots to do so. * * New buffers are allocated. If this succeeds, we know we can proceed * with rehashing so we assign the pending element to the previous buffer * (possibly violating the invariant of having at least one empty slot) * and rehash all keys, substituting new buffers at the end. */ protected void allocateThenInsertThenRehash(int slot, KType pendingKey, VType pendingValue) { assert assigned == resizeAt && Intrinsics. isEmpty(Intrinsics. cast(keys[slot])) && !Intrinsics. isEmpty(pendingKey); // Try to allocate new buffers first. If we OOM, we leave in a consistent state. final KType[] prevKeys = Intrinsics. cast(this.keys); final VType[] prevValues = Intrinsics. cast(this.values); allocateBuffers(nextBufferSize(mask + 1, size(), loadFactor)); assert this.keys.length > prevKeys.length; // We have succeeded at allocating new data so insert the pending key/value at // the free slot in the old arrays before rehashing. prevKeys[slot] = pendingKey; prevValues[slot] = pendingValue; // Rehash old keys, including the pending key. rehash(prevKeys, prevValues); } /** * Shift all the slot-conflicting keys and values allocated to * (and including) slot. */ protected void shiftConflictingKeys(int gapSlot) { final KType[] keys = Intrinsics. cast(this.keys); final VType[] values = Intrinsics. cast(this.values); final int mask = this.mask; // Perform shifts of conflicting keys to fill in the gap. int distance = 0; while (true) { final int slot = (gapSlot + (++distance)) & mask; final KType existing = keys[slot]; if (Intrinsics. isEmpty(existing)) { break; } final int idealSlot = hashKey(existing); final int shift = (slot - idealSlot) & mask; if (shift >= distance) { // Entry at this position was originally at or before the gap slot. // Move the conflict-shifted entry to the gap's position and repeat the procedure // for any entries to the right of the current position, treating it // as the new gap. keys[gapSlot] = existing; values[gapSlot] = values[slot]; gapSlot = slot; distance = 0; } } // Mark the last found gap slot without a conflict as empty. keys[gapSlot] = Intrinsics. empty(); values[gapSlot] = Intrinsics. empty(); assigned--; } /*! #if ($TemplateOptions.KTypeGeneric) !*/ /*! #if ($templateonly) !*/ @Override public /*! #else protected #end !*/ boolean equals(Object v1, Object v2) { return (v1 == v2) || (v1 != null && v1.equals(v2)); } /*! #end !*/ } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeVTypeIdentityHashMap.java000066400000000000000000000100121300364116400311400ustar00rootroot00000000000000/*! #set($TemplateOptions.ignored = ($TemplateOptions.KTypePrimitive)) !*/ package com.carrotsearch.hppc; /* #if ($TemplateOptions.VTypeGeneric) */ import java.util.Iterator; import com.carrotsearch.hppc.cursors.*; /* #end */ import static com.carrotsearch.hppc.Containers.*; import static com.carrotsearch.hppc.HashContainers.*; /** * An identity hash map of KType to VType. */ /*! #if ($TemplateOptions.anyGeneric) @SuppressWarnings("all") #end !*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeVTypeIdentityHashMap extends KTypeVTypeHashMap { /** * New instance with sane defaults. */ public KTypeVTypeIdentityHashMap() { this(DEFAULT_EXPECTED_ELEMENTS); } /** * New instance with sane defaults. * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). */ public KTypeVTypeIdentityHashMap(int expectedElements) { this(expectedElements, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause buffer * expansion (inclusive). * @param loadFactor * The load factor for internal buffers. Insane load factors (zero, full capacity) * are rejected by {@link #verifyLoadFactor(double)}. */ public KTypeVTypeIdentityHashMap(int expectedElements, double loadFactor) { this(expectedElements, loadFactor, HashOrderMixing.randomized()); } /** * New instance with the provided defaults. * * @param expectedElements * The expected number of elements guaranteed not to cause a rehash (inclusive). * @param loadFactor * The load factor for internal buffers. Insane load factors (zero, full capacity) * are rejected by {@link #verifyLoadFactor(double)}. * @param orderMixer * Hash key order mixing strategy. See {@link HashOrderMixing} for predefined * implementations. Use constant mixers only if you understand the potential * consequences. */ public KTypeVTypeIdentityHashMap(int expectedElements, double loadFactor, HashOrderMixingStrategy orderMixer) { this.orderMixer = orderMixer; this.loadFactor = verifyLoadFactor(loadFactor); ensureCapacity(expectedElements); } /** * Create a hash map from all key-value pairs of another container. */ public KTypeVTypeIdentityHashMap(KTypeVTypeAssociativeContainer container) { this(container.size()); putAll(container); } @Override public int hashKey(KType key) { assert !Intrinsics. isEmpty(key); // Handled as a special case (empty slot marker). return BitMixer.mix(System.identityHashCode(key), this.keyMixer); } @Override public boolean equals(Object v1, Object v2) { return v1 == v2; } /* #if ($TemplateOptions.VTypeGeneric) */ @Override protected boolean equalElements(KTypeVTypeHashMap other) { if (other.size() != size()) { return false; } Iterator> i = other.iterator(); while (i.hasNext()) { KTypeVTypeCursor c = i.next(); KType key = Intrinsics. cast(c.key); if (!containsKey(key) || !equals(get(key), c.value)) { // Compare values using the same function as keys. return false; } } return true; } /* #end */ /** * Creates a hash map from two index-aligned arrays of key-value pairs. */ public static KTypeVTypeIdentityHashMap from(KType[] keys, VType[] values) { if (keys.length != values.length) { throw new IllegalArgumentException("Arrays of keys and values must have an identical length."); } KTypeVTypeIdentityHashMap map = new KTypeVTypeIdentityHashMap<>(keys.length); for (int i = 0; i < keys.length; i++) { map.put(keys[i], values[i]); } return map; } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeVTypeMap.java000066400000000000000000000166471300364116400266460ustar00rootroot00000000000000package com.carrotsearch.hppc; import com.carrotsearch.hppc.cursors.KTypeVTypeCursor; /** * An associative container with unique binding from keys to a single value. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeVTypeMap extends KTypeVTypeAssociativeContainer { /** * @return Returns the value associated with the given key or the default * value for the key type, if the key is not associated with any * value. * * Important note: For primitive type values, the value * returned for a non-existing key may not be the default value of the * primitive type (it may be any value previously assigned to that * slot). */ public VType get(KType key); /** * @return Returns the value associated with the given key or the provided * default value if the key is not associated with any value. */ public VType getOrDefault(KType key, VType defaultValue); /** * Place a given key and value in the container. * * @return The value previously stored under the given key in the map is * returned. */ public VType put(KType key, VType value); /** * Puts all keys from another container to this map, replacing the values of * existing keys, if such keys are present. * * @return Returns the number of keys added to the map as a result of this * call (not previously present in the map). Values of existing keys * are overwritten. */ public int putAll(KTypeVTypeAssociativeContainer container); /** * Puts all keys from an iterable cursor to this map, replacing the values of * existing keys, if such keys are present. * * @return Returns the number of keys added to the map as a result of this * call (not previously present in the map). Values of existing keys * are overwritten. */ public int putAll(Iterable> iterable); /*! #if ($TemplateOptions.VTypePrimitive) !*/ /** * If key exists, putValue is inserted into the map, * otherwise any existing value is incremented by additionValue. * * @param key * The key of the value to adjust. * @param putValue * The value to put if key does not exist. * @param incrementValue * The value to add to the existing value if key exists. * @return Returns the current value associated with key (after * changes). */ public VType putOrAdd(KType key, VType putValue, VType incrementValue); /*! #end !*/ /*! #if ($TemplateOptions.VTypePrimitive) !*/ /** * An equivalent of calling * *
   * putOrAdd(key, additionValue, additionValue);
   * 
* * @param key * The key of the value to adjust. * @param additionValue * The value to put or add to the existing value if key * exists. * @return Returns the current value associated with key (after * changes). */ public VType addTo(KType key, VType additionValue); /*! #end !*/ /** * Remove all values at the given key. The default value for the key type is * returned if the value does not exist in the map. */ public VType remove(KType key); /** * Compares the specified object with this set for equality. Returns * true if and only if the specified object is also a * {@link KTypeVTypeMap} and both objects contains exactly the same key-value * pairs. */ public boolean equals(Object obj); /** * @return A hash code of elements stored in the map. The hash code is defined * as a sum of hash codes of keys and values stored within the set). * Because sum is commutative, this ensures that different order of * elements in a set does not affect the hash code. */ public int hashCode(); /** * Returns a logical "index" of a given key that can be used to speed up * follow-up value setters or getters in certain scenarios (conditional * logic). * * The semantics of "indexes" are not strictly defined. Indexes may (and * typically won't be) contiguous. * * The index is valid only between map modifications (it will not be affected * by read-only operations like iteration or value retrievals). * * @see #indexExists * @see #indexGet * @see #indexInsert * @see #indexReplace * * @param key * The key to locate in the map. * @return A non-negative value of the logical "index" of the key in the map * or a negative value if the key did not exist. */ public int indexOf(KType key); /** * @see #indexOf * * @param index * The index of a given key, as returned from {@link #indexOf}. * @return Returns true if the index corresponds to an existing * key or false otherwise. This is equivalent to checking whether the * index is a positive value (existing keys) or a negative value * (non-existing keys). */ public boolean indexExists(int index); /** * Returns the value associated with an existing key. * * @see #indexOf * * @param index * The index of an existing key. * @return Returns the value currently associated with the key. * @throws AssertionError * If assertions are enabled and the index does not correspond to an * existing key. */ public VType indexGet(int index); /** * Replaces the value associated with an existing key and returns any previous * value stored for that key. * * @see #indexOf * * @param index * The index of an existing key. * @return Returns the previous value associated with the key. * @throws AssertionError * If assertions are enabled and the index does not correspond to an * existing key. */ public VType indexReplace(int index, VType newValue); /** * Inserts a key-value pair for a key that is not present in the map. This * method may help in avoiding double recalculation of the key's hash. * * @see #indexOf * * @param index * The index of a previously non-existing key, as returned from * {@link #indexOf}. * @throws AssertionError * If assertions are enabled and the index corresponds to an * existing key. */ public void indexInsert(int index, KType key, VType value); /** * Clear all keys and values in the container. * * @see #release() */ public void clear(); /** * Removes all elements from the collection and additionally releases any * internal buffers. Typically, if the object is to be reused, a simple * {@link #clear()} should be a better alternative since it'll avoid * reallocation. * * @see #clear() */ public void release(); /** * Visually depict the distribution of keys. * * @param characters * The number of characters to "squeeze" the entire buffer into. * @return Returns a sequence of characters where '.' depicts an empty * fragment of the internal buffer and 'X' depicts full or nearly full * capacity within the buffer's range and anything between 1 and 9 is between. */ public String visualizeKeyDistribution(int characters); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/KTypeVTypeScatterMap.java000066400000000000000000000034021300364116400301550ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.Containers.*; import static com.carrotsearch.hppc.HashContainers.*; /** * Same as {@link KTypeVTypeHashMap} but does not implement per-instance * key mixing strategy and uses a simpler (faster) bit distribution function. * *

Note: read about * important differences * between hash and scatter sets.

*/ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeVTypeScatterMap extends KTypeVTypeHashMap { /** * New instance with sane defaults. */ public KTypeVTypeScatterMap() { this(DEFAULT_EXPECTED_ELEMENTS); } /** * New instance with sane defaults. */ public KTypeVTypeScatterMap(int expectedElements) { this(expectedElements, DEFAULT_LOAD_FACTOR); } /** * New instance with sane defaults. */ @SuppressWarnings("deprecation") public KTypeVTypeScatterMap(int expectedElements, double loadFactor) { super(expectedElements, loadFactor, HashOrderMixing.none()); } /*! #if ($templateonly) !*/ @Override public /*! #else protected #end !*/ int hashKey(KType key) { return BitMixer.mixPhi(key); } /** * Creates a hash map from two index-aligned arrays of key-value pairs. */ public static KTypeVTypeScatterMap from(KType[] keys, VType[] values) { if (keys.length != values.length) { throw new IllegalArgumentException("Arrays of keys and values must have an identical length."); } KTypeVTypeScatterMap map = new KTypeVTypeScatterMap<>(keys.length); for (int i = 0; i < keys.length; i++) { map.put(keys[i], values[i]); } return map; } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/cursors/000077500000000000000000000000001300364116400250035ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/cursors/KTypeCursor.java000066400000000000000000000011231300364116400300750ustar00rootroot00000000000000package com.carrotsearch.hppc.cursors; /** * A cursor over a collection of KTypes. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public final class KTypeCursor { /** * The current value's index in the container this cursor belongs to. The * meaning of this index is defined by the container (usually it will be an * index in the underlying storage buffer). */ public int index; /** * The current value. */ public KType value; @Override public String toString() { return "[cursor, index: " + index + ", value: " + value + "]"; } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/cursors/KTypeVTypeCursor.java000066400000000000000000000013211300364116400310650ustar00rootroot00000000000000package com.carrotsearch.hppc.cursors; /** * A cursor over entries of an associative container (KType keys and VType * values). */ /*! ${TemplateOptions.generatedAnnotation} !*/ public final class KTypeVTypeCursor { /** * The current key and value's index in the container this cursor belongs to. * The meaning of this index is defined by the container (usually it will be * an index in the underlying storage buffer). */ public int index; /** * The current key. */ public KType key; /** * The current value. */ public VType value; @Override public String toString() { return "[cursor, index: " + index + ", key: " + key + ", value: " + value + "]"; } } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/predicates/000077500000000000000000000000001300364116400254265ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/predicates/KTypePredicate.java000066400000000000000000000003551300364116400311510ustar00rootroot00000000000000package com.carrotsearch.hppc.predicates; /** * A predicate that applies to KType objects. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypePredicate { public boolean apply(KType value); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/predicates/KTypeVTypePredicate.java000066400000000000000000000004261300364116400321400ustar00rootroot00000000000000package com.carrotsearch.hppc.predicates; /** * A predicate that applies to KType, VType pairs. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeVTypePredicate { public boolean apply(KType key, VType value); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/procedures/000077500000000000000000000000001300364116400254565ustar00rootroot00000000000000hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/procedures/KTypeProcedure.java000066400000000000000000000003521300364116400312260ustar00rootroot00000000000000package com.carrotsearch.hppc.procedures; /** * A procedure that applies to KType objects. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeProcedure { public void apply(KType value); } hppc-0.7.2/hppc/src/main/templates/com/carrotsearch/hppc/procedures/KTypeVTypeProcedure.java000066400000000000000000000004231300364116400322150ustar00rootroot00000000000000package com.carrotsearch.hppc.procedures; /** * A procedure that applies to KType, VType pairs. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public interface KTypeVTypeProcedure { public void apply(KType key, VType value); } hppc-0.7.2/hppc/src/test/000077500000000000000000000000001300364116400151505ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/000077500000000000000000000000001300364116400160715ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/com/000077500000000000000000000000001300364116400166475ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/com/carrotsearch/000077500000000000000000000000001300364116400213275ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/000077500000000000000000000000001300364116400222615ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/APIExpectationsTest.java000066400000000000000000000177221300364116400267750ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; import org.assertj.core.api.Assertions; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * Various API expectations from generated classes. */ public class APIExpectationsTest extends RandomizedTest { public volatile int [] t1; @Test public void testRemoveAllFromMap() { ObjectIntHashMap list = new ObjectIntHashMap<>(); list.put(1, 1); list.put(2, 2); list.put(3, 3); // Same type. ObjectHashSet other1 = new ObjectHashSet<>(); other1.add(1); list.removeAll(other1); // Supertype. ObjectArrayList other2 = new ObjectArrayList<>(); other2.add(1); list.removeAll(other2); // Object ObjectArrayList other3 = new ObjectArrayList<>(); other3.add(1); list.removeAll(other3); } @Test public void testRemoveAllWithLookupContainer() { ObjectArrayList list = new ObjectArrayList<>(); list.add(1); list.add(2); list.add(3); // Same type. ObjectHashSet other1 = new ObjectHashSet<>(); other1.add(1); list.removeAll(other1); // Supertype. ObjectHashSet other2 = new ObjectHashSet<>(); other2.add(1); list.removeAll(other2); // Object ObjectHashSet other3 = new ObjectHashSet<>(); other3.add(1); list.removeAll(other3); } @Test public void testToArrayWithClass() { ObjectArrayDeque l1 = ObjectArrayDeque.from(1, 2, 3); Integer[] result1 = l1.toArray(Integer.class); assertArrayEquals(new Integer [] {1, 2, 3}, result1); Number[] result2 = l1.toArray(Number.class); Assertions.assertThat(result2).isExactlyInstanceOf(Number[].class); assertArrayEquals(new Number [] {1, 2, 3}, result2); } @Test public void testEqualElementsDifferentGenericType() { ObjectArrayList l1 = new ObjectArrayList(); ObjectArrayList l2 = new ObjectArrayList(); Assertions.assertThat(l1.equalElements(l2)).isTrue(); Assertions.assertThat(l2.equalElements(l1)).isTrue(); } @Test public void testArrayListEqualsWithOverridenComparisonMethod() { class IntegerIdentityList extends ObjectArrayList { @Override protected boolean equals(Object k1, Object k2) { return k1 == k2; } }; IntegerIdentityList l1 = new IntegerIdentityList(); IntegerIdentityList l2 = new IntegerIdentityList(); IntegerIdentityList l3 = new IntegerIdentityList(); l1.add(1, 2, 3); l2.add(1, 2, 3); l3.add(1, 2, new Integer(3)); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1.hashCode()).isEqualTo(l3.hashCode()); Assertions.assertThat(l1.equalElements(l2)).isTrue(); Assertions.assertThat(l1.equalElements(l3)).isFalse(); } @Test public void testArrayDequeEqualsWithOverridenComparisonMethod() { class IntegerIdentityDeque extends ObjectArrayDeque { @Override protected boolean equals(Object k1, Object k2) { return k1 == k2; } }; IntegerIdentityDeque l1 = new IntegerIdentityDeque(); IntegerIdentityDeque l2 = new IntegerIdentityDeque(); IntegerIdentityDeque l3 = new IntegerIdentityDeque(); l1.addLast(1, 2, 3); l2.addLast(1, 2, 3); l3.addLast(1, 2, new Integer(3)); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1.hashCode()).isEqualTo(l3.hashCode()); Assertions.assertThat(l1.equalElements(l2)).isTrue(); Assertions.assertThat(l1.equalElements(l3)).isFalse(); } @Test public void testPrimitiveToArray() { t1 = IntArrayList.from(1, 2, 3).toArray(); t1 = IntStack.from(1, 2, 3).toArray(); t1 = IntArrayDeque.from(1, 2, 3).toArray(); t1 = IntHashSet.from(1, 2, 3).toArray(); t1 = IntObjectHashMap.from( new int [] {1, 2}, new Long [] {1L, 2L}).keys().toArray(); } @Test @SuppressWarnings("unused") public void testNewInstance() { IntArrayList v1 = new IntArrayList(); ObjectArrayList v2 = new ObjectArrayList<>(); ObjectArrayList v3 = new ObjectArrayList<>(); IntStack v4 = new IntStack(); ObjectStack v5 = new ObjectStack<>(); ObjectStack v6 = new ObjectStack<>(); IntHashSet v7 = new IntHashSet(); ObjectHashSet v8 = new ObjectHashSet<>(); ObjectHashSet v9 = new ObjectHashSet<>(); IntArrayDeque v10 = new IntArrayDeque(); ObjectArrayDeque v11 = new ObjectArrayDeque<>(); ObjectArrayDeque v12 = new ObjectArrayDeque<>(); IntIntHashMap v13 = new IntIntHashMap(); ObjectIntHashMap v14 = new ObjectIntHashMap<>(); IntObjectHashMap v15 = new IntObjectHashMap<>(); } @Test public void testObjectToArray() { isObjectArray(ObjectArrayList.from(1, 2, 3).toArray()); isObjectArray(ObjectStack.from(1, 2, 3).toArray()); isObjectArray(ObjectArrayDeque.from(1, 2, 3).toArray()); isObjectArray(ObjectHashSet.from(1, 2, 3).toArray()); isObjectArray(ObjectObjectHashMap.from( new Integer [] {1, 2}, new Long [] {1L, 2L}).keys().toArray()); } @Test public void testWithClassToArray() { isIntegerArray(ObjectArrayList.from(1, 2, 3).toArray(Integer.class)); isIntegerArray(ObjectStack.from(1, 2, 3).toArray(Integer.class)); isIntegerArray(ObjectArrayDeque.from(1, 2, 3).toArray(Integer.class)); isIntegerArray(ObjectHashSet.from(1, 2, 3).toArray(Integer.class)); isIntegerArray(ObjectObjectHashMap.from( new Integer [] {1, 2}, new Long [] {1L, 2L}).keys().toArray(Integer.class)); } @Test public void testWildcards() { ObjectArrayList t = ObjectArrayList.from(1, 2, 3); isTypeArray(Number.class, t.toArray(Number.class)); t = ObjectArrayList.from(1L, 2L, 3L); isTypeArray(Number.class, t.toArray(Number.class)); } @Test public void testPutOrAddOnEqualKeys() { ObjectIntHashMap map = new ObjectIntHashMap<>(); Integer k1 = 1; Integer k1b = new Integer(k1.intValue()); assertTrue(k1 != k1b); assertEquals2(1, map.putOrAdd(k1, 1, 2)); assertTrue(map.containsKey(k1b)); assertEquals2(3, map.putOrAdd(k1b, 1, 2)); } /* * Even with two different hash distribution keys the * result of hashCode() should be the same. */ @Test public void testHashCodeOverflowIdentical() { IntHashSet l0 = new IntHashSet(0, 0.5, HashOrderMixing.constant(0xcafe)); IntHashSet l1 = new IntHashSet(0, 0.5, HashOrderMixing.constant(0xbabe)); for (int i = 100000 + randomIntBetween(0, 100000); i-- > 0;) { l0.add(i); l1.add(i); } assertEquals(l0.hashCode(), l1.hashCode()); assertEquals(l0, l1); } /** * Check if the array is indeed of Object component type. */ private void isObjectArray(Object [] array) { isTypeArray(Object.class, array); } /** * */ private void isTypeArray(Class clazz, Object [] array) { assertEquals(clazz, array.getClass().getComponentType()); } /** * Check if the array is indeed of Integer component type. */ private void isIntegerArray(Integer [] array) { isTypeArray(Integer.class, array); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/AbstractIteratorTest.java000066400000000000000000000037021300364116400272430ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class AbstractIteratorTest { public static class RangeIterator extends AbstractIterator { int start; int count; public RangeIterator(int start, int count) { this.start = start; this.count = count; } @Override protected Integer fetch() { if (count == 0) { return done(); } count--; return start++; } } @Test public void testEmpty() { RangeIterator i = new RangeIterator(1, 0); assertFalse(i.hasNext()); assertFalse(i.hasNext()); } @Test(expected = NoSuchElementException.class) public void testEmptyExceptionOnNext() { RangeIterator i = new RangeIterator(1, 0); i.next(); } @Test public void testNonEmpty() { RangeIterator i = new RangeIterator(1, 1); assertTrue(i.hasNext()); assertTrue(i.hasNext()); i.next(); assertFalse(i.hasNext()); assertFalse(i.hasNext()); try { i.next(); fail(); } catch (NoSuchElementException e) { // expected. } } @Test public void testValuesAllRight() { assertEquals(Arrays.asList(1), addAll(new RangeIterator(1, 1))); assertEquals(Arrays.asList(1, 2), addAll(new RangeIterator(1, 2))); assertEquals(Arrays.asList(1, 2, 3), addAll(new RangeIterator(1, 3))); } private static List addAll(Iterator i) { List t = new ArrayList(); while (i.hasNext()) t.add(i.next()); return t; } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/BitSetTest.java000066400000000000000000000142321300364116400251600ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.*; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.cursors.IntCursor; import com.carrotsearch.hppc.cursors.LongCursor; import com.carrotsearch.hppc.predicates.IntPredicate; import com.carrotsearch.hppc.predicates.LongPredicate; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * Regression tests against java.util.BitSet. */ public class BitSetTest extends RandomizedTest { private BitSet hppc; private java.util.BitSet jre; /* */ @Before public void before() { hppc = new BitSet(); jre = new java.util.BitSet(); } /** * Test to string conversion. */ @Test public void testToString() { assertEquals(jre.toString(), hppc.toString()); for (int i : new int [] {1, 10, 20, 5000}) { hppc.set(i); jre.set(i); } assertEquals(jre.toString(), hppc.toString()); } /** * Test random insertions into the bitset. */ @Test public void testAgainstJREBitSet() throws Exception { final int rounds = 100; final int bits = 1000; final int bitSpace = bits * 10; for (int i = 0; i < rounds; i++) { for (int bit = 0; bit < bits; bit++) { int index = randomInt(bitSpace); jre.set(index); hppc.set(index); assertEquals(jre.length(), hppc.length()); } assertSame(jre, hppc); assertIntLookupContainer(jre, hppc.asIntLookupContainer()); assertLongLookupContainer(jre, hppc.asLongLookupContainer()); } } /** */ @Test public void testHashCodeEquals() { BitSet bs1 = new BitSet(200); BitSet bs2 = new BitSet(64); bs1.set(3); bs2.set(3); assertEquals(bs1, bs2); assertEquals(bs1.hashCode(), bs2.hashCode()); } /** * Assert that the two bitsets are identical. */ private void assertSame(final java.util.BitSet jre, BitSet hppc) { // Cardinality and emptiness status. assertEquals(jre.cardinality(), hppc.cardinality()); assertEquals(jre.isEmpty(), hppc.isEmpty()); // Check bit-by-bit. for (int i = 0; i < jre.size() - 1; i++) assertEquals(jre.get(i), hppc.get(i)); // Check iterator indices. int i = jre.nextSetBit(0); int j = hppc.nextSetBit(0); BitSetIterator k = hppc.iterator(); while (i >= 0) { assertEquals(i, j); assertEquals(i, k.nextSetBit()); i = jre.nextSetBit(i + 1); j = hppc.nextSetBit(j + 1); } assertEquals(-1, k.nextSetBit()); assertEquals(-1, j); } private void assertIntLookupContainer(final java.util.BitSet jre, IntLookupContainer ilc) { int i, j; // Check adapter to IntLookupContainer assertEquals(ilc.size(), jre.cardinality()); i = jre.nextSetBit(0); Iterator ilcCursor = ilc.iterator(); while (i >= 0) { assertTrue(ilcCursor.hasNext()); IntCursor c = ilcCursor.next(); assertEquals(i, c.index); assertEquals(i, c.value); i = jre.nextSetBit(i + 1); } assertEquals(-1, i); assertFalse(ilcCursor.hasNext()); try { ilcCursor.next(); fail(); } catch (NoSuchElementException e) { // expected. } // Check toArray() int [] setIndexes = ilc.toArray(); int [] expected = new int [jre.cardinality()]; for (j = 0, i = jre.nextSetBit(0); i >= 0; i = jre.nextSetBit(i + 1)) { expected[j++] = i; } assertArrayEquals(expected, setIndexes); // Test for-each predicates. ilc.forEach(new IntPredicate() { int i = jre.nextSetBit(0); public boolean apply(int setBit) { assertEquals(i, setBit); i = jre.nextSetBit(i + 1); return true; } }); // Test contains. for (i = 0; i < jre.size() + 65; i++) { assertEquals(hppc.get(i), ilc.contains(i)); } // IntLookupContainer must not throw exceptions on negative arguments. ilc.contains(-1); } private void assertLongLookupContainer(final java.util.BitSet jre, LongLookupContainer llc) { int i, j; // Check adapter to IntLookupContainer assertEquals(llc.size(), jre.cardinality()); i = jre.nextSetBit(0); Iterator llcCursor = llc.iterator(); while (i >= 0) { assertTrue(llcCursor.hasNext()); LongCursor c = llcCursor.next(); assertEquals(i, c.index); assertEquals(i, c.value); i = jre.nextSetBit(i + 1); } assertEquals(-1, i); assertFalse(llcCursor.hasNext()); try { llcCursor.next(); fail(); } catch (NoSuchElementException e) { // expected. } // Check toArray() long [] setIndexes = llc.toArray(); long [] expected = new long [jre.cardinality()]; for (j = 0, i = jre.nextSetBit(0); i >= 0; i = jre.nextSetBit(i + 1)) { expected[j++] = i; } assertArrayEquals(expected, setIndexes); // Test for-each predicates. llc.forEach(new LongPredicate() { int i = jre.nextSetBit(0); public boolean apply(long setBit) { assertEquals(i, setBit); i = jre.nextSetBit(i + 1); return true; } }); // Test contains. for (i = 0; i < jre.size() + 65; i++) { assertEquals(hppc.get(i), llc.contains(i)); } // IntLookupContainer must not throw exceptions on negative arguments. llc.contains(-1); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/BoundedProportionalArraySizingStrategyTest.java000066400000000000000000000022441300364116400336650ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.assertEquals; import org.junit.Test; /** * Test case for bounded proportional sizing strategy. */ public class BoundedProportionalArraySizingStrategyTest { private BoundedProportionalArraySizingStrategy resizer; @Test(expected = BufferAllocationException.class) public void testBeyondIntRange() { resizer = new BoundedProportionalArraySizingStrategy(); resizer.grow( BoundedProportionalArraySizingStrategy.MAX_ARRAY_LENGTH, BoundedProportionalArraySizingStrategy.MAX_ARRAY_LENGTH, 1); } @Test public void testExactIntRange() { resizer = new BoundedProportionalArraySizingStrategy(); int size = BoundedProportionalArraySizingStrategy.MAX_ARRAY_LENGTH - 2; size = resizer.grow(size, size, 1); assertEquals(BoundedProportionalArraySizingStrategy.MAX_ARRAY_LENGTH, size); try { size = resizer.grow(size, size, 1); throw new RuntimeException("Unexpected."); } catch (BufferAllocationException e) { // Expected. } } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/ContainersTest.java000066400000000000000000000020271300364116400260720ustar00rootroot00000000000000package com.carrotsearch.hppc; import org.assertj.core.api.Assertions; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; /* */ public class ContainersTest extends RandomizedTest { @Rule public final TestRule rules = RuleChain.outerRule( new SystemPropertiesRestoreRule()); @After public void resetState() { Containers.test$reset(); } @Test public void testNoTestsSeed() { System.clearProperty("tests.seed"); Containers.test$reset(); Assertions.assertThat(Containers.randomSeed64()) .isNotEqualTo(Containers.randomSeed64()); } @Test public void testWithTestsSeed() { System.setProperty("tests.seed", "deadbeef"); Containers.test$reset(); Assertions.assertThat(Containers.randomSeed64()) .isEqualTo(Containers.randomSeed64()); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/EntryShiftingOnRemovalTest.java000066400000000000000000000020431300364116400304030ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.HashSet; import java.util.Set; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import com.carrotsearch.randomizedtesting.annotations.Repeat; public class EntryShiftingOnRemovalTest extends RandomizedTest { @Test @Repeat(iterations = 10) public void testRemoveSanity() { @SuppressWarnings("deprecation") IntHashSet v = new IntHashSet(8, 0.5d, HashOrderMixing.none()) { @Override protected int hashKey(int key) { return key & 0xff; } }; Set ref = new HashSet(); for (int i = 0; i < 4; i++) { int r = randomInt() & 0xffff; ref.add(r); v.add(r); } Integer[] array = ref.toArray(new Integer[ref.size()]); int remove = randomFrom(array); ref.remove(remove); v.remove(remove); int[] actual = v.toArray(); assertTrue(actual.length == ref.size()); for (Integer ri : ref) { assertTrue(v.contains(ri)); } } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/HashCollisionsClusteringTest.java000066400000000000000000000113421300364116400307470ustar00rootroot00000000000000package com.carrotsearch.hppc; import java.util.Locale; import java.util.concurrent.TimeUnit; import org.junit.Test; import com.carrotsearch.hppc.cursors.IntCursor; import com.carrotsearch.randomizedtesting.RandomizedTest; public class HashCollisionsClusteringTest extends RandomizedTest { private static boolean debugging = false; /** @see "http://issues.carrot2.org/browse/HPPC-80" */ @Test public void testHashSetClusteringOnRehash() { IntHashSet source = new IntHashSet(0, 0.9d); for (int i = 1250000; i-- != 0;) { source.add(i); } IntHashSet target = new IntHashSet(0, 0.9d); int i = 0; long start = System.currentTimeMillis(); long deadline = start + TimeUnit.SECONDS.toMillis(3); for (IntCursor c : source) { target.add(c.value); if ((i++ % 5000) == 0) { System.out.println(String.format(Locale.ROOT, "Keys: %7d, %5d ms.", i, System.currentTimeMillis() - start)); if (System.currentTimeMillis() >= deadline) { fail("Takes too long, something is wrong. Added " + i + " keys out of " + source.size()); } } } } /** @see "http://issues.carrot2.org/browse/HPPC-80" */ @Test public void testHashMapClusteringOnRehash() { IntIntHashMap a = new IntIntHashMap(); for (int i = 10000000; i-- != 0;) { a.put(i, 0); } IntIntHashMap b2 = new IntIntHashMap(); b2.putAll(a); } /** */ @Test public void testHashSetClusteringAtFront() { int keys = 500000; IntHashSet target = new IntHashSet(keys, 0.9) { @Override protected void allocateBuffers(int arraySize) { super.allocateBuffers(arraySize); System.out.println("Rehashed to: " + arraySize); } }; int expandAtCount = HashContainers.expandAtCount(target.keys.length - 1, 0.9); int fillUntil = expandAtCount - 100000; IntHashSet source = new IntHashSet(keys, 0.9); int unique = 0; while (source.size() < expandAtCount - 1) { source.add(unique++); } System.out.println("Source filled up."); while (target.size() < fillUntil) { target.add(unique++); } System.out.println("Target filled up."); assertEquals(source.keys.length, target.keys.length); long start = System.currentTimeMillis(); long deadline = start + TimeUnit.SECONDS.toMillis(5); int i = 0; for (IntCursor c : source) { target.add(c.value); if ((i++ % 5000) == 0) { if (source.keys.length == target.keys.length) { System.out.println(String.format(Locale.ROOT, "Keys: %7d, %5d ms.: %s", i, System.currentTimeMillis() - start, debugging ? target.visualizeKeyDistribution(80) : "--")); } if (System.currentTimeMillis() >= deadline) { fail("Takes too long, something is wrong. Added " + i + " keys out of " + source.size()); } } } } /** */ @Test public void testHashSetClusteringAtFront2() { int keys = 100000; int expected = keys * 5; IntHashSet target = new IntHashSet(expected, 0.9) { @Override protected void allocateBuffers(int arraySize) { super.allocateBuffers(arraySize); System.out.println("[Rehashed to: " + arraySize + "]"); } }; long deadline = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(15); IntHashSet source = new IntHashSet(expected, 0.9); int unique = 0; for (int i = 0; i < 200; i++) { source.clear(); while (source.size() < keys) { source.add(unique++); } long s = System.currentTimeMillis(); int firstSubsetOfKeys = 5000; for (IntCursor c : source) { target.add(c.value); if (firstSubsetOfKeys-- == 0) break; } long e = System.currentTimeMillis(); System.out.println(String.format(Locale.ROOT, "Keys: %7d, %5d ms. (%5d): %s", i, e - s, deadline - e, debugging ? target.visualizeKeyDistribution(80) : "--")); if (System.currentTimeMillis() > deadline) { fail("Takes too long, something is wrong. Added " + i + " batches."); } } } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/HashContainersTest.java000066400000000000000000000026131300364116400266770ustar00rootroot00000000000000package com.carrotsearch.hppc; import org.junit.Test; import com.carrotsearch.randomizedtesting.RandomizedTest; import static com.carrotsearch.hppc.HashContainers.*; public class HashContainersTest extends RandomizedTest { /* */ @Test public void testCapacityCalculations() { assertEquals(MIN_HASH_ARRAY_LENGTH, minBufferSize(0, 0.5f)); assertEquals(MIN_HASH_ARRAY_LENGTH, minBufferSize(1, 0.5f)); assertEquals(0x20, minBufferSize(0x10, 0.5f)); assertEquals(0x40, minBufferSize(0x10, 0.49f)); int maxCapacity = maxElements(HashContainers.MAX_LOAD_FACTOR); assertEquals(0x40000000, minBufferSize(maxCapacity, MAX_LOAD_FACTOR)); // This would fill the array fully, validating the invariant, but should // be possible without reallocating the buffer. minBufferSize(maxCapacity + 1, MAX_LOAD_FACTOR); assertEquals(maxCapacity + 1, expandAtCount(MAX_HASH_ARRAY_LENGTH, MAX_LOAD_FACTOR)); try { // This should be impossible because it'd create a negative-sized array. minBufferSize(maxCapacity + 2, MAX_LOAD_FACTOR); fail(); } catch (BufferAllocationException e) { // Expected. } } /* */ @Test public void testLoadFactorOne() { assertEquals(0x100, minBufferSize(0x80, 1d)); assertEquals(0x7f, expandAtCount(0x80, 1d)); assertEquals(0xff, expandAtCount(0x100, 1d)); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/IdentityMapsTest.java000066400000000000000000000043421300364116400264010ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.*; import org.junit.Test; public class IdentityMapsTest { @Test public void testSanity() { ObjectCharIdentityHashMap m1 = new ObjectCharIdentityHashMap<>(); Integer a, b; m1.put(a = new Integer(1), 'a'); m1.put(b = new Integer(1), 'b'); assertEquals('a', m1.get(a)); assertEquals('b', m1.get(b)); assertEquals(2, m1.size()); ObjectCharIdentityHashMap m2 = new ObjectCharIdentityHashMap<>(); m2.put(b, 'b'); m2.put(a, 'a'); assertEquals(m1, m2); assertEquals(m2, m1); m2.remove(a); m2.put(new Integer(1), 'a'); assertNotEquals(m1, m2); assertNotEquals(m2, m1); } @Test public void testEqualsComparesValuesByReference() { ObjectObjectIdentityHashMap m1 = new ObjectObjectIdentityHashMap<>(); ObjectObjectIdentityHashMap m2 = new ObjectObjectIdentityHashMap<>(); String a = "a"; String av = "av"; String b = "b"; String bv = "bv"; m1.put(a, av); m1.put(b, bv); m2.put(b, bv); m2.put(a, av); assertEquals(m1, m2); assertEquals(m2, m1); m2.put(a, new String(av)); assertNotEquals(m1, m2); assertNotEquals(m2, m1); } @Test public void testNaNsInValues() { ObjectDoubleIdentityHashMap m1 = new ObjectDoubleIdentityHashMap<>(); ObjectDoubleIdentityHashMap m2 = new ObjectDoubleIdentityHashMap<>(); String a = "a"; Double av = Double.NaN; m1.put(a, av); m2.put(a, av); assertEquals(m1, m2); assertEquals(m2, m1); // value storage is an array of primitives, so NaNs should be equal, even though the object // was different. m2.put(a, new Double(Double.NaN)); assertEquals(m1, m2); assertEquals(m2, m1); DoubleContainer values = m1.values(); assertTrue(values.contains(Double.NaN)); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/IdentitySetsTest.java000066400000000000000000000022701300364116400264150ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.*; import org.assertj.core.api.Assertions; import org.junit.Test; public class IdentitySetsTest { @Test public void testSanity() { ObjectIdentityHashSet m1 = new ObjectIdentityHashSet<>(); Integer a, b; Assertions.assertThat(m1.add(a = new Integer(1))).isTrue(); Assertions.assertThat(m1.add(a)).isFalse(); Assertions.assertThat(m1.add(b = new Integer(1))).isTrue(); Assertions.assertThat(m1.add(b)).isFalse(); Assertions.assertThat(m1.contains(a)).isTrue(); Assertions.assertThat(m1.contains(b)).isTrue(); Assertions.assertThat(m1.contains(new Integer(1))).isFalse(); Assertions.assertThat(m1.contains(null)).isFalse(); Assertions.assertThat(m1.add(null)).isTrue(); Assertions.assertThat(m1.add(null)).isFalse(); assertEquals(3, m1.size()); ObjectIdentityHashSet m2 = new ObjectIdentityHashSet<>(); m2.addAll(m1); Assertions.assertThat(m1).isEqualTo(m2); m2.remove(a); Assertions.assertThat(m1).isNotEqualTo(m2); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/NaNCornerCaseTest.java000066400000000000000000000064751300364116400264210ustar00rootroot00000000000000package com.carrotsearch.hppc; import org.junit.Assert; import org.junit.Test; public class NaNCornerCaseTest { /** @see "http://issues.carrot2.org/browse/HPPC-93" */ @Test public void testNaNAsDoubleKey() { DoubleObjectMap map = new DoubleObjectHashMap<>(); map.put(Double.NaN, "a"); map.put(Double.NaN, "b"); Assert.assertEquals(1, map.size()); Assert.assertEquals("b", map.get(Double.NaN)); map.put(Double.longBitsToDouble(0xfff8000000000000L), "c"); Assert.assertEquals(1, map.size()); Assert.assertEquals("c", map.get(Double.NaN)); Assert.assertEquals( (Double) map.keys().iterator().next().value, (Double) Double.NaN); DoubleHashSet set = new DoubleHashSet(); set.add(Double.NaN); set.add(Double.NaN); set.add(Double.longBitsToDouble(0xfff8000000000000L)); Assert.assertEquals(1, set.size()); Assert.assertEquals( (Double) set.iterator().next().value, (Double) Double.NaN); } /** @see "http://issues.carrot2.org/browse/HPPC-93" */ @Test public void testNaNAsFloatKey() { FloatObjectMap map = new FloatObjectHashMap<>(); map.put(Float.NaN, "a"); map.put(Float.NaN, "b"); Assert.assertEquals(1, map.size()); Assert.assertEquals("b", map.get(Float.NaN)); map.put(Float.intBitsToFloat(0xfff80000), "c"); Assert.assertEquals(1, map.size()); Assert.assertEquals("c", map.get(Float.NaN)); Assert.assertEquals( (Float) map.keys().iterator().next().value, (Float) Float.NaN); FloatHashSet set = new FloatHashSet(); set.add(Float.NaN); set.add(Float.NaN); set.add(Float.intBitsToFloat(0xfff80000)); Assert.assertEquals(1, set.size()); Assert.assertEquals( (Float) set.iterator().next().value, (Float) Float.NaN); } /** @see "http://issues.carrot2.org/browse/HPPC-93" */ @Test public void testNaNAsValue() { { IntDoubleMap m1 = new IntDoubleHashMap(); m1.put(1, Double.NaN); IntDoubleMap m2 = new IntDoubleHashMap(); m2.put(1, Double.NaN); Assert.assertEquals(m1, m2); } { IntFloatMap m1 = new IntFloatHashMap(); m1.put(1, Float.NaN); IntFloatMap m2 = new IntFloatHashMap(); m2.put(1, Float.NaN); Assert.assertEquals(m1, m2); } { FloatArrayList list = new FloatArrayList(); Assert.assertFalse(list.contains(Float.NaN)); list.add(0, Float.NaN, 1); Assert.assertTrue(list.contains(Float.NaN)); } { DoubleArrayList list = new DoubleArrayList(); Assert.assertFalse(list.contains(Double.NaN)); list.add(0, Double.NaN, 1); Assert.assertTrue(list.contains(Double.NaN)); } { DoubleArrayList l1 = new DoubleArrayList(); l1.add(0, Double.NaN, 1); DoubleArrayList l2 = new DoubleArrayList(); l2.add(0, Double.NaN, 1); Assert.assertEquals(l1, l2); } } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/ObjectIntHashMapRegressionTest.java000066400000000000000000000010751300364116400311530ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.*; import org.junit.Test; public class ObjectIntHashMapRegressionTest { /** @see "http://issues.carrot2.org/browse/HPPC-32" */ @Test public void testEqualsOnObjectKeys() { ObjectIntHashMap map = new ObjectIntHashMap(); String key1 = "key1"; String key2 = new String("key1"); map.put(key1, 1); assertEquals(1, map.get(key2)); assertEquals(1, map.put(key2, 2)); assertEquals(1, map.size()); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/RequireAssertionsRule.java000066400000000000000000000015621300364116400274470ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.assertTrue; import org.junit.Before; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; /** * A JUnit rule that forces assertions to be enabled. */ public class RequireAssertionsRule implements MethodRule { public Statement apply(Statement base, FrameworkMethod paramFrameworkMethod, Object paramObject) { checkAssertionsEnabled(); return base; } /* */ @Before public void checkAssertionsEnabled() { boolean enabled = true; try { assert false; enabled = false; } catch (AssertionError e) { // Expected, fall through. } assertTrue("Enable JVM assertions for testing.", enabled); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/StringConversionsTest.java000066400000000000000000000020011300364116400274540ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.*; import org.junit.Test; public class StringConversionsTest { @Test public void testByteList() { ByteArrayList list = new ByteArrayList(); list.add(new byte [] {1, 2, 3}); assertEquals("[1, 2, 3]", list.toString()); } @Test public void testCharList() { CharArrayList list = new CharArrayList(); list.add(new char [] {'a', 'b', 'c'}); assertEquals("[a, b, c]", list.toString()); } @Test public void testObjectList() { ObjectArrayList list = new ObjectArrayList(); list.add("ab", "ac", "ad"); assertEquals("[ab, ac, ad]", list.toString()); } @Test public void testObjectObjectMap() { ObjectObjectHashMap map = ObjectObjectHashMap.from( new String [] {"a"}, new String [] {"b"}); assertEquals("[a=>b]", map.toString()); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/TestUtils.java000066400000000000000000000273631300364116400250770ustar00rootroot00000000000000package com.carrotsearch.hppc; import static org.junit.Assert.*; import java.util.Arrays; /** * Test utilities. */ public abstract class TestUtils { private final static float delta = 0; // no instances. private TestUtils() {} /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static Object [] reverse(Object [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { Object t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static byte [] reverse(byte [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { byte t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static char [] reverse(char [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { char t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static short [] reverse(short [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { short t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static int [] reverse(int [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { int t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static float [] reverse(float [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { float t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static double [] reverse(double [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { double t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Reverse the order of elements in an array. Returns the array argument * for easier chaining. */ public static long [] reverse(long [] array) { for (int i = 0, mid = array.length / 2, j = array.length - 1; i < mid; i++, j--) { long t = array[i]; array[i] = array[j]; array[j] = t; } return array; } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(Object [] array, Object... elements) { assertEquals(elements.length, array.length); assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(double [] array, double... elements) { assertEquals(elements.length, array.length); assertArrayEquals(elements, array, delta); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(float [] array, float... elements) { assertEquals(elements.length, array.length); assertArrayEquals(elements, array, delta); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(int [] array, int... elements) { assertEquals(elements.length, array.length); assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(long [] array, long... elements) { assertEquals(elements.length, array.length); assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(short [] array, int... elements) { assertEquals(elements.length, array.length); assertArrayEquals(newArray(array, elements), array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(short [] array, short... elements) { assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(byte [] array, int... elements) { assertEquals(elements.length, array.length); assertArrayEquals(newArray(array, elements), array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(byte [] array, byte... elements) { assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(char [] array, int... elements) { assertEquals(elements.length, array.length); assertArrayEquals(newArray(array, elements), array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertListEquals(char [] array, char... elements) { assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(Object [] array, Object... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(double [] array, double... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(elements, array, delta); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(float [] array, float... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(elements, array, delta); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(int [] array, int... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); Arrays.sort(elements); assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(long [] array, long... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(elements, array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(short [] array, int... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(newArray(array, elements), array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(byte [] array, int... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(newArray(array, elements), array); } /** * Check if the array's content is identical to a given sequence of elements. */ public static void assertSortedListEquals(char [] array, int... elements) { assertEquals(elements.length, array.length); Arrays.sort(array); assertArrayEquals(newArray(array, elements), array); } /** * Create a new array of a given type and copy the arguments to this array. */ public static T [] newArray(T [] arrayType, @SuppressWarnings("unchecked") T... elements) { return elements; } /** * Create a new array of ints. */ public static int [] newArray(int [] arrayType, int... elements) { return elements; } /** * Create a new array of doubles. */ public static double [] newArray(double [] arrayType, double... elements) { return elements; } /** * Create a new array of float. */ public static float [] newArray(float [] arrayType, float... elements) { return elements; } /** * Create a new array of longs. */ public static long [] newArray(long [] arrayType, long... elements) { return elements; } /** * Create a new array of shorts. */ public static short [] newArray(short [] arrayType, int... elements) { final short [] result = new short [elements.length]; for (int i = 0; i < elements.length; i++) { org.junit.Assert.assertTrue( elements[i] >= Short.MIN_VALUE && elements[i] <= Short.MAX_VALUE); result[i] = (short) elements[i]; } return result; } /** * Create a new array of chars. */ public static char [] newArray(char [] arrayType, int... elements) { final char [] result = new char [elements.length]; for (int i = 0; i < elements.length; i++) { org.junit.Assert.assertTrue( elements[i] >= Character.MIN_VALUE && elements[i] <= Character.MAX_VALUE); result[i] = (char) elements[i]; } return result; } /** * Create a new array of bytes. */ public static byte [] newArray(byte [] arrayType, int... elements) { final byte [] result = new byte [elements.length]; for (int i = 0; i < elements.length; i++) { org.junit.Assert.assertTrue( elements[i] >= Byte.MIN_VALUE && elements[i] <= Byte.MAX_VALUE); result[i] = (byte) elements[i]; } return result; } /** Override for generated templates. */ public static void assertEquals2(double a, double b) { org.junit.Assert.assertEquals(a, b, delta); } /** Override for generated templates. */ public static void assertEquals2(float a, float b) { org.junit.Assert.assertEquals(a, b, delta); } /** Override for generated templates. */ public static void assertEquals2(Object a, Object b) { org.junit.Assert.assertEquals(a, b); } } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/TightRandomResizingStrategy.java000066400000000000000000000014251300364116400306040ustar00rootroot00000000000000package com.carrotsearch.hppc; import com.carrotsearch.randomizedtesting.RandomizedContext; public final class TightRandomResizingStrategy implements ArraySizingStrategy { private final int maxRandomIncrement; public int growCalls; public TightRandomResizingStrategy(int maxRandomIncrement) { this.maxRandomIncrement = maxRandomIncrement; } public TightRandomResizingStrategy() { this(10); } @Override public int grow(int currentBufferLength, int elementsCount, int expectedAdditions) { growCalls++; int r = 0; if (maxRandomIncrement > 0) { r += RandomizedContext.current().getRandom().nextInt(maxRandomIncrement); } return Math.max(currentBufferLength, elementsCount + expectedAdditions) + r; } }hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/annotations/000077500000000000000000000000001300364116400246165ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/annotations/AwaitsFix.java000066400000000000000000000007661300364116400273710ustar00rootroot00000000000000package com.carrotsearch.hppc.annotations; import java.lang.annotation.Documented; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import com.carrotsearch.randomizedtesting.annotations.TestGroup; /** * An annotation for bug tracking issues that await resolution. */ @Documented @Inherited @Retention(RetentionPolicy.RUNTIME) @TestGroup(enabled = false) public @interface AwaitsFix { String value(); } hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/sorting/000077500000000000000000000000001300364116400237465ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/java/com/carrotsearch/hppc/sorting/IndirectSortTest.java000066400000000000000000000235011300364116400300630ustar00rootroot00000000000000package com.carrotsearch.hppc.sorting; import java.util.Arrays; import java.util.Random; import org.junit.*; import com.carrotsearch.hppc.XorShift128P; import static org.junit.Assert.*; /** * Test cases for {@link IndirectSort}. */ public class IndirectSortTest { static final int DATA_LENGTH = 1000000; /** * Implies the same order as the order of indices. */ private static class OrderedInputComparator implements IndirectComparator { public int compare(int a, int b) { if (a < b) return -1; if (a > b) return 1; return 0; } } /** * Implies reverse order of indices. */ private static class ReverseOrderedInputComparator extends OrderedInputComparator { @Override public int compare(int a, int b) { return -super.compare(a, b); } } enum DataDistribution { ORDERED, SAWTOOTH, RANDOM, STAGGER, PLATEAU, SHUFFLE } enum Algorithm { MERGESORT } /** * Test "certification" program as in Bentley and McIlroy's paper. */ @Test public void testSortCertificationMergeSort() { sortCertification(Algorithm.MERGESORT); } /** * Run a "sort certification" test. */ static void sortCertification(Algorithm algorithm) { int [] n_values = { 100, 1023, 1024, 1025, 1024 * 32 }; for (int n : n_values) { for (int m = 1; m < 2 * n; m *= 2) { for (DataDistribution dist : DataDistribution.values()) { int [] x = generate(dist, n, m); String testName = dist + "-" + n + "-" + m; testOn(algorithm, x, testName + "-normal"); testOn(algorithm, reverse(x, 0, n), testName + "-reversed"); testOn(algorithm, reverse(x, 0, n / 2), testName + "-reversed_front"); testOn(algorithm, reverse(x, n / 2, n), testName + "-reversed_back"); testOn(algorithm, sort(x), testName + "-sorted"); testOn(algorithm, dither(x), testName + "-dither"); } } } } /** * Generate n-length data set distributed according to dist. * * @param m Step for sawtooth, stagger, plateau and shuffle. */ static int [] generate(final DataDistribution dist, int n, int m) { // Start from a constant seed (repeatable tests). final Random rand = new Random(0x11223344); final int [] x = new int [n]; for (int i = 0, j = 0, k = 1; i < n; i++) { switch (dist) { case ORDERED: x[i] = i; break; case SAWTOOTH: x[i] = i % m; break; case RANDOM: x[i] = rand.nextInt() % m; break; case STAGGER: x[i] = (i * m + i) % n; break; case PLATEAU: x[i] = Math.min(i, m); break; case SHUFFLE: x[i] = (rand.nextInt() % m) != 0 ? (j += 2) : (k += 2); break; default: throw new RuntimeException(); } } return x; } static int [] sort(int [] x) { x = copy(x); Arrays.sort(x); return x; } static int [] dither(int [] x) { x = copy(x); for (int i = 0; i < x.length; i++) x[i] += i % 5; return x; } static int [] reverse(int [] x, int start, int end) { x = copy(x); for (int i = start, j = end - 1; i < j; i++, j--) { int v = x[i]; x[i] = x[j]; x[j] = v; } return x; } private static int [] copy(int [] x) { return (int []) x.clone(); } /* * */ private static void testOn(Algorithm algo, int [] x, String testName) { final IndirectComparator c = new IndirectComparator.AscendingIntComparator(x); final int [] order; switch (algo) { case MERGESORT: order = IndirectSort.mergesort(0, x.length, c); break; default: Assert.fail(); throw new RuntimeException(); } assertOrder(order, x.length, c); } /** * Empty and single-item input. */ @Test public void testEmptyAndSingle() { final IndirectComparator comparator = new OrderedInputComparator(); int [] mSortOrder = IndirectSort.mergesort(0, 0, comparator); Assert.assertEquals(mSortOrder.length, 0); for (int i = 0; i < 1000; i++) { mSortOrder = IndirectSort.mergesort(0, i, comparator); Assert.assertEquals(mSortOrder.length, i); } } /** * Large ordered input. */ @Test public void testOrderedMergeSort() { final IndirectComparator comparator = new OrderedInputComparator(); int [] order = IndirectSort.mergesort(0, DATA_LENGTH, comparator); assertOrder(order, DATA_LENGTH, comparator); } /** * Large reversed input. */ @Test public void testReversedMergeSort() { final IndirectComparator comparator = new ReverseOrderedInputComparator(); final int [] order = IndirectSort.mergesort(0, DATA_LENGTH, comparator); assertOrder(order, DATA_LENGTH, comparator); } /* * */ private static void assertOrder(final int [] order, int length, final IndirectComparator comparator) { for (int i = 1; i < length; i++) { Assert.assertTrue(comparator.compare(order[i - 1], order[i]) <= 0); } } /** * Randomized input, ascending int comparator. */ @Test public void testAscInt() { final int maxSize = 500; final int rounds = 1000; final int vocabulary = 10; final Random rnd = new Random(0x11223344); for (int round = 0; round < rounds; round++) { final int [] input = generateRandom(maxSize, vocabulary, rnd); final IndirectComparator comparator = new IndirectComparator.AscendingIntComparator( input); final int start = rnd.nextInt(input.length - 1); final int length = (input.length - start); int [] order = IndirectSort.mergesort(start, length, comparator); assertOrder(order, length, comparator); } } /** * Randomized input, descending int comparator. */ @Test public void testDescInt() { final int maxSize = 500; final int rounds = 1000; final int vocabulary = 10; final Random rnd = new Random(0x11223344); for (int round = 0; round < rounds; round++) { final int [] input = generateRandom(maxSize, vocabulary, rnd); final IndirectComparator comparator = new IndirectComparator.DescendingIntComparator( input); final int start = rnd.nextInt(input.length - 1); final int length = (input.length - start); int [] order = IndirectSort.mergesort(start, length, comparator); assertOrder(order, length, comparator); } } /** * Randomized input, ascending double comparator. */ @Test public void testAscDouble() { final int maxSize = 1000; final int rounds = 1000; final Random rnd = new Random(0x11223344); for (int round = 0; round < rounds; round++) { final double [] input = generateRandom(maxSize, rnd); final IndirectComparator comparator = new IndirectComparator.AscendingDoubleComparator( input); final int start = rnd.nextInt(input.length - 1); final int length = (input.length - start); int [] order = IndirectSort.mergesort(start, length, comparator); assertOrder(order, length, comparator); } } /** * Sort random integers from the range 0..0xff based on their 4 upper bits. The relative * order of 0xf0-masked integers should be preserved from the input. */ @Test public void testMergeSortIsStable() { final XorShift128P rnd = new XorShift128P(0xdeadbeefL); final int [] data = new int [10000]; for (int i = 0; i < data.length; i++) { data[i] = rnd.nextInt(0x100); } int [] order = IndirectSort.mergesort(0, data.length, new IndirectComparator() { public int compare(int indexA, int indexB) { return (data[indexA] & 0xf0) - (data[indexB] & 0xf0); } }); for (int i = 1; i < order.length; i++) { if ((data[order[i - 1]] & 0xf0) == (data[order[i]] & 0xf0)) { assertTrue(order[i - 1] < order[i]); } } } /* * */ private int [] generateRandom(final int maxSize, final int vocabulary, final Random rnd) { final int [] input = new int [2 + rnd.nextInt(maxSize)]; for (int i = 0; i < input.length; i++) { input[i] = vocabulary / 2 - rnd.nextInt(vocabulary); } return input; } /* * */ private double [] generateRandom(final int maxSize, final Random rnd) { final double [] input = new double [2 + rnd.nextInt(maxSize)]; for (int i = 0; i < input.length; i++) { input[i] = rnd.nextGaussian(); } return input; } } hppc-0.7.2/hppc/src/test/templates/000077500000000000000000000000001300364116400171465ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/templates/com/000077500000000000000000000000001300364116400177245ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/000077500000000000000000000000001300364116400224045ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/000077500000000000000000000000001300364116400233365ustar00rootroot00000000000000hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/AbstractKTypeTest.java000066400000000000000000000063551300364116400275720ustar00rootroot00000000000000package com.carrotsearch.hppc; import org.junit.Rule; import org.junit.rules.MethodRule; import com.carrotsearch.randomizedtesting.RandomizedTest; /** * Unit helpers for KType. */ /*! ${TemplateOptions.generatedAnnotation} !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @SuppressWarnings("unchecked") /*! #end !*/ public abstract class AbstractKTypeTest extends RandomizedTest { /** * Require assertions for all tests. */ @Rule public MethodRule requireAssertions = new RequireAssertionsRule(); /* Ready to use key values. */ protected KType keyE = Intrinsics. empty(); protected KType key0 = cast(0), k0 = key0; protected KType key1 = cast(1), k1 = key1; protected KType key2 = cast(2), k2 = key2; protected KType key3 = cast(3), k3 = key3; protected KType key4 = cast(4), k4 = key4; protected KType key5 = cast(5), k5 = key5; protected KType key6 = cast(6), k6 = key6; protected KType key7 = cast(7), k7 = key7; protected KType key8 = cast(8), k8 = key8; protected KType key9 = cast(9), k9 = key9; /** * Convert to target type from an integer used to test stuff. */ public KType cast(Integer v) { /*! #if ($TemplateOptions.KTypePrimitive) return (KType) v.intValue(); #else !*/ // @SuppressWarnings("unchecked") KType k = (KType)(Object) v; return k; /*! #end !*/ } public KType [] asArray(int... ints) { KType [] values = Intrinsics. newArray(ints.length); for (int i = 0; i < ints.length; i++) values[i] = (KType) /*! #if ($TemplateOptions.KTypeGeneric) !*/ (Object) /*! #end !*/ ints[i]; return values; } /** * Create a new array of a given type and copy the arguments to this array. */ /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ public final KType [] newArray(KType... elements) { return newArray0(elements); } /* #if ($TemplateOptions.KTypeGeneric) */ @SafeVarargs /* #end */ private final KType [] newArray0(KType... elements) { return elements; } public KType [] newArray(KType v0) { return this.newArray0(v0); } public KType [] newArray(KType v0, KType v1) { return this.newArray0(v0, v1); } public KType [] newArray(KType v0, KType v1, KType v2) { return this.newArray0(v0, v1, v2); } public KType [] newArray(KType v0, KType v1, KType v2, KType v3) { return this.newArray0(v0, v1, v2, v3); } public KType [] newArray(KType v0, KType v1, KType v2, KType v3, KType v4, KType v5, KType v6) { return this.newArray0(v0, v1, v2, v3, v4, v5, v6); } public KType [] newArray(KType v0, KType v1, KType v2, KType v3, KType v4, KType v5) { return this.newArray0(v0, v1, v2, v3, v4, v5); } public KType [] newArray(KType v0, KType v1, KType v2, KType v3, KType v4) { return this.newArray0(v0, v1, v2, v3, v4); } public KType [] newArray(KType v0, KType v1, KType v2, KType v3, KType v4, KType v5, KType v6, KType v7) { return this.newArray0(v0, v1, v2, v3, v4, v5, v6, v7); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeArrayDequeTest.java000066400000000000000000000436741300364116400300760ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; /*! #if ($TemplateOptions.KTypeGeneric) !*/ import java.util.ArrayDeque; /*! #end !*/ import java.util.Iterator; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.assertj.core.api.Assertions; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.KTypeProcedure; /** * Unit tests for {@link KTypeArrayDeque}. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeArrayDequeTest extends AbstractKTypeTest { /** * Per-test fresh initialized instance. */ public KTypeArrayDeque deque; /** * Some sequence values for tests. */ private KTypeArrayList sequence; /* */ @Before public void initialize() { deque = new KTypeArrayDeque<>(); sequence = new KTypeArrayList<>(); for (int i = 0; i < 10000; i++) sequence.add(cast(i)); } @After public void checkTrailingSpaceUninitialized() { if (deque != null) { for (int i = deque.tail; i < deque.head; i = KTypeArrayDeque.oneRight(i, deque.buffer.length)) assertTrue(Intrinsics. empty() == deque.buffer[i]); } } /* */ @Test public void testInitiallyEmpty() { assertEquals(0, deque.size()); } /* */ @Test public void testAddFirst() { deque.addFirst(k1); deque.addFirst(k2); deque.addFirst(k3); assertListEquals(deque.toArray(), 3, 2, 1); assertEquals(3, deque.size()); } /* */ @Test public void testAddLast() { deque.addLast(k1); deque.addLast(k2); deque.addLast(k3); assertListEquals(deque.toArray(), 1, 2, 3); assertEquals(3, deque.size()); } /* */ @Test public void testAddWithGrowth() { for (int i = 0; i < sequence.size(); i++) { deque.addFirst(sequence.get(i)); } assertListEquals(reverse(sequence.toArray()), deque.toArray()); } /* */ @Test public void testAddLastWithGrowth() { for (int i = 0; i < sequence.size(); i++) { deque.addLast(sequence.get(i)); } assertListEquals(sequence.toArray(), deque.toArray()); } /* */ @Test public void testAddAllFirst() { KTypeArrayList list2 = new KTypeArrayList<>(); list2.add(asArray(0, 1, 2)); deque.addFirst(list2); assertListEquals(deque.toArray(), 2, 1, 0); deque.addFirst(list2); assertListEquals(deque.toArray(), 2, 1, 0, 2, 1, 0); deque.clear(); KTypeArrayDeque deque2 = new KTypeArrayDeque(); deque2.addLast(asArray(0, 1, 2)); deque.addFirst(deque2); assertListEquals(deque.toArray(), 2, 1, 0); } /* */ @Test public void testAddAllLast() { KTypeArrayList list2 = new KTypeArrayList<>(); list2.add(asArray(0, 1, 2)); deque.addLast(list2); assertListEquals(deque.toArray(), 0, 1, 2); deque.addLast(list2); assertListEquals(deque.toArray(), 0, 1, 2, 0, 1, 2); deque.clear(); KTypeArrayDeque deque2 = new KTypeArrayDeque(); deque2.addLast(asArray(0, 1, 2)); deque.addLast(deque2); assertListEquals(deque.toArray(), 0, 1, 2); } /* */ @Test public void testRemoveFirst() { deque.addLast(k1); deque.addLast(k2); deque.addLast(k3); deque.removeFirst(); assertListEquals(deque.toArray(), 2, 3); assertEquals(2, deque.size()); deque.addFirst(k4); assertListEquals(deque.toArray(), 4, 2, 3); assertEquals(3, deque.size()); deque.removeFirst(); deque.removeFirst(); deque.removeFirst(); assertEquals(0, deque.toArray().length); assertEquals(0, deque.size()); } /* */ @Test(expected = AssertionError.class) public void testRemoveFirstEmpty() { deque.removeFirst(); } /* */ @Test public void testRemoveLast() { deque.addLast(k1); deque.addLast(k2); deque.addLast(k3); deque.removeLast(); assertListEquals(deque.toArray(), 1, 2); assertEquals(2, deque.size()); deque.addLast(k4); assertListEquals(deque.toArray(), 1, 2, 4); assertEquals(3, deque.size()); deque.removeLast(); deque.removeLast(); deque.removeLast(); assertEquals(0, deque.toArray().length); assertEquals(0, deque.size()); } /* */ @Test(expected = AssertionError.class) public void testRemoveLastEmpty() { deque.removeLast(); } /* */ @Test public void testGetFirst() { deque.addLast(k1); deque.addLast(k2); assertEquals2(k1, deque.getFirst()); deque.addFirst(k3); assertEquals2(k3, deque.getFirst()); } /* */ @Test(expected = AssertionError.class) public void testGetFirstEmpty() { deque.getFirst(); } /* */ @Test public void testGetLast() { deque.addLast(k1); deque.addLast(k2); assertEquals2(k2, deque.getLast()); deque.addLast(k3); assertEquals2(k3, deque.getLast()); } /* */ @Test(expected = AssertionError.class) public void testGetLastEmpty() { deque.getLast(); } /* */ @Test public void testRemoveFirstOccurrence() { int modulo = 10; int count = 10000; sequence.clear(); for (int i = 0; i < count; i++) { deque.addLast(cast(i % modulo)); sequence.add(cast(i % modulo)); } Random rnd = getRandom(); for (int i = 0; i < 500; i++) { KType k = cast(rnd.nextInt(modulo)); assertEquals( deque.removeFirst(k) >= 0, sequence.removeFirst(k) >= 0); } assertListEquals(deque.toArray(), sequence.toArray()); assertTrue(0 > deque.removeFirst(cast(modulo + 1))); deque.addLast(cast(modulo + 1)); assertTrue(0 <= deque.removeFirst(cast(modulo + 1))); } /* */ @Test public void testRemoveLastOccurrence() { int modulo = 10; int count = 10000; sequence.clear(); for (int i = 0; i < count; i++) { deque.addLast(cast(i % modulo)); sequence.add(cast(i % modulo)); } Random rnd = getRandom(); for (int i = 0; i < 500; i++) { KType k = cast(rnd.nextInt(modulo)); assertEquals( deque.removeLast(k) >= 0, sequence.removeLast(k) >= 0); } assertListEquals(deque.toArray(), sequence.toArray()); assertTrue(0 > deque.removeLast(cast(modulo + 1))); deque.addFirst(cast(modulo + 1)); assertTrue(0 <= deque.removeLast(cast(modulo + 1))); } /* */ @Test public void testRemoveAll() { deque.addLast(asArray(0, 1, 2, 1, 0, 3, 0)); assertEquals(0, deque.removeAll(k4)); assertEquals(3, deque.removeAll(k0)); assertListEquals(deque.toArray(), 1, 2, 1, 3); assertEquals(1, deque.removeAll(k3)); assertListEquals(deque.toArray(), 1, 2, 1); assertEquals(2, deque.removeAll(k1)); assertListEquals(deque.toArray(), 2); assertEquals(1, deque.removeAll(k2)); assertEquals(0, deque.size()); } /* */ @Test public void testRemoveAllInLookupContainer() { deque.addLast(asArray(0, 1, 2, 1, 0)); KTypeHashSet set = new KTypeHashSet<>(); set.addAll(asArray(0, 2)); assertEquals(3, deque.removeAll(set)); assertEquals(0, deque.removeAll(set)); assertListEquals(deque.toArray(), 1, 1); } /* */ @Test public void testRemoveAllWithPredicate() { deque.addLast(newArray(k0, k1, k2, k1, k4)); assertEquals(3, deque.removeAll(new KTypePredicate() { public boolean apply(KType v) { return v == key1 || v == key2; }; })); assertListEquals(deque.toArray(), 0, 4); } /* */ @Test public void testRemoveAllWithPredicateInterrupted() { deque.addLast(newArray(k0, k1, k2, k1, k4)); final RuntimeException t = new RuntimeException(); try { assertEquals(3, deque.removeAll(new KTypePredicate() { public boolean apply(KType v) { if (v == key2) throw t; return v == key1; }; })); fail(); } catch (RuntimeException e) { // Make sure it's really our exception... if (e != t) throw e; } // And check if the deque is in consistent state. assertListEquals(deque.toArray(), 0, key2, key1, 4); assertEquals(4, deque.size()); } /* */ @Test public void testClear() { deque.addLast(k1); deque.addLast(k2); deque.addFirst(k3); deque.clear(); assertEquals(0, deque.size()); assertEquals(0, deque.head); assertEquals(0, deque.tail); deque.addLast(k1); assertListEquals(deque.toArray(), 1); } /* */ @Test public void testEnsureCapacity() { TightRandomResizingStrategy resizer = new TightRandomResizingStrategy(); KTypeArrayDeque deque = new KTypeArrayDeque<>(0, resizer); // Add some elements. final int max = rarely() ? 0 : randomIntBetween(0, 1000); for (int i = 0; i < max; i++) { deque.addLast(cast(i)); } final int additions = randomIntBetween(1, 5000); deque.ensureCapacity(additions + deque.size()); final int before = resizer.growCalls; for (int i = 0; i < additions; i++) { if (randomBoolean()) { deque.addLast(cast(i)); } else { deque.addFirst(cast(i)); } } assertEquals(before, resizer.growCalls); } /* */ @Test public void testRelease() { deque.addLast(k1); deque.addLast(k2); deque.addFirst(k3); deque.release(); assertEquals(0, deque.size()); assertEquals(0, deque.head); assertEquals(0, deque.tail); deque.addLast(k1); assertListEquals(deque.toArray(), 1); } /* */ @Test public void testIterable() { deque.addLast(sequence); int count = 0; for (KTypeCursor cursor : deque) { assertEquals2(sequence.buffer[count], cursor.value); assertEquals2(deque.buffer[cursor.index], cursor.value); count++; } assertEquals(count, deque.size()); assertEquals(count, sequence.size()); count = 0; deque.clear(); for (@SuppressWarnings("unused") KTypeCursor cursor : deque) { count++; } assertEquals(0, count); } /* */ @Test public void testIterator() { deque.addLast(asArray(0, 1, 2, 3)); Iterator> iterator = deque.iterator(); int count = 0; while (iterator.hasNext()) { iterator.hasNext(); iterator.hasNext(); iterator.hasNext(); iterator.next(); count++; } assertEquals(count, deque.size()); deque.clear(); assertFalse(deque.iterator().hasNext()); } /* */ @Test public void testDescendingIterator() { deque.addLast(sequence); int index = sequence.size() - 1; for (Iterator> i = deque.descendingIterator(); i.hasNext(); ) { KTypeCursor cursor = i.next(); assertEquals2(sequence.buffer[index], cursor.value); assertEquals2(deque.buffer[cursor.index], cursor.value); index--; } assertEquals(-1, index); deque.clear(); assertFalse(deque.descendingIterator().hasNext()); } /* */ @Test public void testForEachWithProcedure() { deque.addLast(sequence); final AtomicInteger count = new AtomicInteger(); deque.forEach(new KTypeProcedure() { int index = 0; public void apply(KType v) { assertEquals2(sequence.buffer[index++], v); count.incrementAndGet(); } }); assertEquals(count.get(), deque.size()); } /* */ @Test public void testDescendingForEachWithProcedure() { deque.addLast(sequence); final AtomicInteger count = new AtomicInteger(); deque.descendingForEach(new KTypeProcedure() { int index = sequence.size(); public void apply(KType v) { assertEquals2(sequence.buffer[--index], v); count.incrementAndGet(); } }); assertEquals(count.get(), deque.size()); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testAgainstArrayDeque() { final Random rnd = new Random(randomLong()); final int rounds = 10000; final int modulo = 100; final ArrayDeque ad = new ArrayDeque(); for (int i = 0; i < rounds; i++) { KType k = cast(rnd.nextInt(modulo)); final int op = rnd.nextInt(8); if (op < 2) { deque.addFirst(k); ad.addFirst(k); } else if (op < 4) { deque.addLast(k); ad.addLast(k); } else if (op < 5 && ad.size() > 0) { deque.removeLast(); ad.removeLast(); } else if (op < 6 && ad.size() > 0) { deque.removeLast(); ad.removeLast(); } else if (op < 7) { assertEquals( ad.removeFirstOccurrence(k), deque.removeFirst(k) >= 0); } else if (op < 8) { assertEquals( ad.removeLastOccurrence(k), deque.removeLast(k) >= 0); } assertEquals(ad.size(), deque.size()); } assertArrayEquals(ad.toArray(), deque.toArray()); } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testAgainstArrayDequeVariousTailHeadPositions() { this.deque.clear(); this.deque.head = this.deque.tail = 2; testAgainstArrayDeque(); this.deque.clear(); this.deque.head = this.deque.tail = this.deque.buffer.length - 2; testAgainstArrayDeque(); this.deque.clear(); this.deque.head = this.deque.tail = this.deque.buffer.length / 2; testAgainstArrayDeque(); } /*! #end !*/ @Test public void testHashCodeEquals() { KTypeArrayDeque l0 = new KTypeArrayDeque<>(); assertEquals(1, l0.hashCode()); assertEquals(l0, KTypeArrayDeque.from()); KTypeArrayDeque l1 = KTypeArrayDeque.from(k1, k2, k3); KTypeArrayDeque l2 = KTypeArrayDeque.from(k1, k2); l2.addLast(k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testHashCodeWithNulls() { KTypeArrayDeque l1 = KTypeArrayDeque.from(k1, null, k3); KTypeArrayDeque l2 = KTypeArrayDeque.from(k1, null, k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testToArray() { KTypeArrayDeque l1 = KTypeArrayDeque.from(k1, k2, k3); Object[] result = l1.toArray(); assertArrayEquals(new Object [] {k1, k2, k3}, result); // dummy } /*! #end !*/ @Test public void testClone() { this.deque.addLast(key1, key2, key3); KTypeArrayDeque cloned = deque.clone(); cloned.removeAll(key1); assertSortedListEquals(deque.toArray(), key1, key2, key3); assertSortedListEquals(cloned.toArray(), key2, key3); } @Test public void testToString() { assertEquals("[" + key1 + ", " + key2 + ", " + key3 + "]", KTypeArrayDeque.from(key1, key2, key3).toString()); } /* */ @Test public void testEqualsSameClass() { KTypeArrayDeque l1 = KTypeArrayDeque.from(k1, k2, k3); KTypeArrayDeque l2 = KTypeArrayDeque.from(k1, k2, k3); KTypeArrayDeque l3 = KTypeArrayDeque.from(k1, k3, k2); Assertions.assertThat(l1).isEqualTo(l2); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1).isNotEqualTo(l3); } /* */ @Test public void testEqualsSubClass() { class Sub extends KTypeArrayDeque { }; KTypeArrayDeque l1 = KTypeArrayDeque.from(k1, k2, k3); KTypeArrayDeque l2 = new Sub(); KTypeArrayDeque l3 = new Sub(); l2.addLast(k1); l2.removeFirst(); // no-op l2.addLast(l1); l3.addLast(l1); Assertions.assertThat(l2).isEqualTo(l3); Assertions.assertThat(l1).isNotEqualTo(l2); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeArrayListTest.java000066400000000000000000000371341300364116400277400ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; import java.util.Arrays; import java.util.Iterator; import java.util.concurrent.atomic.AtomicInteger; import org.assertj.core.api.Assertions; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.KTypeProcedure; /** * Unit tests for {@link KTypeArrayList}. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeArrayListTest extends AbstractKTypeTest { /** * Per-test fresh initialized instance. */ public KTypeArrayList list; /* */ @Before public void initialize() { list = new KTypeArrayList<>(); } @After public void checkTrailingSpaceUninitialized() { if (list != null) { for (int i = list.elementsCount; i < list.buffer.length; i++) assertTrue(Intrinsics. empty() == list.buffer[i]); } } /* */ @Test public void testInitiallyEmpty() { assertEquals(0, list.size()); } /* */ @Test public void testAdd() { list.add(key1, key2); assertListEquals(list.toArray(), 1, 2); } /* */ @Test public void testAddTwoArgs() { list.add(key1, key2); list.add(key3, key4); assertListEquals(list.toArray(), 1, 2, 3, 4); } /* */ @Test public void testAddArray() { list.add(asArray(0, 1, 2, 3), 1, 2); assertListEquals(list.toArray(), 1, 2); } /* */ @Test public void testAddVarArg() { list.add(asArray(0, 1, 2, 3)); list.add(key4, key5, key6, key7); assertListEquals(list.toArray(), 0, 1, 2, 3, 4, 5, 6, 7); } /* */ @Test public void testAddAll() { KTypeArrayList list2 = new KTypeArrayList<>(); list2.add(asArray(0, 1, 2)); list.addAll(list2); list.addAll(list2); assertListEquals(list.toArray(), 0, 1, 2, 0, 1, 2); } /* */ @Test public void testInsert() { list.insert(0, k1); list.insert(0, k2); list.insert(2, k3); list.insert(1, k4); assertListEquals(list.toArray(), 2, 4, 1, 3); } /* */ @Test public void testSet() { list.add(asArray(0, 1, 2)); assertEquals2(0, list.set(0, k3)); assertEquals2(1, list.set(1, k4)); assertEquals2(2, list.set(2, k5)); assertListEquals(list.toArray(), 3, 4, 5); } /* */ @Test public void testRemove() { list.add(asArray(0, 1, 2, 3, 4)); list.remove(0); list.remove(2); list.remove(1); assertListEquals(list.toArray(), 1, 4); } /* */ @Test public void testRemoveRange() { list.add(asArray(0, 1, 2, 3, 4)); list.removeRange(0, 2); assertListEquals(list.toArray(), 2, 3, 4); list.removeRange(2, 3); assertListEquals(list.toArray(), 2, 3); list.removeRange(1, 1); assertListEquals(list.toArray(), 2, 3); list.removeRange(0, 1); assertListEquals(list.toArray(), 3); } /* */ @Test public void testRemoveFirstLast() { list.add(asArray(0, 1, 2, 1, 0)); assertEquals(-1, list.removeFirst(k5)); assertEquals(-1, list.removeLast(k5)); assertListEquals(list.toArray(), 0, 1, 2, 1, 0); assertEquals(1, list.removeFirst(k1)); assertListEquals(list.toArray(), 0, 2, 1, 0); assertEquals(3, list.removeLast(k0)); assertListEquals(list.toArray(), 0, 2, 1); assertEquals(0, list.removeLast(k0)); assertListEquals(list.toArray(), 2, 1); assertEquals(-1, list.removeLast(k0)); /*! #if ($TemplateOptions.KTypeGeneric) !*/ list.clear(); list.add(newArray(k0, null, k2, null, k0)); assertEquals(1, list.removeFirst(null)); assertEquals(2, list.removeLast(null)); assertListEquals(list.toArray(), 0, 2, 0); /*! #end !*/ } /* */ @Test public void testRemoveAll() { list.add(asArray(0, 1, 0, 1, 0)); assertEquals(0, list.removeAll(k2)); assertEquals(3, list.removeAll(k0)); assertListEquals(list.toArray(), 1, 1); assertEquals(2, list.removeAll(k1)); assertTrue(list.isEmpty()); /*! #if ($TemplateOptions.KTypeGeneric) !*/ list.clear(); list.add(newArray(k0, null, k2, null, k0)); assertEquals(2, list.removeAll((KType) null)); assertEquals(0, list.removeAll((KType) null)); assertListEquals(list.toArray(), 0, 2, 0); /*! #end !*/ } /* */ @Test public void testRemoveAllFromLookupContainer() { list.add(asArray(0, 1, 2, 1, 0)); KTypeHashSet list2 = new KTypeHashSet<>(); list2.addAll(asArray(0, 2)); assertEquals(3, list.removeAll(list2)); assertEquals(0, list.removeAll(list2)); assertListEquals(list.toArray(), 1, 1); } /* */ @Test public void testRemoveAllWithPredicate() { list.add(newArray(k0, k1, k2, k1, k4)); assertEquals(3, list.removeAll(new KTypePredicate() { public boolean apply(KType v) { return v == key1 || v == key2; }; })); assertListEquals(list.toArray(), 0, 4); } /* */ @Test public void testRetainAllWithPredicate() { list.add(newArray(k0, k1, k2, k1, k0)); assertEquals(2, list.retainAll(new KTypePredicate() { public boolean apply(KType v) { return v == key1 || v == key2; }; })); assertListEquals(list.toArray(), 1, 2, 1); } /* */ @Test public void testRemoveAllWithPredicateInterrupted() { list.add(newArray(k0, k1, k2, k1, k4)); final RuntimeException t = new RuntimeException(); try { assertEquals(3, list.removeAll(new KTypePredicate() { public boolean apply(KType v) { if (v == key2) throw t; return v == key1; }; })); fail(); } catch (RuntimeException e) { // Make sure it's really our exception... if (e != t) throw e; } // And check if the list is in consistent state. assertListEquals(list.toArray(), 0, key2, key1, 4); assertEquals(4, list.size()); } /* */ @Test public void testIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); /*! #if ($TemplateOptions.KTypeGeneric) !*/ list.add((KType) null); assertEquals(5, list.indexOf(null)); /*! #end !*/ assertEquals(0, list.indexOf(k0)); assertEquals(-1, list.indexOf(k3)); assertEquals(2, list.indexOf(k2)); } /* */ @Test public void testLastIndexOf() { list.add(asArray(0, 1, 2, 1, 0)); /*! #if ($TemplateOptions.KTypeGeneric) !*/ list.add((KType) null); assertEquals(5, list.lastIndexOf(null)); /*! #end !*/ assertEquals2(4, list.lastIndexOf(k0)); assertEquals2(-1, list.lastIndexOf(k3)); assertEquals2(2, list.lastIndexOf(k2)); } /* */ @Test public void testEnsureCapacity() { TightRandomResizingStrategy resizer = new TightRandomResizingStrategy(0); KTypeArrayList list = new KTypeArrayList<>(0, resizer); // Add some elements. final int max = rarely() ? 0 : randomIntBetween(0, 1000); for (int i = 0; i < max; i++) { list.add(cast(i)); } final int additions = randomIntBetween(1, 5000); list.ensureCapacity(additions + list.size()); final int before = resizer.growCalls; for (int i = 0; i < additions; i++) { list.add(cast(i)); } assertEquals(before, resizer.growCalls); } @Test public void testResizeAndCleanBuffer() { list.ensureCapacity(20); Arrays.fill(list.buffer, k1); list.resize(10); assertEquals(10, list.size()); for (int i = 0; i < list.size(); i++) { assertEquals2(Intrinsics. empty(), list.get(i)); } Arrays.fill(list.buffer, Intrinsics. empty()); for (int i = 5; i < list.size(); i++) { list.set(i, k1); } list.resize(5); assertEquals(5, list.size()); for (int i = list.size(); i < list.buffer.length; i++) { assertEquals2(Intrinsics. empty(), list.buffer[i]); } } /* */ @Test public void testTrimToSize() { list.add(asArray(1, 2)); list.trimToSize(); assertEquals(2, list.buffer.length); } /* */ @Test public void testRelease() { list.add(asArray(1, 2)); list.release(); assertEquals(0, list.size()); list.add(asArray(1, 2)); assertEquals(2, list.size()); } /* */ @Test public void testGrowth() { final int maxGrowth = 10; final int count = 500; list = new KTypeArrayList(0, new BoundedProportionalArraySizingStrategy(5, maxGrowth, 2)); for (int i = 0; i < count; i++) list.add(cast(i)); assertEquals(count, list.size()); for (int i = 0; i < count; i++) assertEquals2(cast(i), list.get(i)); assertTrue("Buffer size: 510 <= " + list.buffer.length, list.buffer.length <= count + maxGrowth); } /* */ @Test public void testIterable() { list.add(asArray( 0, 1, 2, 3)); int count = 0; for (KTypeCursor cursor : list) { count++; assertEquals2(list.get(cursor.index), cursor.value); assertEquals2(list.buffer[cursor.index], cursor.value); } assertEquals(count, list.size()); count = 0; list.resize(0); for (@SuppressWarnings("unused") KTypeCursor cursor : list) { count++; } assertEquals(0, count); } /* */ @Test public void testIterator() { list.add(asArray( 0, 1, 2, 3)); Iterator> iterator = list.iterator(); int count = 0; while (iterator.hasNext()) { iterator.hasNext(); iterator.hasNext(); iterator.hasNext(); iterator.next(); count++; } assertEquals(count, list.size()); list.resize(0); assertFalse(list.iterator().hasNext()); } /* */ @Test public void testForEachWithProcedure() { list.add(asArray( 1, 2, 3)); final AtomicInteger holder = new AtomicInteger(); list.forEach(new KTypeProcedure() { int index = 0; public void apply(KType v) { assertEquals2(v, list.get(index++)); holder.set(index); } }); assertEquals(holder.get(), list.size()); } /* */ @Test public void testForEachReturnValueFromAnonymousClass() { list.add(asArray( 1, 2, 3)); int result = list.forEach(new KTypeProcedure() { int index = 0; public void apply(KType v) { assertEquals2(v, list.get(index++)); } }).index; assertEquals(result, list.size()); } /* */ @Test public void testClear() { list.add(asArray( 1, 2, 3)); list.clear(); checkTrailingSpaceUninitialized(); } /* */ @Test public void testFrom() { KTypeArrayList variable = KTypeArrayList.from(k1, k2, k3); assertEquals(3, variable.size()); assertListEquals(variable.toArray(), 1, 2, 3); } /* */ @Test public void testHashCodeEquals() { KTypeArrayList l0 = KTypeArrayList.from(); assertEquals(1, l0.hashCode()); assertEquals(l0, KTypeArrayList.from()); KTypeArrayList l1 = KTypeArrayList.from(k1, k2, k3); KTypeArrayList l2 = KTypeArrayList.from(k1, k2); l2.add(k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } /* */ @Test public void testEqualElements() { KTypeStack l1 = KTypeStack.from(k1, k2, k3); KTypeArrayList l2 = KTypeArrayList.from(k1, k2); l2.add(k3); assertEquals(l1.hashCode(), l2.hashCode()); assertTrue(l2.equalElements(l1)); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testHashCodeWithNulls() { KTypeArrayList l1 = KTypeArrayList.from(k1, null, k3); KTypeArrayList l2 = KTypeArrayList.from(k1, null, k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testAddAll_subclass() { class A { } class B extends A { } KTypeArrayList list2 = new KTypeArrayList(); list2.add(new B()); KTypeArrayList list3 = new KTypeArrayList(); list3.add(new B()); list3.add(new A()); list3.addAll(list2); assertEquals(3, list3.size()); } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testToArrayWithClass() { KTypeArrayList l1 = KTypeArrayList.from(1, 2, 3); Integer[] result = l1.toArray(Integer.class); assertArrayEquals(new Integer [] {1, 2, 3}, result); // dummy } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testToArray() { KTypeArrayList l1 = KTypeArrayList.from(k1, k2, k3); Object[] result = l1.toArray(); assertArrayEquals(new Object [] {k1, k2, k3}, result); } /*! #end !*/ /* */ @Test public void testClone() { list.add(k1, k2, k3); KTypeArrayList cloned = list.clone(); cloned.removeAll(key1); assertSortedListEquals(list.toArray(), key1, key2, key3); assertSortedListEquals(cloned.toArray(), key2, key3); } /* */ @Test public void testToString() { assertEquals("[" + key1 + ", " + key2 + ", " + key3 + "]", KTypeArrayList.from(k1, k2, k3).toString()); } /* */ @Test public void testEqualsSameClass() { KTypeArrayList l1 = KTypeArrayList.from(k1, k2, k3); KTypeArrayList l2 = KTypeArrayList.from(k1, k2, k3); KTypeArrayList l3 = KTypeArrayList.from(k1, k3, k2); Assertions.assertThat(l1).isEqualTo(l2); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1).isNotEqualTo(l3); } /* */ @Test public void testEqualsSubClass() { class Sub extends KTypeArrayList { }; KTypeArrayList l1 = KTypeArrayList.from(k1, k2, k3); KTypeArrayList l2 = new Sub(); KTypeArrayList l3 = new Sub(); l2.addAll(l1); l3.addAll(l1); Assertions.assertThat(l2).isEqualTo(l3); Assertions.assertThat(l1).isNotEqualTo(l2); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeHashSetTest.java000066400000000000000000000343521300364116400273640ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; import java.util.concurrent.atomic.AtomicInteger; import org.assertj.core.api.Assertions; import org.junit.Before; import org.junit.Test; import com.carrotsearch.hppc.cursors.KTypeCursor; import com.carrotsearch.hppc.predicates.KTypePredicate; import com.carrotsearch.hppc.procedures.KTypeProcedure; /** * Unit tests for {@link KTypeHashSet}. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeHashSetTest extends AbstractKTypeTest { /** * Per-test fresh initialized instance. */ public KTypeHashSet set; public final KType EMPTY_KEY = Intrinsics. empty(); /* */ @Before public void initialize() { set = new KTypeHashSet<>(); } @Test public void testVisualizeKeys() { set.clear(); Assertions.assertThat(set.visualizeKeyDistribution(20).trim()).matches("\\.+"); set.add(keyE); Assertions.assertThat(set.visualizeKeyDistribution(20).trim()).matches("\\.+"); set.add(key1); Assertions.assertThat(set.visualizeKeyDistribution(20).trim()).matches("\\.*X\\.*"); Assertions.assertThat(set.visualizeKeyDistribution(20)).hasSize(20); for (int i = 0; i < 60; i++) { set.add(cast(i)); } Assertions.assertThat(set.visualizeKeyDistribution(20)).hasSize(20); } @Test public void testIndexMethods() { set.add(keyE); set.add(key1); Assertions.assertThat(set.indexOf(keyE)).isNotNegative(); Assertions.assertThat(set.indexOf(key1)).isNotNegative(); Assertions.assertThat(set.indexOf(key2)).isNegative(); Assertions.assertThat(set.indexExists(set.indexOf(keyE))).isTrue(); Assertions.assertThat(set.indexExists(set.indexOf(key1))).isTrue(); Assertions.assertThat(set.indexExists(set.indexOf(key2))).isFalse(); Assertions.assertThat(set.indexGet(set.indexOf(keyE))).isEqualTo(keyE); Assertions.assertThat(set.indexGet(set.indexOf(key1))).isEqualTo(key1); try { set.indexGet(set.indexOf(key2)); fail(); } catch (AssertionError e) { // Expected. } Assertions.assertThat(set.indexReplace(set.indexOf(keyE), keyE)).isEqualTo(keyE); Assertions.assertThat(set.indexReplace(set.indexOf(key1), key1)).isEqualTo(key1); set.indexInsert(set.indexOf(key2), key2); Assertions.assertThat(set.indexGet(set.indexOf(key2))).isEqualTo(key2); Assertions.assertThat(set.size()).isEqualTo(3); } @Test public void testCursorIndexIsValid() { set.add(keyE); set.add(key1); set.add(key2); for (KTypeCursor c : set) { Assertions.assertThat(set.indexExists(c.index)).isTrue(); Assertions.assertThat(set.indexGet(c.index)).isEqualTo(c.value); } } /* */ @Test public void testEmptyKey() { KTypeHashSet set = new KTypeHashSet(); set.add(EMPTY_KEY); Assertions.assertThat(set.size()).isEqualTo(1); Assertions.assertThat(set.isEmpty()).isFalse(); Assertions.assertThat(set.toArray()).containsOnly(EMPTY_KEY); Assertions.assertThat(set.contains(EMPTY_KEY)).isTrue(); set.remove(EMPTY_KEY); Assertions.assertThat(set.size()).isEqualTo(0); Assertions.assertThat(set.isEmpty()).isTrue(); Assertions.assertThat(set.toArray()).isEmpty(); Assertions.assertThat(set.contains(EMPTY_KEY)).isFalse(); } /* */ @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); KTypeHashSet set = new KTypeHashSet(0) { @Override protected void allocateBuffers(int arraySize) { super.allocateBuffers(arraySize); expands.incrementAndGet(); } }; // Add some elements. final int max = rarely() ? 0 : randomIntBetween(0, 250); for (int i = 0; i < max; i++) { set.add(cast(i)); } final int additions = randomIntBetween(max, max + 5000); set.ensureCapacity(additions + set.size()); final int before = expands.get(); for (int i = 0; i < additions; i++) { set.add(cast(i)); } assertEquals(before, expands.get()); } /* */ @Test public void testInitiallyEmpty() { assertEquals(0, set.size()); } /* */ @Test public void testAdd() { assertTrue(set.add(key1)); assertFalse(set.add(key1)); assertEquals(1, set.size()); } /* */ @Test public void testAdd2() { set.addAll(key1, key1); assertEquals(1, set.size()); assertEquals(1, set.addAll(key1, key2)); assertEquals(2, set.size()); } /* */ @Test public void testAddVarArgs() { set.addAll(asArray(0, 1, 2, 1, 0)); assertEquals(3, set.size()); assertSortedListEquals(set.toArray(), 0, 1, 2); } /* */ @Test public void testAddAll() { KTypeHashSet set2 = new KTypeHashSet(); set2.addAll(asArray(1, 2)); set.addAll(asArray(0, 1)); assertEquals(1, set.addAll(set2)); assertEquals(0, set.addAll(set2)); assertEquals(3, set.size()); assertSortedListEquals(set.toArray(), 0, 1, 2); } /* */ @Test public void testRemove() { set.addAll(asArray(0, 1, 2, 3, 4)); assertTrue(set.remove(k2)); assertFalse(set.remove(k2)); assertEquals(4, set.size()); assertSortedListEquals(set.toArray(), 0, 1, 3, 4); } /* */ @Test public void testInitialCapacityAndGrowth() { for (int i = 0; i < 256; i++) { KTypeHashSet set = new KTypeHashSet(i); for (int j = 0; j < i; j++) { set.add(cast(j)); } assertEquals(i, set.size()); } } /* */ @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; set = new KTypeHashSet(elements, 1f) { @Override protected double verifyLoadFactor(double loadFactor) { // Skip load factor sanity range checking. return loadFactor; } @Override protected void allocateBuffers(int arraySize) { super.allocateBuffers(arraySize); reallocations.incrementAndGet(); } }; int reallocationsBefore = reallocations.get(); assertEquals(reallocationsBefore, 1); for (int i = 1; i <= elements; i++) { set.add(cast(i)); } // Non-existent key. KType outOfSet = cast(elements + 1); set.remove(outOfSet); assertFalse(set.contains(outOfSet)); assertEquals(reallocationsBefore, reallocations.get()); // Should not expand because we're replacing an existing element. assertFalse(set.add(k1)); assertEquals(reallocationsBefore, reallocations.get()); // Remove from a full set. set.remove(k1); assertEquals(reallocationsBefore, reallocations.get()); set.add(k1); // Check expand on "last slot of a full map" condition. set.add(outOfSet); assertEquals(reallocationsBefore + 1, reallocations.get()); } /* */ @Test public void testRemoveAllFromLookupContainer() { set.addAll(asArray(0, 1, 2, 3, 4)); KTypeHashSet list2 = new KTypeHashSet(); list2.addAll(asArray(1, 3, 5)); assertEquals(2, set.removeAll(list2)); assertEquals(3, set.size()); assertSortedListEquals(set.toArray(), 0, 2, 4); } /* */ @Test public void testRemoveAllWithPredicate() { set.addAll(newArray(k0, k1, k2)); assertEquals(1, set.removeAll(new KTypePredicate() { public boolean apply(KType v) { return v == key1; }; })); assertSortedListEquals(set.toArray(), 0, key2); } /* */ @Test public void testRetainAllWithPredicate() { set.addAll(newArray(k0, k1, k2, k3, k4, k5)); assertEquals(4, set.retainAll(new KTypePredicate() { public boolean apply(KType v) { return v == key1 || v == key2; }; })); assertSortedListEquals(set.toArray(), key1, key2); } /* */ @Test public void testClear() { set.addAll(asArray(1, 2, 3)); set.clear(); assertEquals(0, set.size()); } /* */ @Test public void testRelease() { set.addAll(asArray(1, 2, 3)); set.release(); assertEquals(0, set.size()); set.addAll(asArray(1, 2, 3)); assertEquals(3, set.size()); } /* */ @Test public void testIterable() { set.addAll(asArray(1, 2, 2, 3, 4)); set.remove(k2); assertEquals(3, set.size()); int count = 0; for (KTypeCursor cursor : set) { count++; assertTrue(set.contains(cursor.value)); } assertEquals(count, set.size()); set.clear(); assertFalse(set.iterator().hasNext()); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testNullKey() { assertTrue(set.add((KType) null)); assertEquals(1, set.size()); assertTrue(set.contains(null)); assertTrue(set.remove(null)); assertEquals(0, set.size()); assertFalse(set.contains(null)); } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ /** * Run some random insertions/ deletions and compare the results * against java.util.HashSet. */ @Test public void testAgainstHashMap() { final java.util.Random rnd = new java.util.Random(); final java.util.HashSet other = new java.util.HashSet(); for (int size = 1000; size < 20000; size += 4000) { other.clear(); set.clear(); for (int round = 0; round < size * 20; round++) { Integer key = rnd.nextInt(size); if (rnd.nextInt(50) == 0) { key = Intrinsics.empty(); } if (rnd.nextBoolean()) { other.add(cast(key)); set.add(cast(key)); assertTrue(set.contains(cast(key))); } else { assertEquals(other.remove(key), set.remove(cast(key))); } assertEquals(other.size(), set.size()); } } } /*! #end !*/ /* */ @Test public void testHashCodeEquals() { KTypeHashSet l0 = new KTypeHashSet<>(); assertEquals(0, l0.hashCode()); assertEquals(l0, new KTypeHashSet<>()); KTypeHashSet l1 = KTypeHashSet.from(k1, k2, k3); KTypeHashSet l2 = KTypeHashSet.from(k1, k2); l2.add(k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } /* */ @Test public void testHashCodeEqualsForDifferentMix() { KTypeHashSet l0 = new KTypeHashSet(0, 0.5d, HashOrderMixing.constant(1)); KTypeHashSet l1 = new KTypeHashSet(0, 0.5d, HashOrderMixing.constant(2)); assertEquals(0, l0.hashCode()); assertEquals(l0.hashCode(), l1.hashCode()); assertEquals(l0, l1); l0.addAll(newArray(k1, k2, k3)); l1.addAll(newArray(k1, k2, k3)); assertEquals(l0.hashCode(), l1.hashCode()); assertEquals(l0, l1); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testHashCodeWithNulls() { KTypeHashSet l1 = KTypeHashSet.from(k1, null, k3); KTypeHashSet l2 = KTypeHashSet.from(k1, null); l2.add(k3); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); } /*! #end !*/ @Test public void testClone() { this.set.addAll(key1, key2, key3); KTypeHashSet cloned = set.clone(); cloned.removeAll(key1); assertSortedListEquals(set.toArray(), key1, key2, key3); assertSortedListEquals(cloned.toArray(), key2, key3); } /* */ @Test public void testEqualsSameClass() { KTypeHashSet l1 = KTypeHashSet.from(k1, k2, k3); KTypeHashSet l2 = KTypeHashSet.from(k1, k2, k3); KTypeHashSet l3 = KTypeHashSet.from(k1, k2, k4); Assertions.assertThat(l1).isEqualTo(l2); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1).isNotEqualTo(l3); } /* */ @Test public void testEqualsSubClass() { class Sub extends KTypeHashSet { }; KTypeHashSet l1 = KTypeHashSet.from(k1, k2, k3); KTypeHashSet l2 = new Sub(); KTypeHashSet l3 = new Sub(); l2.addAll(l1); l3.addAll(l1); Assertions.assertThat(l2).isEqualTo(l3); Assertions.assertThat(l1).isNotEqualTo(l2); } /* */ @Test public void testForEachPredicate() { final KTypeHashSet set = KTypeHashSet.from(keyE, k1, k2, k3); final KTypeHashSet other = new KTypeHashSet<>(); set.forEach(new KTypePredicate() { @Override public boolean apply(KType value) { other.add(value); return true; } }); Assertions.assertThat(other).isEqualTo(set); } /* */ @Test public void testForEachProcedure() { final KTypeHashSet set = KTypeHashSet.from(keyE, k1, k2, k3); final KTypeHashSet other = new KTypeHashSet<>(); set.forEach(new KTypeProcedure() { @Override public void apply(KType value) { other.add(value); } }); Assertions.assertThat(other).isEqualTo(set); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeScatterSetTest.java000066400000000000000000000005131300364116400300760ustar00rootroot00000000000000package com.carrotsearch.hppc; import org.junit.Before; /** * Unit tests for {@link KTypeHashSet}. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeScatterSetTest extends KTypeHashSetTest { /* */ @Before public void initialize() { set = new KTypeScatterSet<>(); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeStackTest.java000066400000000000000000000136061300364116400270710ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; import org.assertj.core.api.Assertions; import org.junit.*; /** * Unit tests for {@link KTypeStack}. */ /*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeStackTest extends AbstractKTypeTest { /** * Per-test fresh initialized instance. */ public KTypeStack stack; /* */ @Before public void initialize() { stack = new KTypeStack<>(); } /* */ @Test public void testInitiallyEmpty() { assertEquals(0, stack.size()); } /* */ @Test public void testPush1() { stack.push(key1); assertEquals(1, stack.size()); assertEquals2(key1, stack.peek()); assertEquals2(key1, stack.pop()); assertEquals(0, stack.size()); } /* */ @Test public void testPush2() { stack.push(key1, key3); assertEquals(2, stack.size()); assertEquals2(key3, stack.peek()); assertEquals2(key1, stack.get(0)); assertEquals2(key3, stack.get(1)); assertEquals2(key3, stack.pop()); assertEquals2(key1, stack.pop()); assertEquals(0, stack.size()); } /* */ @Test public void testPushArray() { stack.push(asArray(1, 2, 3, 4), 1, 2); assertEquals(2, stack.size()); assertEquals2(key2, stack.get(0)); assertEquals2(key3, stack.get(1)); } /* */ @Test public void testAddAllPushAll() { KTypeArrayList list2 = new KTypeArrayList<>(); list2.add(asArray(0, 1, 2)); stack.addAll(list2); stack.pushAll(list2); assertListEquals(stack.toArray(), 0, 1, 2, 0, 1, 2); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ /* */ @Test public void testNullify() { stack.push(asArray(1, 2, 3, 4)); stack.pop(); stack.discard(); stack.discard(2); assertEquals(0, stack.size()); /* * Cleanup only for the generic version (to allow GCing of references). */ for (int i = 0; i < stack.buffer.length; i++) { assertEquals2(Intrinsics. empty(), stack.buffer[i]); } } /*! #end !*/ /* */ @Test public void testDiscard() { stack.push(key1, key3); assertEquals(2, stack.size()); stack.discard(); assertEquals(1, stack.size()); stack.push(key4); assertEquals(2, stack.size()); assertEquals2(1, stack.get(0)); assertEquals2(4, stack.get(1)); stack.discard(2); assertEquals(0, stack.size()); } /* */ @Test(expected = AssertionError.class) public void testGetAssertions() { stack.push(key1); stack.pop(); stack.get(0); } /* */ @Test(expected = AssertionError.class) public void testDiscardAssertions() { stack.push(key1); stack.discard(2); } /* */ @Test public void testHashCodeEquals() { KTypeStack s0 = new KTypeStack<>(); assertEquals(1, s0.hashCode()); KTypeStack s1 = KTypeStack.from(key1, key2, key3); KTypeStack s2 = KTypeStack.from(key1, key2, key3); assertEquals(s1.hashCode(), s2.hashCode()); assertEquals(s1, s2); s1 = KTypeStack.from(key1, key2); assertFalse(s1.equals(s2)); } /* */ @Test public void testHashCodeEqualsWithOtherContainer() { KTypeStack s1 = KTypeStack.from(key1, key2, key3); KTypeArrayList s2 = KTypeArrayList.from(key1, key2, key3); assertEquals(s1.hashCode(), s2.hashCode()); assertTrue(s1.equalElements(s2)); } /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testToArrayWithClass() { KTypeStack l1 = KTypeStack.from(1, 2, 3); Integer[] result = l1.toArray(Integer.class); assertArrayEquals(new Integer [] {1, 2, 3}, result); // dummy } /*! #end !*/ /*! #if ($TemplateOptions.KTypeGeneric) !*/ @Test public void testToArray() { KTypeStack l1 = KTypeStack.from(1, 2, 3); Object[] result = l1.toArray(); assertArrayEquals(new Object [] {1, 2, 3}, result); // dummy } /*! #end !*/ /* */ @Test public void testClone() { stack.push(key1, key2, key3); KTypeStack cloned = stack.clone(); cloned.removeAll(key1); assertSortedListEquals(stack.toArray(), key1, key2, key3); assertSortedListEquals(cloned.toArray(), key2, key3); } /* */ @Test public void testToString() { assertEquals("[" + key1 + ", " + key2 + ", " + key3 + "]", KTypeStack.from(key1, key2, key3).toString()); } /* */ @Test public void testEqualsSameClass() { KTypeStack l1 = KTypeStack.from(k1, k2, k3); KTypeStack l2 = KTypeStack.from(k1, k2, k3); KTypeStack l3 = KTypeStack.from(k1, k3, k2); Assertions.assertThat(l1).isEqualTo(l2); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1).isNotEqualTo(l3); } /* */ @Test public void testEqualsSubClass() { class Sub extends KTypeStack { }; KTypeStack l1 = KTypeStack.from(k1, k2, k3); KTypeStack l2 = new Sub(); KTypeStack l3 = new Sub(); l2.addAll(l1); l3.addAll(l1); Assertions.assertThat(l2).isEqualTo(l3); Assertions.assertThat(l1).isNotEqualTo(l2); KTypeArrayList l4 = new KTypeArrayList<>(); l4.addAll(l1); Assertions.assertThat(l1).isNotEqualTo(l4); Assertions.assertThat(l1.equalElements(l4)).isTrue(); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeVTypeHashMapTest.java000066400000000000000000000631301300364116400303320ustar00rootroot00000000000000package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; import java.util.HashSet; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import org.assertj.core.api.Assertions; import org.junit.*; import com.carrotsearch.hppc.cursors.*; import com.carrotsearch.hppc.predicates.*; import com.carrotsearch.hppc.procedures.*; /** * Tests for {@link KTypeVTypeHashMap}. */ /* ! ${TemplateOptions.generatedAnnotation} ! */ public class KTypeVTypeHashMapTest extends AbstractKTypeTest { protected VType value0 = vcast(0); protected VType value1 = vcast(1); protected VType value2 = vcast(2); protected VType value3 = vcast(3); protected VType value4 = vcast(4); /** * Per-test fresh initialized instance. */ public KTypeVTypeHashMap map = newInstance(); protected KTypeVTypeHashMap newInstance() { return new KTypeVTypeHashMap<>(); } @After public void checkEmptySlotsUninitialized() { if (map != null) { int occupied = 0; for (int i = 0; i <= map.mask; i++) { if (Intrinsics. isEmpty(map.keys[i])) { /*! #if ($TemplateOptions.KTypeGeneric) !*/ assertEquals2(Intrinsics. empty(), map.keys[i]); /*! #end !*/ /*! #if ($TemplateOptions.VTypeGeneric) !*/ assertEquals2(Intrinsics. empty(), map.values[i]); /*! #end !*/ } else { occupied++; } } assertEquals(occupied, map.assigned); if (!map.hasEmptyKey) { /*! #if ($TemplateOptions.VTypeGeneric) !*/ assertEquals2(Intrinsics. empty(), map.values[map.mask + 1]); /*! #end !*/ } } } /** * Convert to target type from an integer used to test stuff. */ protected VType vcast(int value) { /*! #if ($TemplateOptions.VTypePrimitive) return (VType) value; #else !*/ @SuppressWarnings("unchecked") VType v = (VType)(Object) value; return v; /*! #end !*/ } /** * Create a new array of a given type and copy the arguments to this array. */ /* #if ($TemplateOptions.VTypeGeneric) */ @SafeVarargs /* #end */ protected final VType [] newvArray(VType... elements) { return elements; } private void assertSameMap( final KTypeVTypeMap c1, final KTypeVTypeMap c2) { assertEquals(c1.size(), c2.size()); c1.forEach(new KTypeVTypeProcedure() { public void apply(KType key, VType value) { assertTrue(c2.containsKey(key)); assertEquals2(value, c2.get(key)); } }); } @Test public void testVisualizeKeys() { map.clear(); Assertions.assertThat(map.visualizeKeyDistribution(20).trim()).matches("\\.+"); map.put(keyE, value0); Assertions.assertThat(map.visualizeKeyDistribution(20).trim()).matches("\\.+"); map.put(key1, value1); Assertions.assertThat(map.visualizeKeyDistribution(20).trim()).matches("\\.*X\\.*"); } /* */ @Test public void testEnsureCapacity() { final AtomicInteger expands = new AtomicInteger(); KTypeVTypeHashMap map = new KTypeVTypeHashMap(0) { @Override protected void allocateBuffers(int arraySize) { super.allocateBuffers(arraySize); expands.incrementAndGet(); } }; // Add some elements. final int max = rarely() ? 0 : randomIntBetween(0, 250); for (int i = 0; i < max; i++) { map.put(cast(i), value0); } final int additions = randomIntBetween(max, max + 5000); map.ensureCapacity(additions + map.size()); final int before = expands.get(); for (int i = 0; i < additions; i++) { map.put(cast(i), value0); } assertEquals(before, expands.get()); } @Test public void testCursorIndexIsValid() { map.put(keyE, value1); map.put(key1, value2); map.put(key2, value3); for (KTypeVTypeCursor c : map) { Assertions.assertThat(map.indexExists(c.index)).isTrue(); Assertions.assertThat(map.indexGet(c.index)).isEqualTo(c.value); } } @Test public void testIndexMethods() { map.put(keyE, value1); map.put(key1, value2); Assertions.assertThat(map.indexOf(keyE)).isNotNegative(); Assertions.assertThat(map.indexOf(key1)).isNotNegative(); Assertions.assertThat(map.indexOf(key2)).isNegative(); Assertions.assertThat(map.indexExists(map.indexOf(keyE))).isTrue(); Assertions.assertThat(map.indexExists(map.indexOf(key1))).isTrue(); Assertions.assertThat(map.indexExists(map.indexOf(key2))).isFalse(); Assertions.assertThat(map.indexGet(map.indexOf(keyE))).isEqualTo(value1); Assertions.assertThat(map.indexGet(map.indexOf(key1))).isEqualTo(value2); try { map.indexGet(map.indexOf(key2)); fail(); } catch (AssertionError e) { // Expected. } Assertions.assertThat(map.indexReplace(map.indexOf(keyE), value3)).isEqualTo(value1); Assertions.assertThat(map.indexReplace(map.indexOf(key1), value4)).isEqualTo(value2); Assertions.assertThat(map.indexGet(map.indexOf(keyE))).isEqualTo(value3); Assertions.assertThat(map.indexGet(map.indexOf(key1))).isEqualTo(value4); map.indexInsert(map.indexOf(key2), key2, value1); Assertions.assertThat(map.indexGet(map.indexOf(key2))).isEqualTo(value1); Assertions.assertThat(map.size()).isEqualTo(3); } /* */ @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value3); assertSameMap(map, new KTypeVTypeHashMap<>(map)); } /* */ @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value3); KTypeVTypeHashMap map2 = KTypeVTypeHashMap.from( newArray(key1, key2, key3), newvArray(value1, value2, value3)); assertSameMap(map, map2); } @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); map.put(key1, value1); assertEquals2(value1, map.getOrDefault(key1, value3)); assertEquals2(value3, map.getOrDefault(key3, value3)); map.remove(key1); assertEquals2(value3, map.getOrDefault(key1, value3)); } /* */ @Test public void testPut() { map.put(key1, value1); assertTrue(map.containsKey(key1)); assertEquals2(value1, map.get(key1)); } /* */ @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals2(value1, map.put(key1, value3)); assertEquals2(value3, map.get(key1)); } /* */ @Test public void testPutWithExpansions() { final int COUNT = 10000; final Random rnd = new Random(randomLong()); final HashSet values = new HashSet(); for (int i = 0; i < COUNT; i++) { final int v = rnd.nextInt(); final boolean hadKey = values.contains(cast(v)); values.add(cast(v)); assertEquals(hadKey, map.containsKey(cast(v))); map.put(cast(v), vcast(v)); assertEquals(values.size(), map.size()); } assertEquals(values.size(), map.size()); } /* */ @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); KTypeVTypeHashMap map2 = newInstance(); map2.put(key2, value2); map2.put(keyE, value1); // One new key (keyE). assertEquals(1, map.putAll(map2)); // Assert the value under key2 has been replaced. assertEquals2(value2, map.get(key2)); // And key3 has been added. assertEquals2(value1, map.get(keyE)); assertEquals(3, map.size()); } /* */ @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals2(value1, map.get(key1)); } /*! #if ($TemplateOptions.VTypePrimitive) !*/ @Test public void testPutOrAdd() { assertEquals2(value1, map.putOrAdd(key1, value1, value2)); assertEquals2(value3, map.putOrAdd(key1, value1, value2)); } /*! #end !*/ /*! #if ($TemplateOptions.VTypePrimitive) !*/ @Test public void testAddTo() { assertEquals2(value1, map.addTo(key1, value1)); assertEquals2(value3, map.addTo(key1, value2)); } /*! #end !*/ /* */ @Test public void testRemove() { map.put(key1, value1); assertEquals2(value1, map.remove(key1)); assertEquals2(Intrinsics. empty(), map.remove(key1)); assertEquals(0, map.size()); // These are internals, but perhaps worth asserting too. assertEquals(0, map.assigned); } /* */ @Test public void testEmptyKey() { final KType empty = Intrinsics. empty(); map.put(empty, value1); assertEquals(1, map.size()); assertEquals(false, map.isEmpty()); assertEquals2(value1, map.get(empty)); assertEquals2(value1, map.getOrDefault(empty, value2)); assertEquals(true, map.iterator().hasNext()); assertEquals2(empty, map.iterator().next().key); assertEquals2(value1, map.iterator().next().value); assertEquals(true, map.forEach(new KTypeVTypeProcedure() { boolean hadKeyValue; @Override public void apply(KType key, VType value) { hadKeyValue |= (key == empty && value == value1); } }).hadKeyValue); assertEquals(true, map.forEach(new KTypeVTypePredicate() { boolean hadKeyValue; @Override public boolean apply(KType key, VType value) { hadKeyValue |= (key == empty && value == value1); return true; } }).hadKeyValue); assertEquals(1, map.keys().size()); assertEquals(true, map.keys().contains(empty)); assertEquals2(empty, map.keys().iterator().next().value); Assertions.assertThat(map.keys().toArray()).containsOnly(empty); assertEquals(1, map.values().size()); assertEquals(true, map.values().contains(value1)); assertEquals2(value1, map.values().iterator().next().value); Assertions.assertThat(map.values().toArray()).containsOnly(value1); map.remove(empty); assertEquals2(Intrinsics. empty(), map.get(empty)); } /* */ @Test public void testRemoveAllWithList() { map.put(key1, value1); map.put(key2, value1); map.put(keyE, value1); KTypeArrayList other = new KTypeArrayList<>(); other.add(newArray(key2, keyE, key4)); assertEquals(2, map.removeAll(other)); assertEquals(1, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testRemoveAllWithSet() { map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map.put(keyE, value1); KTypeHashSet other = new KTypeHashSet<>(); other.addAll(newArray(key2, keyE, key4)); assertEquals(2, map.removeAll(other)); assertEquals(2, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testRemoveAllWithKeyPredicate() { map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map.removeAll(new KTypePredicate() { public boolean apply(KType value) { return value == key2 || value == key3; } }); assertEquals(1, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testRemoveAllWithKeyValuePredicate() { map.put(keyE, value1); map.put(key1, value1); map.put(key2, value2); map.put(key3, value2); map.removeAll(new KTypeVTypePredicate() { public boolean apply(KType key, VType value) { return value == value1; } }); assertEquals(2, map.size()); Assertions.assertThat(map.getOrDefault(key2, value0)).isEqualTo(value2); Assertions.assertThat(map.getOrDefault(key3, value0)).isEqualTo(value2); } /* */ @Test public void testRemoveAllOnValueContainer() { map.put(keyE, value1); map.put(key1, value1); map.put(key2, value2); map.put(key3, value2); map.values().removeAll(value1); assertEquals(2, map.size()); Assertions.assertThat(map.getOrDefault(key2, value0)).isEqualTo(value2); Assertions.assertThat(map.getOrDefault(key3, value0)).isEqualTo(value2); } /* */ @Test public void testRemoveAllPredicateOnValueContainer() { map.put(keyE, value1); map.put(key1, value1); map.put(key2, value2); map.put(key3, value2); map.values().removeAll(new KTypePredicate() { @Override public boolean apply(VType value) { return value == value1; } }); assertEquals(2, map.size()); Assertions.assertThat(map.getOrDefault(key2, value0)).isEqualTo(value2); Assertions.assertThat(map.getOrDefault(key3, value0)).isEqualTo(value2); } /* */ @Test public void testRemoveViaKeySetView() { map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map.keys().removeAll(new KTypePredicate() { public boolean apply(KType value) { return value == key2 || value == key3; } }); assertEquals(1, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testMapsIntersection() { KTypeVTypeHashMap map2 = newInstance(); map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map2.put(key2, value1); map2.put(key4, value1); assertEquals(2, map.keys().retainAll(map2.keys())); assertEquals(1, map.size()); assertTrue(map.containsKey(key2)); } /* */ @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); map.put(key3, value1); assertSortedListEquals(map.keys().toArray(), key1, key2, key3); } /* */ @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); map.put(key3, value1); int counted = 0; for (KTypeCursor c : map.keys()) { assertEquals2(map.keys[c.index], c.value); counted++; } assertEquals(counted, map.size()); } /* */ @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); map.clear(); assertEquals(0, map.size()); // These are internals, but perhaps worth asserting too. assertEquals(0, map.assigned); // Check if the map behaves properly upon subsequent use. testPutWithExpansions(); } /* */ @Test public void testRelease() { map.put(key1, value1); map.put(key2, value1); map.release(); assertEquals(0, map.size()); // These are internals, but perhaps worth asserting too. assertEquals(0, map.assigned); // Check if the map behaves properly upon subsequent use. testPutWithExpansions(); } /* */ @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value3); map.remove(key2); int count = 0; for (KTypeVTypeCursor cursor : map) { count++; assertTrue(map.containsKey(cursor.key)); assertEquals2(cursor.value, map.get(cursor.key)); assertEquals2(cursor.value, map.values[cursor.index]); assertEquals2(cursor.key, map.keys[cursor.index]); } assertEquals(count, map.size()); map.clear(); assertFalse(map.iterator().hasNext()); } /* */ @Test public void testBug_HPPC73_FullCapacityGet() { final AtomicInteger reallocations = new AtomicInteger(); final int elements = 0x7F; map = new KTypeVTypeHashMap(elements, 1f) { @Override protected double verifyLoadFactor(double loadFactor) { // Skip load factor sanity range checking. return loadFactor; } @Override protected void allocateBuffers(int arraySize) { super.allocateBuffers(arraySize); reallocations.incrementAndGet(); } }; int reallocationsBefore = reallocations.get(); assertEquals(reallocationsBefore, 1); for (int i = 1; i <= elements; i++) { map.put(cast(i), value1); } // Non-existent key. KType outOfSet = cast(elements + 1); map.remove(outOfSet); assertFalse(map.containsKey(outOfSet)); assertEquals(reallocationsBefore, reallocations.get()); // Should not expand because we're replacing an existing element. map.put(k1, value2); assertEquals(reallocationsBefore, reallocations.get()); // Remove from a full map. map.remove(k1); assertEquals(reallocationsBefore, reallocations.get()); map.put(k1, value2); // Check expand on "last slot of a full map" condition. map.put(outOfSet, value1); assertEquals(reallocationsBefore + 1, reallocations.get()); } @Test public void testHashCodeEquals() { KTypeVTypeHashMap l0 = newInstance(); assertEquals(0, l0.hashCode()); assertEquals(l0, newInstance()); KTypeVTypeHashMap l1 = KTypeVTypeHashMap.from( newArray(key1, key2, key3), newvArray(value1, value2, value3)); KTypeVTypeHashMap l2 = KTypeVTypeHashMap.from( newArray(key2, key1, key3), newvArray(value2, value1, value3)); KTypeVTypeHashMap l3 = KTypeVTypeHashMap.from( newArray(key1, key2), newvArray(value2, value1)); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); assertFalse(l1.equals(l3)); assertFalse(l2.equals(l3)); } /* */ @Test public void testHashCodeEqualsForDifferentMix() { KTypeVTypeHashMap l0 = new KTypeVTypeHashMap<>(0, 0.5d, HashOrderMixing.constant(1)); KTypeVTypeHashMap l1 = new KTypeVTypeHashMap<>(0, 0.5d, HashOrderMixing.constant(2)); assertEquals(0, l0.hashCode()); assertEquals(l0.hashCode(), l1.hashCode()); assertEquals(l0, l1); KTypeVTypeHashMap l2 = KTypeVTypeHashMap.from( newArray(key1, key2, key3), newvArray(value1, value2, value3)); l0.putAll(l2); l1.putAll(l2); assertEquals(l0.hashCode(), l1.hashCode()); assertEquals(l0, l1); } @Test public void testBug_HPPC37() { KTypeVTypeHashMap l1 = KTypeVTypeHashMap.from( newArray(key1), newvArray(value1)); KTypeVTypeHashMap l2 = KTypeVTypeHashMap.from( newArray(key2), newvArray(value1)); assertFalse(l1.equals(l2)); assertFalse(l2.equals(l1)); } /*! #if ($TemplateOptions.VTypeGeneric) !*/ @Test public void testNullValue() { assertEquals(null, map.put(key1, null)); assertEquals(null, map.get(key1)); assertTrue(map.containsKey(key1)); map.remove(key1); assertFalse(map.containsKey(key1)); assertEquals(0, map.size()); } /*! #end !*/ /*! #if ($TemplateOptions.AllGeneric) !*/ /** * Run some random insertions/ deletions and compare the results * against java.util.HashMap. */ @Test public void testAgainstHashMap() { final Random rnd = new Random(randomLong()); final java.util.HashMap other = new java.util.HashMap(); for (int size = 1000; size < 20000; size += 4000) { other.clear(); map.clear(); for (int round = 0; round < size * 20; round++) { KType key = cast(rnd.nextInt(size)); if (rnd.nextInt(50) == 0) { key = Intrinsics. empty(); } VType value = vcast(rnd.nextInt()); if (rnd.nextBoolean()) { map.put(key, value); other.put(key, value); assertEquals(value, map.get(key)); assertTrue(map.containsKey(key)); } else { assertEquals(other.containsKey(key), map.containsKey(key)); assertEquals(other.remove(key), map.remove(key)); } assertEquals(other.size(), map.size()); } } } /*! #end !*/ /* * */ @Test public void testClone() { this.map.put(key1, value1); this.map.put(key2, value2); this.map.put(key3, value3); KTypeVTypeHashMap cloned = map.clone(); cloned.remove(key1); assertSortedListEquals(map.keys().toArray(), key1, key2, key3); assertSortedListEquals(cloned.keys().toArray(), key2, key3); } /* */ @Test public void testMapValues() { map.put(key1, value3); map.put(key2, value2); map.put(key3, value1); assertSortedListEquals(map.values().toArray(), value1, value2, value3); map.clear(); map.put(key1, value1); map.put(key2, value2); map.put(key3, value2); assertSortedListEquals(map.values().toArray(), value1, value2, value2); } /* */ @Test public void testMapValuesIterator() { map.put(key1, value3); map.put(key2, value2); map.put(key3, value1); int counted = 0; for (KTypeCursor c : map.values()) { assertEquals2(map.values[c.index], c.value); counted++; } assertEquals(counted, map.size()); } /* */ @Test public void testMapValuesContainer() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value2); // contains() for (KTypeVTypeCursor c : map) assertTrue(map.values().contains(c.value)); assertFalse(map.values().contains(value3)); assertEquals(map.isEmpty(), map.values().isEmpty()); assertEquals(map.size(), map.values().size()); final KTypeArrayList values = new KTypeArrayList(); map.values().forEach(new KTypeProcedure() { public void apply(VType value) { values.add(value); } }); assertSortedListEquals(map.values().toArray(), value1, value2, value2); values.clear(); map.values().forEach(new KTypePredicate() { public boolean apply(VType value) { values.add(value); return true; } }); assertSortedListEquals(map.values().toArray(), value1, value2, value2); } /* */ @Test public void testEqualsSameClass() { KTypeVTypeHashMap l1 = newInstance(); l1.put(k1, value0); l1.put(k2, value1); l1.put(k3, value2); KTypeVTypeHashMap l2 = new KTypeVTypeHashMap<>(l1); l2.putAll(l1); KTypeVTypeHashMap l3 = new KTypeVTypeHashMap<>(l2); l3.putAll(l2); l3.put(k4, value0); Assertions.assertThat(l1).isEqualTo(l2); Assertions.assertThat(l1.hashCode()).isEqualTo(l2.hashCode()); Assertions.assertThat(l1).isNotEqualTo(l3); } /* */ @Test public void testEqualsSubClass() { class Sub extends KTypeVTypeHashMap { }; KTypeVTypeHashMap l1 = newInstance(); l1.put(k1, value0); l1.put(k2, value1); l1.put(k3, value2); KTypeVTypeHashMap l2 = new Sub(); l2.putAll(l1); l2.put(k4, value3); KTypeVTypeHashMap l3 = new Sub(); l3.putAll(l2); Assertions.assertThat(l1).isNotEqualTo(l2); Assertions.assertThat(l2.hashCode()).isEqualTo(l3.hashCode()); Assertions.assertThat(l2).isEqualTo(l3); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeVTypeIdentityHashMapTest.java000066400000000000000000000246771300364116400320610ustar00rootroot00000000000000/*! #set($TemplateOptions.ignored = ($TemplateOptions.KTypePrimitive)) !*/ package com.carrotsearch.hppc; import static com.carrotsearch.hppc.TestUtils.*; import org.junit.*; import com.carrotsearch.hppc.cursors.*; import com.carrotsearch.hppc.predicates.*; import com.carrotsearch.hppc.procedures.*; /** * Tests for {@link KTypeVTypeIdentityHashMap}. */ /*! #if ($TemplateOptions.anyGeneric) @SuppressWarnings("all") #end !*/ /* ! ${TemplateOptions.generatedAnnotation} ! */ public class KTypeVTypeIdentityHashMapTest extends AbstractKTypeTest { protected VType value0 = vcast(0); protected VType value1 = vcast(1); protected VType value2 = vcast(2); protected VType value3 = vcast(3); /** * Per-test fresh initialized instance. */ public KTypeVTypeIdentityHashMap map = new KTypeVTypeIdentityHashMap<>(); @After public void checkEmptySlotsUninitialized() { if (map != null) { int occupied = 0; for (int i = 0; i <= map.mask; i++) { if (Intrinsics. isEmpty(map.keys[i])) { /*! #if ($TemplateOptions.KTypeGeneric) !*/ assertEquals2(Intrinsics. empty(), map.keys[i]); /*! #end !*/ /*! #if ($TemplateOptions.VTypeGeneric) !*/ assertEquals2(Intrinsics. empty(), map.values[i]); /*! #end !*/ } else { occupied++; } } assertEquals(occupied, map.assigned); if (!map.hasEmptyKey) { /*! #if ($TemplateOptions.VTypeGeneric) !*/ assertEquals2(Intrinsics. empty(), map.values[map.mask + 1]); /*! #end !*/ } } } /** * Convert to target type from an integer used to test stuff. */ protected VType vcast(int value) { /*! #if ($TemplateOptions.VTypePrimitive) return (VType) value; #else !*/ @SuppressWarnings("unchecked") VType v = (VType)(Object) value; return v; /*! #end !*/ } /** * Create a new array of a given type and copy the arguments to this array. */ @SafeVarargs protected final VType [] newvArray(VType... elements) { return elements; } private void assertSameMap( final KTypeVTypeMap c1, final KTypeVTypeMap c2) { assertEquals(c1.size(), c2.size()); c1.forEach(new KTypeVTypeProcedure() { public void apply(KType key, VType value) { assertTrue(c2.containsKey(key)); assertEquals2(value, c2.get(key)); } }); } /* */ @Test public void testCloningConstructor() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value3); assertSameMap(map, new KTypeVTypeIdentityHashMap(map)); } /* */ @Test public void testFromArrays() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value3); KTypeVTypeIdentityHashMap map2 = KTypeVTypeIdentityHashMap.from( newArray(key1, key2, key3), newvArray(value1, value2, value3)); assertSameMap(map, map2); } @Test public void testGetOrDefault() { map.put(key2, value2); assertTrue(map.containsKey(key2)); map.put(key1, value1); assertEquals2(value1, map.getOrDefault(key1, value3)); assertEquals2(value3, map.getOrDefault(key3, value3)); map.remove(key1); assertEquals2(value3, map.getOrDefault(key1, value3)); } /* */ @Test public void testPut() { map.put(key1, value1); assertTrue(map.containsKey(key1)); assertEquals2(value1, map.get(key1)); } /* */ @Test public void testPutOverExistingKey() { map.put(key1, value1); assertEquals2(value1, map.put(key1, value3)); assertEquals2(value3, map.get(key1)); } /* */ @Test public void testPutAll() { map.put(key1, value1); map.put(key2, value1); KTypeVTypeIdentityHashMap map2 = new KTypeVTypeIdentityHashMap(); map2.put(key2, value2); map2.put(key3, value1); // One new key (key3). assertEquals(1, map.putAll(map2)); // Assert the value under key2 has been replaced. assertEquals2(value2, map.get(key2)); // And key3 has been added. assertEquals2(value1, map.get(key3)); assertEquals(3, map.size()); } /* */ @Test public void testPutIfAbsent() { assertTrue(map.putIfAbsent(key1, value1)); assertFalse(map.putIfAbsent(key1, value2)); assertEquals2(value1, map.get(key1)); } /*! #if ($TemplateOptions.VTypePrimitive) !*/ @Test public void testPutOrAdd() { assertEquals2(value1, map.putOrAdd(key1, value1, value2)); assertEquals2(value3, map.putOrAdd(key1, value1, value2)); } /*! #end !*/ /*! #if ($TemplateOptions.VTypePrimitive) !*/ @Test public void testAddTo() { assertEquals2(value1, map.addTo(key1, value1)); assertEquals2(value3, map.addTo(key1, value2)); } /*! #end !*/ /* */ @Test public void testRemove() { map.put(key1, value1); assertEquals2(value1, map.remove(key1)); assertEquals2(Intrinsics. empty(), map.remove(key1)); assertEquals(0, map.size()); // These are internals, but perhaps worth asserting too. assertEquals(0, map.assigned); } /* */ @Test public void testRemoveAllWithContainer() { map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); KTypeArrayList list2 = new KTypeArrayList<>(); list2.add(newArray(key2, key3, key4)); map.removeAll(list2); assertEquals(1, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testRemoveAllWithPredicate() { map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map.removeAll(new KTypePredicate() { public boolean apply(KType value) { return value == key2 || value == key3; } }); assertEquals(1, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testRemoveViaKeySetView() { map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map.keys().removeAll(new KTypePredicate() { public boolean apply(KType value) { return value == key2 || value == key3; } }); assertEquals(1, map.size()); assertTrue(map.containsKey(key1)); } /* */ @Test public void testMapsIntersection() { KTypeVTypeIdentityHashMap map2 = new KTypeVTypeIdentityHashMap<>(); map.put(key1, value1); map.put(key2, value1); map.put(key3, value1); map2.put(key2, value1); map2.put(key4, value1); assertEquals(2, map.keys().retainAll(map2.keys())); assertEquals(1, map.size()); assertTrue(map.containsKey(key2)); } /* */ @Test public void testMapKeySet() { map.put(key1, value3); map.put(key2, value2); map.put(key3, value1); assertSortedListEquals(map.keys().toArray(), key1, key2, key3); } /* */ @Test public void testMapKeySetIterator() { map.put(key1, value3); map.put(key2, value2); map.put(key3, value1); int counted = 0; for (KTypeCursor c : map.keys()) { assertEquals2(map.keys[c.index], c.value); counted++; } assertEquals(counted, map.size()); } /* */ @Test public void testClear() { map.put(key1, value1); map.put(key2, value1); map.clear(); assertEquals(0, map.size()); // These are internals, but perhaps worth asserting too. assertEquals(0, map.assigned); } /* */ @Test public void testIterable() { map.put(key1, value1); map.put(key2, value2); map.put(key3, value3); map.remove(key2); int count = 0; for (KTypeVTypeCursor cursor : map) { count++; assertTrue(map.containsKey(cursor.key)); assertEquals2(cursor.value, map.get(cursor.key)); assertEquals2(cursor.value, map.values[cursor.index]); assertEquals2(cursor.key, map.keys[cursor.index]); } assertEquals(count, map.size()); map.clear(); assertFalse(map.iterator().hasNext()); } @Test public void testHashCodeEquals() { KTypeVTypeIdentityHashMap l0 = new KTypeVTypeIdentityHashMap(); assertEquals(0, l0.hashCode()); assertEquals(l0, new KTypeVTypeIdentityHashMap()); KTypeVTypeIdentityHashMap l1 = KTypeVTypeIdentityHashMap.from( newArray(key1, key2, key3), newvArray(value1, value2, value3)); KTypeVTypeIdentityHashMap l2 = KTypeVTypeIdentityHashMap.from( newArray(key2, key1, key3), newvArray(value2, value1, value3)); KTypeVTypeIdentityHashMap l3 = KTypeVTypeIdentityHashMap.from( newArray(key1, key2), newvArray(value2, value1)); assertEquals(l1.hashCode(), l2.hashCode()); assertEquals(l1, l2); assertFalse(l1.equals(l3)); assertFalse(l2.equals(l3)); } @Test public void testBug_HPPC37() { KTypeVTypeIdentityHashMap l1 = KTypeVTypeIdentityHashMap.from( newArray(key1), newvArray(value1)); KTypeVTypeIdentityHashMap l2 = KTypeVTypeIdentityHashMap.from( newArray(key2), newvArray(value1)); assertFalse(l1.equals(l2)); assertFalse(l2.equals(l1)); } } hppc-0.7.2/hppc/src/test/templates/com/carrotsearch/hppc/KTypeVTypeScatterMapTest.java000066400000000000000000000006641300364116400310570ustar00rootroot00000000000000package com.carrotsearch.hppc; import org.junit.Ignore; /** * Tests for {@link KTypeVTypeHashMap}. */ /* ! ${TemplateOptions.generatedAnnotation} ! */ public class KTypeVTypeScatterMapTest extends KTypeVTypeHashMapTest { @Override protected KTypeVTypeHashMap newInstance() { return new KTypeVTypeScatterMap<>(); } @Override @Ignore public void testEqualsSameClass() { } } hppc-0.7.2/pom.xml000066400000000000000000000463661300364116400140040ustar00rootroot00000000000000 4.0.0 org.sonatype.oss oss-parent 9 com.carrotsearch hppc-parent 0.7.2 pom HPPC (parent POM) Parent POM for HPPC projects (High Performance Primitive Collections) http://labs.carrotsearch.com/hppc.html The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo Carrot Search s.c. http://www.carrotsearch.com Jira http://issues.carrot2.org/browse/HPPC Announcements and bug reports mailing list java-high-performance-primitive-collections+subscribe@googlegroups.com java-high-performance-primitive-collections+unsubscribe@googlegroups.com java-high-performance-primitive-collections@googlegroups.com git@github.com:carrotsearch/hppc.git scm:git:git@github.com:carrotsearch/hppc.git scm:git:git@github.com:carrotsearch/hppc.git dawid.weiss Dawid Weiss dawid.weiss@carrotsearch.com stanislaw.osinski Stanisław Osiński stanislaw.osinski@carrotsearch.com UTF-8 1.7 1.7 18.0 4.12 1.6.2 2.0.0 2.1.14 4.5 1.7 1.8 7.0.2 0.6.6 2.5.2 3.0.0 2.5 3.1 2.9 2.8.2 2.5.2 2.5 2.6 2.17 1.4 2.10.3 2.1 1.9.1 2.2 3.2.3 ${version.maven.api} hppc hppc-template-processor hppc-benchmarks hppc-examples com.google.guava guava ${version.guava} junit junit ${version.junit} org.assertj assertj-core ${version.assertj} jar com.carrotsearch.randomizedtesting randomizedtesting-runner ${version.randomizedtesting} org.apache.maven.plugins maven-gpg-plugin 1.6 org.apache.maven.plugins maven-assembly-plugin ${version.maven-assembly-plugin} org.antlr antlr4-maven-plugin ${version.antlr} org.codehaus.mojo versions-maven-plugin ${version.maven-versions-plugin} org.apache.maven.plugins maven-clean-plugin ${version.maven-clean-plugin} true ${project.build.directory} eclipse/** org.apache.maven.plugins maven-compiler-plugin ${version.maven-compiler-plugin} ${maven.compiler.source} ${maven.compiler.target} -Xlint maven-deploy-plugin ${version.maven-deploy-plugin} org.apache.maven.plugins maven-install-plugin ${version.maven-install-plugin} org.apache.maven.plugins maven-jar-plugin ${version.maven-jar-plugin} org.apache.maven.plugins maven-javadoc-plugin ${version.maven-javadoc-plugin} false false false true org.apache.maven.plugins maven-resources-plugin ${version.maven-resources-plugin} org.apache.maven.plugins maven-surefire-plugin ${version.maven-surefire-plugin} default-test none com.carrotsearch.randomizedtesting junit4-maven-plugin ${version.randomizedtesting} junit4-tests junit4 **/*Test.* **/*$* **/Abstract* auto 750m de.thetaphi forbiddenapis ${version.forbiddenapis} check-forbidden-apis 1.7 true false false jdk-unsafe jdk-deprecated jdk-system-out check check-forbidden-apis-tests 1.7 true false false jdk-unsafe jdk-deprecated testCheck org.apache.maven.plugins maven-enforcer-plugin ${version.maven-enforcer-plugin} enforce-environment verify false enforce 1.7.0 ${version.maven.api} enforce-maven enforce none org.apache.felix maven-bundle-plugin ${version.maven-bundle-plugin} true quick true eclipse-builds m2e.version target/eclipse eclipse m2e.version true true true true install antrun:run maven-antrun-plugin 1.8 default-cli none false run org.apache.ant ant 1.9.4 org.eclipse.m2e lifecycle-mapping 1.0.0 de.thetaphi forbiddenapis [0.0.0,) check testCheck com.carrotsearch hppc-template-processor [0.0.0,) template-processor add-source add-test-source false true org.apache.maven.plugins maven-plugin-plugin [3.4,) descriptor helpmojo org.apache.maven.plugins maven-enforcer-plugin [0.0,) enforce